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.into_iter().map(Into::into).collect(),
389 }
390 }
391}
392
393impl TryFrom<&CheckpointedTransactionInfo> for sui_sdk_types::CheckpointTransactionInfo {
394 type Error = TryFromProtoError;
395
396 fn try_from(value: &CheckpointedTransactionInfo) -> Result<Self, Self::Error> {
397 let transaction = value
398 .transaction
399 .as_ref()
400 .ok_or_else(|| TryFromProtoError::missing("transaction"))?
401 .parse()
402 .map_err(|e| {
403 TryFromProtoError::invalid(CheckpointedTransactionInfo::TRANSACTION_FIELD, e)
404 })?;
405
406 let effects = value
407 .effects
408 .as_ref()
409 .ok_or_else(|| TryFromProtoError::missing("effects"))?
410 .parse()
411 .map_err(|e| {
412 TryFromProtoError::invalid(CheckpointedTransactionInfo::EFFECTS_FIELD, e)
413 })?;
414
415 let signatures = value
416 .signatures
417 .iter()
418 .map(TryInto::try_into)
419 .collect::<Result<_, _>>()?;
420
421 Ok(Self {
422 transaction,
423 effects,
424 signatures,
425 })
426 }
427}
428
429impl From<sui_sdk_types::CheckpointContents> for CheckpointContents {
434 fn from(value: sui_sdk_types::CheckpointContents) -> Self {
435 Self::merge_from(value, &FieldMaskTree::new_wildcard())
436 }
437}
438
439impl Merge<sui_sdk_types::CheckpointContents> for CheckpointContents {
440 fn merge(&mut self, source: sui_sdk_types::CheckpointContents, mask: &FieldMaskTree) {
441 if mask.contains(Self::BCS_FIELD.name) {
442 let mut bcs = Bcs::serialize(&source).unwrap();
443 bcs.name = Some("CheckpointContents".to_owned());
444 self.bcs = Some(bcs);
445 }
446
447 if mask.contains(Self::DIGEST_FIELD.name) {
448 self.digest = Some(source.digest().to_string());
449 }
450
451 if mask.contains(Self::VERSION_FIELD.name) {
452 self.version = Some(1);
453 }
454
455 if mask.contains(Self::TRANSACTIONS_FIELD.name) {
456 self.transactions = source.into_v1().into_iter().map(Into::into).collect();
457 }
458 }
459}
460
461impl Merge<&CheckpointContents> for CheckpointContents {
462 fn merge(&mut self, source: &CheckpointContents, mask: &FieldMaskTree) {
463 let CheckpointContents {
464 bcs,
465 digest,
466 version,
467 transactions,
468 } = source;
469
470 if mask.contains(Self::BCS_FIELD.name) {
471 self.bcs = bcs.clone();
472 }
473
474 if mask.contains(Self::DIGEST_FIELD.name) {
475 self.digest = digest.clone();
476 }
477
478 if mask.contains(Self::VERSION_FIELD.name) {
479 self.version = *version;
480 }
481
482 if mask.contains(Self::TRANSACTIONS_FIELD.name) {
483 self.transactions = transactions.clone();
484 }
485 }
486}
487
488impl TryFrom<&CheckpointContents> for sui_sdk_types::CheckpointContents {
489 type Error = TryFromProtoError;
490
491 fn try_from(value: &CheckpointContents) -> Result<Self, Self::Error> {
492 match value.version {
493 Some(1) => {}
494 v => {
495 return Err(TryFromProtoError::invalid(
496 CheckpointContents::VERSION_FIELD,
497 format!("unknown type version {v:?}"),
498 ));
499 }
500 }
501
502 Ok(Self::new(
503 value
504 .transactions
505 .iter()
506 .map(TryInto::try_into)
507 .collect::<Result<_, _>>()?,
508 ))
509 }
510}
511
512impl Merge<&sui_sdk_types::CheckpointSummary> for Checkpoint {
517 fn merge(&mut self, source: &sui_sdk_types::CheckpointSummary, mask: &FieldMaskTree) {
518 if mask.contains(Self::SEQUENCE_NUMBER_FIELD.name) {
519 self.sequence_number = Some(source.sequence_number);
520 }
521
522 if mask.contains(Self::DIGEST_FIELD.name) {
523 self.digest = Some(source.digest().to_string());
524 }
525
526 if let Some(submask) = mask.subtree(Self::SUMMARY_FIELD.name) {
527 self.summary = Some(CheckpointSummary::merge_from(source.clone(), &submask));
528 }
529 }
530}
531
532impl Merge<sui_sdk_types::ValidatorAggregatedSignature> for Checkpoint {
533 fn merge(&mut self, source: sui_sdk_types::ValidatorAggregatedSignature, mask: &FieldMaskTree) {
534 if mask.contains(Self::SIGNATURE_FIELD.name) {
535 self.signature = Some(source.into());
536 }
537 }
538}
539
540impl Merge<sui_sdk_types::CheckpointContents> for Checkpoint {
541 fn merge(&mut self, source: sui_sdk_types::CheckpointContents, mask: &FieldMaskTree) {
542 if let Some(submask) = mask.subtree(Self::CONTENTS_FIELD.name) {
543 self.contents = Some(CheckpointContents::merge_from(source, &submask));
544 }
545 }
546}
547
548impl Merge<&Checkpoint> for Checkpoint {
549 fn merge(&mut self, source: &Checkpoint, mask: &FieldMaskTree) {
550 let Checkpoint {
551 sequence_number,
552 digest,
553 summary,
554 signature,
555 contents,
556 transactions,
557 objects,
558 } = source;
559
560 if mask.contains(Self::SEQUENCE_NUMBER_FIELD.name) {
561 self.sequence_number = *sequence_number;
562 }
563
564 if mask.contains(Self::DIGEST_FIELD.name) {
565 self.digest = digest.clone();
566 }
567
568 if let Some(submask) = mask.subtree(Self::SUMMARY_FIELD.name) {
569 self.summary = summary
570 .as_ref()
571 .map(|summary| CheckpointSummary::merge_from(summary, &submask));
572 }
573
574 if mask.contains(Self::SIGNATURE_FIELD.name) {
575 self.signature = signature.clone();
576 }
577
578 if let Some(submask) = mask.subtree(Self::CONTENTS_FIELD.name) {
579 self.contents = contents
580 .as_ref()
581 .map(|contents| CheckpointContents::merge_from(contents, &submask));
582 }
583
584 if let Some(submask) = mask.subtree(Self::TRANSACTIONS_FIELD.name) {
585 self.transactions = transactions
586 .iter()
587 .map(|transaction| ExecutedTransaction::merge_from(transaction, &submask))
588 .collect();
589 }
590
591 if let Some(submask) = mask.subtree(Self::OBJECTS_FIELD) {
592 self.objects = objects
593 .as_ref()
594 .map(|objects| ObjectSet::merge_from(objects, &submask));
595 }
596 }
597}