sui_rpc/proto/sui/rpc/v2/
checkpoint.rs1use super::*;
2use crate::field::FieldMaskTree;
3use crate::merge::Merge;
4use crate::proto::TryFromProtoError;
5use tap::Pipe;
6
7impl From<sui_sdk_types::CheckpointSummary> for CheckpointSummary {
12 fn from(summary: sui_sdk_types::CheckpointSummary) -> Self {
13 Self::merge_from(summary, &FieldMaskTree::new_wildcard())
14 }
15}
16
17impl Merge<sui_sdk_types::CheckpointSummary> for CheckpointSummary {
18 fn merge(&mut self, source: sui_sdk_types::CheckpointSummary, mask: &FieldMaskTree) {
19 if mask.contains(Self::BCS_FIELD.name) {
20 let mut bcs = Bcs::serialize(&source).unwrap();
21 bcs.name = Some("CheckpointSummary".to_owned());
22 self.bcs = Some(bcs);
23 }
24
25 if mask.contains(Self::DIGEST_FIELD.name) {
26 self.digest = Some(source.digest().to_string());
27 }
28
29 let sui_sdk_types::CheckpointSummary {
30 epoch,
31 sequence_number,
32 network_total_transactions,
33 content_digest,
34 previous_digest,
35 epoch_rolling_gas_cost_summary,
36 timestamp_ms,
37 checkpoint_commitments,
38 end_of_epoch_data,
39 version_specific_data,
40 } = source;
41
42 if mask.contains(Self::EPOCH_FIELD.name) {
43 self.epoch = Some(epoch);
44 }
45
46 if mask.contains(Self::SEQUENCE_NUMBER_FIELD.name) {
47 self.sequence_number = Some(sequence_number);
48 }
49
50 if mask.contains(Self::TOTAL_NETWORK_TRANSACTIONS_FIELD.name) {
51 self.total_network_transactions = Some(network_total_transactions);
52 }
53
54 if mask.contains(Self::CONTENT_DIGEST_FIELD.name) {
55 self.content_digest = Some(content_digest.to_string());
56 }
57
58 if mask.contains(Self::PREVIOUS_DIGEST_FIELD.name) {
59 self.previous_digest = previous_digest.map(|d| d.to_string());
60 }
61
62 if mask.contains(Self::EPOCH_ROLLING_GAS_COST_SUMMARY_FIELD.name) {
63 self.epoch_rolling_gas_cost_summary = Some(epoch_rolling_gas_cost_summary.into());
64 }
65
66 if mask.contains(Self::TIMESTAMP_FIELD.name) {
67 self.timestamp = Some(crate::proto::timestamp_ms_to_proto(timestamp_ms));
68 }
69
70 if mask.contains(Self::COMMITMENTS_FIELD.name) {
71 self.commitments = checkpoint_commitments.into_iter().map(Into::into).collect();
72 }
73
74 if mask.contains(Self::END_OF_EPOCH_DATA_FIELD.name) {
75 self.end_of_epoch_data = end_of_epoch_data.map(Into::into);
76 }
77
78 if mask.contains(Self::VERSION_SPECIFIC_DATA_FIELD.name) {
79 self.version_specific_data = Some(version_specific_data.into());
80 }
81 }
82}
83
84impl Merge<&CheckpointSummary> for CheckpointSummary {
85 fn merge(&mut self, source: &CheckpointSummary, mask: &FieldMaskTree) {
86 let CheckpointSummary {
87 bcs,
88 digest,
89 epoch,
90 sequence_number,
91 total_network_transactions,
92 content_digest,
93 previous_digest,
94 epoch_rolling_gas_cost_summary,
95 timestamp,
96 commitments,
97 end_of_epoch_data,
98 version_specific_data,
99 } = source;
100
101 if mask.contains(Self::BCS_FIELD.name) {
102 self.bcs = bcs.clone();
103 }
104
105 if mask.contains(Self::DIGEST_FIELD.name) {
106 self.digest = digest.clone();
107 }
108
109 if mask.contains(Self::EPOCH_FIELD.name) {
110 self.epoch = *epoch;
111 }
112
113 if mask.contains(Self::SEQUENCE_NUMBER_FIELD.name) {
114 self.sequence_number = *sequence_number;
115 }
116
117 if mask.contains(Self::TOTAL_NETWORK_TRANSACTIONS_FIELD.name) {
118 self.total_network_transactions = *total_network_transactions;
119 }
120
121 if mask.contains(Self::CONTENT_DIGEST_FIELD.name) {
122 self.content_digest = content_digest.clone();
123 }
124
125 if mask.contains(Self::PREVIOUS_DIGEST_FIELD.name) {
126 self.previous_digest = previous_digest.clone();
127 }
128
129 if mask.contains(Self::EPOCH_ROLLING_GAS_COST_SUMMARY_FIELD.name) {
130 self.epoch_rolling_gas_cost_summary = *epoch_rolling_gas_cost_summary;
131 }
132
133 if mask.contains(Self::TIMESTAMP_FIELD.name) {
134 self.timestamp = *timestamp;
135 }
136
137 if mask.contains(Self::COMMITMENTS_FIELD.name) {
138 self.commitments = commitments.clone();
139 }
140
141 if mask.contains(Self::END_OF_EPOCH_DATA_FIELD.name) {
142 self.end_of_epoch_data = end_of_epoch_data.clone();
143 }
144
145 if mask.contains(Self::VERSION_SPECIFIC_DATA_FIELD.name) {
146 self.version_specific_data = version_specific_data.clone();
147 }
148 }
149}
150
151impl TryFrom<&CheckpointSummary> for sui_sdk_types::CheckpointSummary {
152 type Error = TryFromProtoError;
153
154 fn try_from(
155 CheckpointSummary {
156 bcs: _,
157 digest: _,
158 epoch,
159 sequence_number,
160 total_network_transactions,
161 content_digest,
162 previous_digest,
163 epoch_rolling_gas_cost_summary,
164 timestamp,
165 commitments,
166 end_of_epoch_data,
167 version_specific_data,
168 }: &CheckpointSummary,
169 ) -> Result<Self, Self::Error> {
170 let epoch = epoch.ok_or_else(|| TryFromProtoError::missing("epoch"))?;
171 let sequence_number =
172 sequence_number.ok_or_else(|| TryFromProtoError::missing("sequence_number"))?;
173 let network_total_transactions = total_network_transactions
174 .ok_or_else(|| TryFromProtoError::missing("total_network_transactions"))?;
175 let content_digest = content_digest
176 .as_ref()
177 .ok_or_else(|| TryFromProtoError::missing("content_digest"))?
178 .parse()
179 .map_err(|e| TryFromProtoError::invalid(CheckpointSummary::CONTENT_DIGEST_FIELD, e))?;
180 let previous_digest = previous_digest
181 .as_ref()
182 .map(|s| {
183 s.parse().map_err(|e| {
184 TryFromProtoError::invalid(CheckpointSummary::PREVIOUS_DIGEST_FIELD, e)
185 })
186 })
187 .transpose()?;
188 let epoch_rolling_gas_cost_summary = epoch_rolling_gas_cost_summary
189 .as_ref()
190 .ok_or_else(|| TryFromProtoError::missing("epoch_rolling_gas_cost_summary"))?
191 .try_into()?;
192
193 let timestamp_ms = timestamp
194 .ok_or_else(|| TryFromProtoError::missing("timestamp_ms"))?
195 .pipe(crate::proto::proto_to_timestamp_ms)?;
196
197 let checkpoint_commitments = commitments
198 .iter()
199 .map(TryInto::try_into)
200 .collect::<Result<_, _>>()?;
201
202 let end_of_epoch_data = end_of_epoch_data
203 .as_ref()
204 .map(TryInto::try_into)
205 .transpose()?;
206
207 let version_specific_data = version_specific_data
208 .as_ref()
209 .ok_or_else(|| TryFromProtoError::missing("version_specific_data"))?
210 .to_vec();
211
212 Ok(Self {
213 epoch,
214 sequence_number,
215 network_total_transactions,
216 content_digest,
217 previous_digest,
218 epoch_rolling_gas_cost_summary,
219 timestamp_ms,
220 checkpoint_commitments,
221 end_of_epoch_data,
222 version_specific_data,
223 })
224 }
225}
226
227impl From<sui_sdk_types::GasCostSummary> for GasCostSummary {
232 fn from(
233 sui_sdk_types::GasCostSummary {
234 computation_cost,
235 storage_cost,
236 storage_rebate,
237 non_refundable_storage_fee,
238 }: sui_sdk_types::GasCostSummary,
239 ) -> Self {
240 Self {
241 computation_cost: Some(computation_cost),
242 storage_cost: Some(storage_cost),
243 storage_rebate: Some(storage_rebate),
244 non_refundable_storage_fee: Some(non_refundable_storage_fee),
245 }
246 }
247}
248
249impl TryFrom<&GasCostSummary> for sui_sdk_types::GasCostSummary {
250 type Error = TryFromProtoError;
251
252 fn try_from(
253 GasCostSummary {
254 computation_cost,
255 storage_cost,
256 storage_rebate,
257 non_refundable_storage_fee,
258 }: &GasCostSummary,
259 ) -> Result<Self, Self::Error> {
260 let computation_cost =
261 computation_cost.ok_or_else(|| TryFromProtoError::missing("computation_cost"))?;
262 let storage_cost =
263 storage_cost.ok_or_else(|| TryFromProtoError::missing("storage_cost"))?;
264 let storage_rebate =
265 storage_rebate.ok_or_else(|| TryFromProtoError::missing("storage_rebate"))?;
266 let non_refundable_storage_fee = non_refundable_storage_fee
267 .ok_or_else(|| TryFromProtoError::missing("non_refundable_storage_fee"))?;
268 Ok(Self {
269 computation_cost,
270 storage_cost,
271 storage_rebate,
272 non_refundable_storage_fee,
273 })
274 }
275}
276
277impl From<sui_sdk_types::CheckpointCommitment> for CheckpointCommitment {
282 fn from(value: sui_sdk_types::CheckpointCommitment) -> Self {
283 use checkpoint_commitment::CheckpointCommitmentKind;
284
285 let mut message = Self::default();
286
287 let kind = match value {
288 sui_sdk_types::CheckpointCommitment::EcmhLiveObjectSet { digest } => {
289 message.digest = Some(digest.to_string());
290 CheckpointCommitmentKind::EcmhLiveObjectSet
291 }
292 sui_sdk_types::CheckpointCommitment::CheckpointArtifacts { digest } => {
293 message.digest = Some(digest.to_string());
294 CheckpointCommitmentKind::CheckpointArtifacts
295 }
296 _ => CheckpointCommitmentKind::Unknown,
297 };
298
299 message.set_kind(kind);
300 message
301 }
302}
303
304impl TryFrom<&CheckpointCommitment> for sui_sdk_types::CheckpointCommitment {
305 type Error = TryFromProtoError;
306
307 fn try_from(value: &CheckpointCommitment) -> Result<Self, Self::Error> {
308 use checkpoint_commitment::CheckpointCommitmentKind;
309
310 match value.kind() {
311 CheckpointCommitmentKind::Unknown => {
312 return Err(TryFromProtoError::invalid(
313 CheckpointCommitment::KIND_FIELD,
314 "unknown CheckpointCommitmentKind",
315 ));
316 }
317 CheckpointCommitmentKind::EcmhLiveObjectSet => Self::EcmhLiveObjectSet {
318 digest: value.digest().parse().map_err(|e| {
319 TryFromProtoError::invalid(CheckpointCommitment::DIGEST_FIELD, e)
320 })?,
321 },
322 CheckpointCommitmentKind::CheckpointArtifacts => Self::CheckpointArtifacts {
323 digest: value.digest().parse().map_err(|e| {
324 TryFromProtoError::invalid(CheckpointCommitment::DIGEST_FIELD, e)
325 })?,
326 },
327 }
328 .pipe(Ok)
329 }
330}
331
332impl From<sui_sdk_types::EndOfEpochData> for EndOfEpochData {
337 fn from(
338 sui_sdk_types::EndOfEpochData {
339 next_epoch_committee,
340 next_epoch_protocol_version,
341 epoch_commitments,
342 }: sui_sdk_types::EndOfEpochData,
343 ) -> Self {
344 Self {
345 next_epoch_committee: next_epoch_committee.into_iter().map(Into::into).collect(),
346 next_epoch_protocol_version: Some(next_epoch_protocol_version),
347 epoch_commitments: epoch_commitments.into_iter().map(Into::into).collect(),
348 }
349 }
350}
351
352impl TryFrom<&EndOfEpochData> for sui_sdk_types::EndOfEpochData {
353 type Error = TryFromProtoError;
354
355 fn try_from(
356 EndOfEpochData {
357 next_epoch_committee,
358 next_epoch_protocol_version,
359 epoch_commitments,
360 }: &EndOfEpochData,
361 ) -> Result<Self, Self::Error> {
362 let next_epoch_protocol_version = next_epoch_protocol_version
363 .ok_or_else(|| TryFromProtoError::missing("next_epoch_protocol_version"))?;
364
365 Ok(Self {
366 next_epoch_committee: next_epoch_committee
367 .iter()
368 .map(TryInto::try_into)
369 .collect::<Result<_, _>>()?,
370 next_epoch_protocol_version,
371 epoch_commitments: epoch_commitments
372 .iter()
373 .map(TryInto::try_into)
374 .collect::<Result<_, _>>()?,
375 })
376 }
377}
378
379impl From<&sui_sdk_types::CheckpointTransactionInfo> for CheckpointedTransactionInfo {
384 fn from(value: &sui_sdk_types::CheckpointTransactionInfo) -> Self {
385 Self {
386 transaction: Some(value.transaction().to_string()),
387 effects: Some(value.effects().to_string()),
388 signatures: value.signatures().cloned().map(Into::into).collect(),
389 address_aliases_versions: value
390 .signatures_with_address_aliases_versions()
391 .map(|(_, version)| AddressAliasesVersion { version })
392 .collect(),
393 }
394 }
395}
396
397impl TryFrom<&CheckpointedTransactionInfo> for sui_sdk_types::CheckpointTransactionInfo {
398 type Error = TryFromProtoError;
399
400 fn try_from(value: &CheckpointedTransactionInfo) -> Result<Self, Self::Error> {
401 let transaction = value
402 .transaction
403 .as_ref()
404 .ok_or_else(|| TryFromProtoError::missing("transaction"))?
405 .parse()
406 .map_err(|e| {
407 TryFromProtoError::invalid(CheckpointedTransactionInfo::TRANSACTION_FIELD, e)
408 })?;
409
410 let effects = value
411 .effects
412 .as_ref()
413 .ok_or_else(|| TryFromProtoError::missing("effects"))?
414 .parse()
415 .map_err(|e| {
416 TryFromProtoError::invalid(CheckpointedTransactionInfo::EFFECTS_FIELD, e)
417 })?;
418
419 let signatures: Vec<sui_sdk_types::UserSignature> = value
420 .signatures
421 .iter()
422 .map(TryInto::try_into)
423 .collect::<Result<_, _>>()?;
424
425 let address_aliases_versions: Vec<Option<u64>> = value
426 .address_aliases_versions
427 .iter()
428 .map(|a| a.version)
429 .collect();
430
431 if signatures.len() == address_aliases_versions.len() {
432 Ok(Self::new_with_address_aliases_versions(
433 transaction,
434 effects,
435 signatures
436 .into_iter()
437 .zip(address_aliases_versions)
438 .collect(),
439 ))
440 } else {
441 Ok(Self::new(transaction, effects, signatures))
442 }
443 }
444}
445
446impl From<sui_sdk_types::CheckpointContents> for CheckpointContents {
451 fn from(value: sui_sdk_types::CheckpointContents) -> Self {
452 Self::merge_from(value, &FieldMaskTree::new_wildcard())
453 }
454}
455
456impl Merge<sui_sdk_types::CheckpointContents> for CheckpointContents {
457 fn merge(&mut self, source: sui_sdk_types::CheckpointContents, mask: &FieldMaskTree) {
458 if mask.contains(Self::BCS_FIELD.name) {
459 let mut bcs = Bcs::serialize(&source).unwrap();
460 bcs.name = Some("CheckpointContents".to_owned());
461 self.bcs = Some(bcs);
462 }
463
464 if mask.contains(Self::DIGEST_FIELD.name) {
465 self.digest = Some(source.digest().to_string());
466 }
467
468 if mask.contains(Self::VERSION_FIELD.name) {
469 self.version = Some(source.version() as _);
470 }
471
472 if mask.contains(Self::TRANSACTIONS_FIELD.name) {
473 self.transactions = source.transactions().iter().map(Into::into).collect();
474 }
475 }
476}
477
478impl Merge<&CheckpointContents> for CheckpointContents {
479 fn merge(&mut self, source: &CheckpointContents, mask: &FieldMaskTree) {
480 let CheckpointContents {
481 bcs,
482 digest,
483 version,
484 transactions,
485 } = source;
486
487 if mask.contains(Self::BCS_FIELD.name) {
488 self.bcs = bcs.clone();
489 }
490
491 if mask.contains(Self::DIGEST_FIELD.name) {
492 self.digest = digest.clone();
493 }
494
495 if mask.contains(Self::VERSION_FIELD.name) {
496 self.version = *version;
497 }
498
499 if mask.contains(Self::TRANSACTIONS_FIELD.name) {
500 self.transactions = transactions.clone();
501 }
502 }
503}
504
505impl TryFrom<&CheckpointContents> for sui_sdk_types::CheckpointContents {
506 type Error = TryFromProtoError;
507
508 fn try_from(value: &CheckpointContents) -> Result<Self, Self::Error> {
509 match value.version {
510 Some(1) => Ok(Self::new_v1(
511 value
512 .transactions
513 .iter()
514 .map(TryInto::try_into)
515 .collect::<Result<_, _>>()?,
516 )),
517 Some(2) => Ok(Self::new_v2(
518 value
519 .transactions
520 .iter()
521 .map(TryInto::try_into)
522 .collect::<Result<_, _>>()?,
523 )),
524 v => Err(TryFromProtoError::invalid(
525 CheckpointContents::VERSION_FIELD,
526 format!("unknown type version {v:?}"),
527 )),
528 }
529 }
530}
531
532impl Merge<&sui_sdk_types::CheckpointSummary> for Checkpoint {
537 fn merge(&mut self, source: &sui_sdk_types::CheckpointSummary, mask: &FieldMaskTree) {
538 if mask.contains(Self::SEQUENCE_NUMBER_FIELD.name) {
539 self.sequence_number = Some(source.sequence_number);
540 }
541
542 if mask.contains(Self::DIGEST_FIELD.name) {
543 self.digest = Some(source.digest().to_string());
544 }
545
546 if let Some(submask) = mask.subtree(Self::SUMMARY_FIELD.name) {
547 self.summary = Some(CheckpointSummary::merge_from(source.clone(), &submask));
548 }
549 }
550}
551
552impl Merge<sui_sdk_types::ValidatorAggregatedSignature> for Checkpoint {
553 fn merge(&mut self, source: sui_sdk_types::ValidatorAggregatedSignature, mask: &FieldMaskTree) {
554 if mask.contains(Self::SIGNATURE_FIELD.name) {
555 self.signature = Some(source.into());
556 }
557 }
558}
559
560impl Merge<sui_sdk_types::CheckpointContents> for Checkpoint {
561 fn merge(&mut self, source: sui_sdk_types::CheckpointContents, mask: &FieldMaskTree) {
562 if let Some(submask) = mask.subtree(Self::CONTENTS_FIELD.name) {
563 self.contents = Some(CheckpointContents::merge_from(source, &submask));
564 }
565 }
566}
567
568impl Merge<&Checkpoint> for Checkpoint {
569 fn merge(&mut self, source: &Checkpoint, mask: &FieldMaskTree) {
570 let Checkpoint {
571 sequence_number,
572 digest,
573 summary,
574 signature,
575 contents,
576 transactions,
577 objects,
578 } = source;
579
580 if mask.contains(Self::SEQUENCE_NUMBER_FIELD.name) {
581 self.sequence_number = *sequence_number;
582 }
583
584 if mask.contains(Self::DIGEST_FIELD.name) {
585 self.digest = digest.clone();
586 }
587
588 if let Some(submask) = mask.subtree(Self::SUMMARY_FIELD.name) {
589 self.summary = summary
590 .as_ref()
591 .map(|summary| CheckpointSummary::merge_from(summary, &submask));
592 }
593
594 if mask.contains(Self::SIGNATURE_FIELD.name) {
595 self.signature = signature.clone();
596 }
597
598 if let Some(submask) = mask.subtree(Self::CONTENTS_FIELD.name) {
599 self.contents = contents
600 .as_ref()
601 .map(|contents| CheckpointContents::merge_from(contents, &submask));
602 }
603
604 if let Some(submask) = mask.subtree(Self::TRANSACTIONS_FIELD.name) {
605 self.transactions = transactions
606 .iter()
607 .map(|transaction| ExecutedTransaction::merge_from(transaction, &submask))
608 .collect();
609 }
610
611 if let Some(submask) = mask.subtree(Self::OBJECTS_FIELD) {
612 self.objects = objects
613 .as_ref()
614 .map(|objects| ObjectSet::merge_from(objects, &submask));
615 }
616 }
617}