1use crate::crypto::SuiSignature;
7use nonempty::NonEmpty;
8
9fn ms_to_timestamp(ms: u64) -> prost_types::Timestamp {
10 prost_types::Timestamp {
11 seconds: (ms / 1000) as _,
12 nanos: ((ms % 1000) * 1_000_000) as _,
13 }
14}
15
16fn timestamp_to_ms(timestamp: &prost_types::Timestamp) -> Result<u64, &'static str> {
17 let seconds: u64 = timestamp
18 .seconds
19 .try_into()
20 .map_err(|_| "invalid timestamp: negative seconds")?;
21 let nanos: u64 = timestamp
22 .nanos
23 .try_into()
24 .map_err(|_| "invalid timestamp: negative nanos")?;
25 seconds
26 .checked_mul(1000)
27 .and_then(|ms| ms.checked_add(nanos / 1_000_000))
28 .ok_or("invalid timestamp: out of range")
29}
30use crate::message_envelope::Message as _;
31use fastcrypto::traits::ToFromBytes;
32use sui_rpc::field::FieldMaskTree;
33use sui_rpc::merge::Merge;
34use sui_rpc::proto::TryFromProtoError;
35use sui_rpc::proto::sui::rpc::v2::*;
36
37impl Merge<&crate::full_checkpoint_content::Checkpoint> for Checkpoint {
42 fn merge(&mut self, source: &crate::full_checkpoint_content::Checkpoint, mask: &FieldMaskTree) {
43 let sequence_number = source.summary.sequence_number;
44 let timestamp_ms = source.summary.timestamp_ms;
45
46 let summary = source.summary.data();
47 let signature = source.summary.auth_sig();
48
49 self.merge(summary, mask);
50 self.merge(signature.clone(), mask);
51
52 if mask.contains(Checkpoint::CONTENTS_FIELD.name) {
53 self.merge(&source.contents, mask);
54 }
55
56 if let Some(submask) = mask
57 .subtree(Checkpoint::OBJECTS_FIELD)
58 .and_then(|submask| submask.subtree(ObjectSet::OBJECTS_FIELD))
59 {
60 let set = source
61 .object_set
62 .iter()
63 .map(|o| sui_rpc::proto::sui::rpc::v2::Object::merge_from(o, &submask))
64 .collect();
65 self.objects = Some(ObjectSet::default().with_objects(set));
66 }
67
68 if let Some(submask) = mask.subtree(Checkpoint::TRANSACTIONS_FIELD.name) {
69 self.transactions = source
70 .transactions
71 .iter()
72 .map(|t| {
73 let mut transaction = ExecutedTransaction::merge_from(t, &submask);
74 transaction.checkpoint = submask
75 .contains(ExecutedTransaction::CHECKPOINT_FIELD)
76 .then_some(sequence_number);
77 transaction.timestamp = submask
78 .contains(ExecutedTransaction::TIMESTAMP_FIELD)
79 .then(|| sui_rpc::proto::timestamp_ms_to_proto(timestamp_ms));
80 transaction
81 })
82 .collect();
83 }
84 }
85}
86
87impl Merge<&crate::full_checkpoint_content::ExecutedTransaction> for ExecutedTransaction {
88 fn merge(
89 &mut self,
90 source: &crate::full_checkpoint_content::ExecutedTransaction,
91 mask: &FieldMaskTree,
92 ) {
93 use crate::effects::TransactionEffectsAPI;
94
95 let transaction_mask = mask.subtree(ExecutedTransaction::TRANSACTION_FIELD);
96 let top_level_digest_selected = mask.contains(ExecutedTransaction::DIGEST_FIELD);
97 let nested_digest_selected = transaction_mask
98 .as_ref()
99 .is_some_and(|submask| submask.contains(Transaction::DIGEST_FIELD.name));
100 let (top_level_digest_string, nested_digest_string) =
101 match (top_level_digest_selected, nested_digest_selected) {
102 (false, false) => (None, None),
103 (true, false) => (
104 Some(source.effects.transaction_digest().base58_encode()),
105 None,
106 ),
107 (false, true) => (
108 None,
109 Some(source.effects.transaction_digest().base58_encode()),
110 ),
111 (true, true) => {
112 let digest_string = source.effects.transaction_digest().base58_encode();
113 (Some(digest_string.clone()), Some(digest_string))
114 }
115 };
116
117 if top_level_digest_selected {
118 self.digest = top_level_digest_string;
119 }
120
121 if let Some(submask) = transaction_mask {
122 let mut transaction = Transaction::default();
123 merge_transaction_data(
124 &mut transaction,
125 &source.transaction,
126 nested_digest_string,
127 &submask,
128 );
129 self.transaction = Some(transaction);
130 }
131
132 if let Some(submask) = mask.subtree(ExecutedTransaction::SIGNATURES_FIELD) {
133 self.signatures = source
134 .signatures
135 .iter()
136 .map(|s| UserSignature::merge_from(s, &submask))
137 .collect();
138 }
139
140 if let Some(submask) = mask.subtree(ExecutedTransaction::EFFECTS_FIELD) {
141 let mut effects = TransactionEffects::merge_from(&source.effects, &submask);
142 if submask.contains(TransactionEffects::UNCHANGED_LOADED_RUNTIME_OBJECTS_FIELD) {
143 effects.set_unchanged_loaded_runtime_objects(
144 source
145 .unchanged_loaded_runtime_objects
146 .iter()
147 .map(Into::into)
148 .collect(),
149 );
150 }
151 self.effects = Some(effects);
152 }
153
154 if let Some(submask) = mask.subtree(ExecutedTransaction::EVENTS_FIELD) {
155 self.events = source
156 .events
157 .as_ref()
158 .map(|events| TransactionEvents::merge_from(events, &submask));
159 }
160 }
161}
162
163impl TryFrom<&Checkpoint> for crate::full_checkpoint_content::Checkpoint {
164 type Error = TryFromProtoError;
165
166 fn try_from(checkpoint: &Checkpoint) -> Result<Self, Self::Error> {
167 let summary = checkpoint
168 .summary()
169 .bcs()
170 .deserialize()
171 .map_err(|e| TryFromProtoError::invalid("summary.bcs", e))?;
172
173 let signature =
174 crate::crypto::AuthorityStrongQuorumSignInfo::try_from(checkpoint.signature())?;
175
176 let summary = crate::messages_checkpoint::CertifiedCheckpointSummary::new_from_data_and_sig(
177 summary, signature,
178 );
179
180 let contents: crate::messages_checkpoint::CheckpointContents = checkpoint
181 .contents()
182 .bcs()
183 .deserialize()
184 .map_err(|e| TryFromProtoError::invalid("contents.bcs", e))?;
185
186 let user_signatures: Vec<_> = contents
187 .clone()
188 .into_iter_with_signatures()
189 .map(|(_, user_signatures)| user_signatures)
190 .collect();
191
192 #[allow(clippy::disallowed_methods)]
193 let transactions = checkpoint
195 .transactions()
196 .iter()
197 .zip(user_signatures)
198 .map(|(tx, user_signatures)| {
199 let mut executed_tx: crate::full_checkpoint_content::ExecutedTransaction =
200 tx.try_into()?;
201 executed_tx.signatures = user_signatures;
202 Ok(executed_tx)
203 })
204 .collect::<Result<_, TryFromProtoError>>()?;
205
206 let object_set = checkpoint.objects().try_into()?;
207
208 Ok(Self {
209 summary,
210 contents,
211 transactions,
212 object_set,
213 })
214 }
215}
216
217impl TryFrom<&ExecutedTransaction> for crate::full_checkpoint_content::ExecutedTransaction {
218 type Error = TryFromProtoError;
219
220 fn try_from(value: &ExecutedTransaction) -> Result<Self, Self::Error> {
221 Ok(Self {
222 transaction: value
223 .transaction()
224 .bcs()
225 .deserialize()
226 .map_err(|e| TryFromProtoError::invalid("transaction.bcs", e))?,
227 signatures: value
228 .signatures()
229 .iter()
230 .map(|sig| {
231 crate::signature::GenericSignature::from_bytes(sig.bcs().value())
232 .map_err(|e| TryFromProtoError::invalid("signature.bcs", e))
233 })
234 .collect::<Result<_, _>>()?,
235 effects: value
236 .effects()
237 .bcs()
238 .deserialize()
239 .map_err(|e| TryFromProtoError::invalid("effects.bcs", e))?,
240 events: value
241 .events_opt()
242 .map(|events| {
243 events
244 .bcs()
245 .deserialize()
246 .map_err(|e| TryFromProtoError::invalid("effects.bcs", e))
247 })
248 .transpose()?,
249 unchanged_loaded_runtime_objects: value
250 .effects()
251 .unchanged_loaded_runtime_objects()
252 .iter()
253 .map(TryInto::try_into)
254 .collect::<Result<_, _>>()?,
255 })
256 }
257}
258
259impl TryFrom<&ObjectReference> for crate::storage::ObjectKey {
260 type Error = TryFromProtoError;
261
262 fn try_from(value: &ObjectReference) -> Result<Self, Self::Error> {
263 Ok(Self(
264 value
265 .object_id()
266 .parse()
267 .map_err(|e| TryFromProtoError::invalid("object_id", e))?,
268 value.version().into(),
269 ))
270 }
271}
272
273impl From<crate::messages_checkpoint::CheckpointSummary> for CheckpointSummary {
278 fn from(summary: crate::messages_checkpoint::CheckpointSummary) -> Self {
279 Self::merge_from(summary, &FieldMaskTree::new_wildcard())
280 }
281}
282
283impl Merge<crate::messages_checkpoint::CheckpointSummary> for CheckpointSummary {
284 fn merge(
285 &mut self,
286 source: crate::messages_checkpoint::CheckpointSummary,
287 mask: &FieldMaskTree,
288 ) {
289 if mask.contains(Self::BCS_FIELD) {
290 let mut bcs = Bcs::serialize(&source).unwrap();
291 bcs.name = Some("CheckpointSummary".to_owned());
292 self.bcs = Some(bcs);
293 }
294
295 if mask.contains(Self::DIGEST_FIELD) {
296 self.digest = Some(source.digest().to_string());
297 }
298
299 let crate::messages_checkpoint::CheckpointSummary {
300 epoch,
301 sequence_number,
302 network_total_transactions,
303 content_digest,
304 previous_digest,
305 epoch_rolling_gas_cost_summary,
306 timestamp_ms,
307 checkpoint_commitments,
308 end_of_epoch_data,
309 version_specific_data,
310 } = source;
311
312 if mask.contains(Self::EPOCH_FIELD) {
313 self.epoch = Some(epoch);
314 }
315
316 if mask.contains(Self::SEQUENCE_NUMBER_FIELD) {
317 self.sequence_number = Some(sequence_number);
318 }
319
320 if mask.contains(Self::TOTAL_NETWORK_TRANSACTIONS_FIELD) {
321 self.total_network_transactions = Some(network_total_transactions);
322 }
323
324 if mask.contains(Self::CONTENT_DIGEST_FIELD) {
325 self.content_digest = Some(content_digest.to_string());
326 }
327
328 if mask.contains(Self::PREVIOUS_DIGEST_FIELD) {
329 self.previous_digest = previous_digest.map(|d| d.to_string());
330 }
331
332 if mask.contains(Self::EPOCH_ROLLING_GAS_COST_SUMMARY_FIELD) {
333 self.epoch_rolling_gas_cost_summary = Some(epoch_rolling_gas_cost_summary.into());
334 }
335
336 if mask.contains(Self::TIMESTAMP_FIELD) {
337 self.timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(timestamp_ms));
338 }
339
340 if mask.contains(Self::COMMITMENTS_FIELD) {
341 self.commitments = checkpoint_commitments.into_iter().map(Into::into).collect();
342 }
343
344 if mask.contains(Self::END_OF_EPOCH_DATA_FIELD) {
345 self.end_of_epoch_data = end_of_epoch_data.map(Into::into);
346 }
347
348 if mask.contains(Self::VERSION_SPECIFIC_DATA_FIELD) {
349 self.version_specific_data = Some(version_specific_data.into());
350 }
351 }
352}
353
354impl From<crate::gas::GasCostSummary> for GasCostSummary {
359 fn from(
360 crate::gas::GasCostSummary {
361 computation_cost,
362 storage_cost,
363 storage_rebate,
364 non_refundable_storage_fee,
365 }: crate::gas::GasCostSummary,
366 ) -> Self {
367 let mut message = Self::default();
368 message.computation_cost = Some(computation_cost);
369 message.storage_cost = Some(storage_cost);
370 message.storage_rebate = Some(storage_rebate);
371 message.non_refundable_storage_fee = Some(non_refundable_storage_fee);
372 message
373 }
374}
375
376impl From<crate::messages_checkpoint::CheckpointCommitment> for CheckpointCommitment {
381 fn from(value: crate::messages_checkpoint::CheckpointCommitment) -> Self {
382 use checkpoint_commitment::CheckpointCommitmentKind;
383
384 let mut message = Self::default();
385
386 let kind = match value {
387 crate::messages_checkpoint::CheckpointCommitment::ECMHLiveObjectSetDigest(digest) => {
388 message.digest = Some(digest.digest.to_string());
389 CheckpointCommitmentKind::EcmhLiveObjectSet
390 }
391 crate::messages_checkpoint::CheckpointCommitment::CheckpointArtifactsDigest(digest) => {
392 message.digest = Some(digest.to_string());
393 CheckpointCommitmentKind::CheckpointArtifacts
394 }
395 };
396
397 message.set_kind(kind);
398 message
399 }
400}
401
402impl From<crate::messages_checkpoint::EndOfEpochData> for EndOfEpochData {
407 fn from(
408 crate::messages_checkpoint::EndOfEpochData {
409 next_epoch_committee,
410 next_epoch_protocol_version,
411 epoch_commitments,
412 }: crate::messages_checkpoint::EndOfEpochData,
413 ) -> Self {
414 let mut message = Self::default();
415
416 message.next_epoch_committee = next_epoch_committee
417 .into_iter()
418 .map(|(name, weight)| {
419 let mut member = ValidatorCommitteeMember::default();
420 member.public_key = Some(name.0.to_vec().into());
421 member.weight = Some(weight);
422 member
423 })
424 .collect();
425 message.next_epoch_protocol_version = Some(next_epoch_protocol_version.as_u64());
426 message.epoch_commitments = epoch_commitments.into_iter().map(Into::into).collect();
427
428 message
429 }
430}
431
432impl From<crate::messages_checkpoint::CheckpointContents> for CheckpointContents {
437 fn from(value: crate::messages_checkpoint::CheckpointContents) -> Self {
438 Self::merge_from(value, &FieldMaskTree::new_wildcard())
439 }
440}
441
442impl Merge<crate::messages_checkpoint::CheckpointContents> for CheckpointContents {
443 fn merge(
444 &mut self,
445 source: crate::messages_checkpoint::CheckpointContents,
446 mask: &FieldMaskTree,
447 ) {
448 if mask.contains(Self::BCS_FIELD) {
449 let mut bcs = Bcs::serialize(&source).unwrap();
450 bcs.name = Some("CheckpointContents".to_owned());
451 self.bcs = Some(bcs);
452 }
453
454 if mask.contains(Self::DIGEST_FIELD) {
455 self.digest = Some(source.digest().to_string());
456 }
457
458 if mask.contains(Self::VERSION_FIELD) {
459 self.set_version(match &source {
460 crate::messages_checkpoint::CheckpointContents::V1(_) => 1,
461 crate::messages_checkpoint::CheckpointContents::V2(_) => 2,
462 });
463 }
464
465 if mask.contains(Self::TRANSACTIONS_FIELD) {
466 self.transactions = source
467 .inner()
468 .iter()
469 .map(|(digests, sigs)| {
470 let mut info = CheckpointedTransactionInfo::default();
471 info.transaction = Some(digests.transaction.to_string());
472 info.effects = Some(digests.effects.to_string());
473 let (signatures, versions) = sigs
474 .map(|(s, v)| {
475 (s.into(), {
476 let mut message = AddressAliasesVersion::default();
477 message.version = v.map(Into::into);
478 message
479 })
480 })
481 .unzip();
482 info.signatures = signatures;
483 info.address_aliases_versions = versions;
484 info
485 })
486 .collect();
487 }
488 }
489}
490
491impl Merge<&crate::messages_checkpoint::CheckpointContents> for Checkpoint {
492 fn merge(
493 &mut self,
494 source: &crate::messages_checkpoint::CheckpointContents,
495 mask: &FieldMaskTree,
496 ) {
497 if let Some(submask) = mask.subtree(Self::CONTENTS_FIELD.name) {
498 self.contents = Some(CheckpointContents::merge_from(source.to_owned(), &submask));
499 }
500 }
501}
502
503impl Merge<&crate::messages_checkpoint::CheckpointSummary> for Checkpoint {
508 fn merge(
509 &mut self,
510 source: &crate::messages_checkpoint::CheckpointSummary,
511 mask: &FieldMaskTree,
512 ) {
513 if mask.contains(Self::SEQUENCE_NUMBER_FIELD) {
514 self.sequence_number = Some(source.sequence_number);
515 }
516
517 if mask.contains(Self::DIGEST_FIELD) {
518 self.digest = Some(source.digest().to_string());
519 }
520
521 if let Some(submask) = mask.subtree(Self::SUMMARY_FIELD) {
522 self.summary = Some(CheckpointSummary::merge_from(source.clone(), &submask));
523 }
524 }
525}
526
527impl<const T: bool> Merge<crate::crypto::AuthorityQuorumSignInfo<T>> for Checkpoint {
528 fn merge(&mut self, source: crate::crypto::AuthorityQuorumSignInfo<T>, mask: &FieldMaskTree) {
529 if mask.contains(Self::SIGNATURE_FIELD) {
530 self.signature = Some(source.into());
531 }
532 }
533}
534
535impl Merge<crate::messages_checkpoint::CheckpointContents> for Checkpoint {
536 fn merge(
537 &mut self,
538 source: crate::messages_checkpoint::CheckpointContents,
539 mask: &FieldMaskTree,
540 ) {
541 if let Some(submask) = mask.subtree(Self::CONTENTS_FIELD) {
542 self.contents = Some(CheckpointContents::merge_from(source, &submask));
543 }
544 }
545}
546
547impl From<crate::event::Event> for Event {
552 fn from(value: crate::event::Event) -> Self {
553 Self::merge_from(&value, &FieldMaskTree::new_wildcard())
554 }
555}
556
557impl Merge<&crate::event::Event> for Event {
558 fn merge(&mut self, source: &crate::event::Event, mask: &FieldMaskTree) {
559 if mask.contains(Self::PACKAGE_ID_FIELD) {
560 self.package_id = Some(source.package_id.to_canonical_string(true));
561 }
562
563 if mask.contains(Self::MODULE_FIELD) {
564 self.module = Some(source.transaction_module.to_string());
565 }
566
567 if mask.contains(Self::SENDER_FIELD) {
568 self.sender = Some(source.sender.to_string());
569 }
570
571 if mask.contains(Self::EVENT_TYPE_FIELD) {
572 self.event_type = Some(source.type_.to_canonical_string(true));
573 }
574
575 if mask.contains(Self::CONTENTS_FIELD) {
576 let mut bcs = Bcs::from(source.contents.clone());
577 bcs.name = Some(source.type_.to_canonical_string(true));
578 self.contents = Some(bcs);
579 }
580 }
581}
582
583impl From<crate::effects::TransactionEvents> for TransactionEvents {
588 fn from(value: crate::effects::TransactionEvents) -> Self {
589 Self::merge_from(&value, &FieldMaskTree::new_wildcard())
590 }
591}
592
593impl Merge<&crate::effects::TransactionEvents> for TransactionEvents {
594 fn merge(&mut self, source: &crate::effects::TransactionEvents, mask: &FieldMaskTree) {
595 if mask.contains(Self::BCS_FIELD) {
596 let mut bcs = Bcs::serialize(&source).unwrap();
597 bcs.name = Some("TransactionEvents".to_owned());
598 self.bcs = Some(bcs);
599 }
600
601 if mask.contains(Self::DIGEST_FIELD) {
602 self.digest = Some(source.digest().to_string());
603 }
604
605 if let Some(events_mask) = mask.subtree(Self::EVENTS_FIELD) {
606 self.events = source
607 .data
608 .iter()
609 .map(|event| Event::merge_from(event, &events_mask))
610 .collect();
611 }
612 }
613}
614
615impl From<crate::sui_system_state::SuiSystemState> for SystemState {
620 fn from(value: crate::sui_system_state::SuiSystemState) -> Self {
621 match value {
622 crate::sui_system_state::SuiSystemState::V1(v1) => v1.into(),
623 crate::sui_system_state::SuiSystemState::V2(v2) => v2.into(),
624
625 #[allow(unreachable_patterns)]
626 _ => Self::default(),
627 }
628 }
629}
630
631impl From<crate::sui_system_state::sui_system_state_inner_v1::SuiSystemStateInnerV1>
632 for SystemState
633{
634 fn from(
635 crate::sui_system_state::sui_system_state_inner_v1::SuiSystemStateInnerV1 {
636 epoch,
637 protocol_version,
638 system_state_version,
639 validators,
640 storage_fund,
641 parameters,
642 reference_gas_price,
643 validator_report_records,
644 stake_subsidy,
645 safe_mode,
646 safe_mode_storage_rewards,
647 safe_mode_computation_rewards,
648 safe_mode_storage_rebates,
649 safe_mode_non_refundable_storage_fee,
650 epoch_start_timestamp_ms,
651 extra_fields,
652 }: crate::sui_system_state::sui_system_state_inner_v1::SuiSystemStateInnerV1,
653 ) -> Self {
654 let validator_report_records = validator_report_records
655 .contents
656 .into_iter()
657 .map(|entry| {
658 let mut record = ValidatorReportRecord::default();
659 record.reported = Some(entry.key.to_string());
660 record.reporters = entry
661 .value
662 .contents
663 .iter()
664 .map(ToString::to_string)
665 .collect();
666 record
667 })
668 .collect();
669
670 let mut message = Self::default();
671
672 message.version = Some(system_state_version);
673 message.epoch = Some(epoch);
674 message.protocol_version = Some(protocol_version);
675 message.validators = Some(validators.into());
676 message.storage_fund = Some(storage_fund.into());
677 message.parameters = Some(parameters.into());
678 message.reference_gas_price = Some(reference_gas_price);
679 message.validator_report_records = validator_report_records;
680 message.stake_subsidy = Some(stake_subsidy.into());
681 message.safe_mode = Some(safe_mode);
682 message.safe_mode_storage_rewards = Some(safe_mode_storage_rewards.value());
683 message.safe_mode_computation_rewards = Some(safe_mode_computation_rewards.value());
684 message.safe_mode_storage_rebates = Some(safe_mode_storage_rebates);
685 message.safe_mode_non_refundable_storage_fee = Some(safe_mode_non_refundable_storage_fee);
686 message.epoch_start_timestamp_ms = Some(epoch_start_timestamp_ms);
687 message.extra_fields = Some(extra_fields.into());
688 message
689 }
690}
691
692impl From<crate::sui_system_state::sui_system_state_inner_v2::SuiSystemStateInnerV2>
693 for SystemState
694{
695 fn from(
696 crate::sui_system_state::sui_system_state_inner_v2::SuiSystemStateInnerV2 {
697 epoch,
698 protocol_version,
699 system_state_version,
700 validators,
701 storage_fund,
702 parameters,
703 reference_gas_price,
704 validator_report_records,
705 stake_subsidy,
706 safe_mode,
707 safe_mode_storage_rewards,
708 safe_mode_computation_rewards,
709 safe_mode_storage_rebates,
710 safe_mode_non_refundable_storage_fee,
711 epoch_start_timestamp_ms,
712 extra_fields,
713 }: crate::sui_system_state::sui_system_state_inner_v2::SuiSystemStateInnerV2,
714 ) -> Self {
715 let validator_report_records = validator_report_records
716 .contents
717 .into_iter()
718 .map(|entry| {
719 let mut record = ValidatorReportRecord::default();
720 record.reported = Some(entry.key.to_string());
721 record.reporters = entry
722 .value
723 .contents
724 .iter()
725 .map(ToString::to_string)
726 .collect();
727 record
728 })
729 .collect();
730
731 let mut message = Self::default();
732
733 message.version = Some(system_state_version);
734 message.epoch = Some(epoch);
735 message.protocol_version = Some(protocol_version);
736 message.validators = Some(validators.into());
737 message.storage_fund = Some(storage_fund.into());
738 message.parameters = Some(parameters.into());
739 message.reference_gas_price = Some(reference_gas_price);
740 message.validator_report_records = validator_report_records;
741 message.stake_subsidy = Some(stake_subsidy.into());
742 message.safe_mode = Some(safe_mode);
743 message.safe_mode_storage_rewards = Some(safe_mode_storage_rewards.value());
744 message.safe_mode_computation_rewards = Some(safe_mode_computation_rewards.value());
745 message.safe_mode_storage_rebates = Some(safe_mode_storage_rebates);
746 message.safe_mode_non_refundable_storage_fee = Some(safe_mode_non_refundable_storage_fee);
747 message.epoch_start_timestamp_ms = Some(epoch_start_timestamp_ms);
748 message.extra_fields = Some(extra_fields.into());
749 message
750 }
751}
752
753impl From<crate::collection_types::Bag> for MoveTable {
754 fn from(crate::collection_types::Bag { id, size }: crate::collection_types::Bag) -> Self {
755 let mut message = Self::default();
756 message.id = Some(id.id.bytes.to_canonical_string(true));
757 message.size = Some(size);
758 message
759 }
760}
761
762impl From<crate::collection_types::Table> for MoveTable {
763 fn from(crate::collection_types::Table { id, size }: crate::collection_types::Table) -> Self {
764 let mut message = Self::default();
765 message.id = Some(id.to_canonical_string(true));
766 message.size = Some(size);
767 message
768 }
769}
770
771impl From<crate::collection_types::TableVec> for MoveTable {
772 fn from(value: crate::collection_types::TableVec) -> Self {
773 value.contents.into()
774 }
775}
776
777impl From<crate::sui_system_state::sui_system_state_inner_v1::StakeSubsidyV1> for StakeSubsidy {
778 fn from(
779 crate::sui_system_state::sui_system_state_inner_v1::StakeSubsidyV1 {
780 balance,
781 distribution_counter,
782 current_distribution_amount,
783 stake_subsidy_period_length,
784 stake_subsidy_decrease_rate,
785 extra_fields,
786 }: crate::sui_system_state::sui_system_state_inner_v1::StakeSubsidyV1,
787 ) -> Self {
788 let mut message = Self::default();
789 message.balance = Some(balance.value());
790 message.distribution_counter = Some(distribution_counter);
791 message.current_distribution_amount = Some(current_distribution_amount);
792 message.stake_subsidy_period_length = Some(stake_subsidy_period_length);
793 message.stake_subsidy_decrease_rate = Some(stake_subsidy_decrease_rate.into());
794 message.extra_fields = Some(extra_fields.into());
795 message
796 }
797}
798
799impl From<crate::sui_system_state::sui_system_state_inner_v1::SystemParametersV1>
800 for SystemParameters
801{
802 fn from(
803 crate::sui_system_state::sui_system_state_inner_v1::SystemParametersV1 {
804 epoch_duration_ms,
805 stake_subsidy_start_epoch,
806 max_validator_count,
807 min_validator_joining_stake,
808 validator_low_stake_threshold,
809 validator_very_low_stake_threshold,
810 validator_low_stake_grace_period,
811 extra_fields,
812 }: crate::sui_system_state::sui_system_state_inner_v1::SystemParametersV1,
813 ) -> Self {
814 let mut message = Self::default();
815 message.epoch_duration_ms = Some(epoch_duration_ms);
816 message.stake_subsidy_start_epoch = Some(stake_subsidy_start_epoch);
817 message.min_validator_count = None;
818 message.max_validator_count = Some(max_validator_count);
819 message.min_validator_joining_stake = Some(min_validator_joining_stake);
820 message.validator_low_stake_threshold = Some(validator_low_stake_threshold);
821 message.validator_very_low_stake_threshold = Some(validator_very_low_stake_threshold);
822 message.validator_low_stake_grace_period = Some(validator_low_stake_grace_period);
823 message.extra_fields = Some(extra_fields.into());
824 message
825 }
826}
827
828impl From<crate::sui_system_state::sui_system_state_inner_v2::SystemParametersV2>
829 for SystemParameters
830{
831 fn from(
832 crate::sui_system_state::sui_system_state_inner_v2::SystemParametersV2 {
833 epoch_duration_ms,
834 stake_subsidy_start_epoch,
835 min_validator_count,
836 max_validator_count,
837 min_validator_joining_stake,
838 validator_low_stake_threshold,
839 validator_very_low_stake_threshold,
840 validator_low_stake_grace_period,
841 extra_fields,
842 }: crate::sui_system_state::sui_system_state_inner_v2::SystemParametersV2,
843 ) -> Self {
844 let mut message = Self::default();
845 message.epoch_duration_ms = Some(epoch_duration_ms);
846 message.stake_subsidy_start_epoch = Some(stake_subsidy_start_epoch);
847 message.min_validator_count = Some(min_validator_count);
848 message.max_validator_count = Some(max_validator_count);
849 message.min_validator_joining_stake = Some(min_validator_joining_stake);
850 message.validator_low_stake_threshold = Some(validator_low_stake_threshold);
851 message.validator_very_low_stake_threshold = Some(validator_very_low_stake_threshold);
852 message.validator_low_stake_grace_period = Some(validator_low_stake_grace_period);
853 message.extra_fields = Some(extra_fields.into());
854 message
855 }
856}
857
858impl From<crate::sui_system_state::sui_system_state_inner_v1::StorageFundV1> for StorageFund {
859 fn from(
860 crate::sui_system_state::sui_system_state_inner_v1::StorageFundV1 {
861 total_object_storage_rebates,
862 non_refundable_balance,
863 }: crate::sui_system_state::sui_system_state_inner_v1::StorageFundV1,
864 ) -> Self {
865 let mut message = Self::default();
866 message.total_object_storage_rebates = Some(total_object_storage_rebates.value());
867 message.non_refundable_balance = Some(non_refundable_balance.value());
868 message
869 }
870}
871
872impl From<crate::sui_system_state::sui_system_state_inner_v1::ValidatorSetV1> for ValidatorSet {
873 fn from(
874 crate::sui_system_state::sui_system_state_inner_v1::ValidatorSetV1 {
875 total_stake,
876 active_validators,
877 pending_active_validators,
878 pending_removals,
879 staking_pool_mappings,
880 inactive_validators,
881 validator_candidates,
882 at_risk_validators,
883 extra_fields,
884 }: crate::sui_system_state::sui_system_state_inner_v1::ValidatorSetV1,
885 ) -> Self {
886 let at_risk_validators = at_risk_validators
887 .contents
888 .into_iter()
889 .map(|entry| (entry.key.to_string(), entry.value))
890 .collect();
891
892 let mut message = Self::default();
893 message.total_stake = Some(total_stake);
894 message.active_validators = active_validators.into_iter().map(Into::into).collect();
895 message.pending_active_validators = Some(pending_active_validators.into());
896 message.pending_removals = pending_removals;
897 message.staking_pool_mappings = Some(staking_pool_mappings.into());
898 message.inactive_validators = Some(inactive_validators.into());
899 message.validator_candidates = Some(validator_candidates.into());
900 message.at_risk_validators = at_risk_validators;
901 message.extra_fields = Some(extra_fields.into());
902 message
903 }
904}
905
906impl From<crate::sui_system_state::sui_system_state_inner_v1::StakingPoolV1> for StakingPool {
907 fn from(
908 crate::sui_system_state::sui_system_state_inner_v1::StakingPoolV1 {
909 id,
910 activation_epoch,
911 deactivation_epoch,
912 sui_balance,
913 rewards_pool,
914 pool_token_balance,
915 exchange_rates,
916 pending_stake,
917 pending_total_sui_withdraw,
918 pending_pool_token_withdraw,
919 extra_fields,
920 }: crate::sui_system_state::sui_system_state_inner_v1::StakingPoolV1,
921 ) -> Self {
922 let mut message = Self::default();
923 message.id = Some(id.to_canonical_string(true));
924 message.activation_epoch = activation_epoch;
925 message.deactivation_epoch = deactivation_epoch;
926 message.sui_balance = Some(sui_balance);
927 message.rewards_pool = Some(rewards_pool.value());
928 message.pool_token_balance = Some(pool_token_balance);
929 message.exchange_rates = Some(exchange_rates.into());
930 message.pending_stake = Some(pending_stake);
931 message.pending_total_sui_withdraw = Some(pending_total_sui_withdraw);
932 message.pending_pool_token_withdraw = Some(pending_pool_token_withdraw);
933 message.extra_fields = Some(extra_fields.into());
934 message
935 }
936}
937
938impl From<crate::sui_system_state::sui_system_state_inner_v1::ValidatorV1> for Validator {
939 fn from(
940 crate::sui_system_state::sui_system_state_inner_v1::ValidatorV1 {
941 metadata:
942 crate::sui_system_state::sui_system_state_inner_v1::ValidatorMetadataV1 {
943 sui_address,
944 protocol_pubkey_bytes,
945 network_pubkey_bytes,
946 worker_pubkey_bytes,
947 proof_of_possession_bytes,
948 name,
949 description,
950 image_url,
951 project_url,
952 net_address,
953 p2p_address,
954 primary_address,
955 worker_address,
956 next_epoch_protocol_pubkey_bytes,
957 next_epoch_proof_of_possession,
958 next_epoch_network_pubkey_bytes,
959 next_epoch_worker_pubkey_bytes,
960 next_epoch_net_address,
961 next_epoch_p2p_address,
962 next_epoch_primary_address,
963 next_epoch_worker_address,
964 extra_fields: metadata_extra_fields,
965 },
966 voting_power,
967 operation_cap_id,
968 gas_price,
969 staking_pool,
970 commission_rate,
971 next_epoch_stake,
972 next_epoch_gas_price,
973 next_epoch_commission_rate,
974 extra_fields,
975 ..
976 }: crate::sui_system_state::sui_system_state_inner_v1::ValidatorV1,
977 ) -> Self {
978 let mut message = Self::default();
979 message.name = Some(name);
980 message.address = Some(sui_address.to_string());
981 message.description = Some(description);
982 message.image_url = Some(image_url);
983 message.project_url = Some(project_url);
984 message.protocol_public_key = Some(protocol_pubkey_bytes.into());
985 message.proof_of_possession = Some(proof_of_possession_bytes.into());
986 message.network_public_key = Some(network_pubkey_bytes.into());
987 message.worker_public_key = Some(worker_pubkey_bytes.into());
988 message.network_address = Some(net_address);
989 message.p2p_address = Some(p2p_address);
990 message.primary_address = Some(primary_address);
991 message.worker_address = Some(worker_address);
992 message.next_epoch_protocol_public_key = next_epoch_protocol_pubkey_bytes.map(Into::into);
993 message.next_epoch_proof_of_possession = next_epoch_proof_of_possession.map(Into::into);
994 message.next_epoch_network_public_key = next_epoch_network_pubkey_bytes.map(Into::into);
995 message.next_epoch_worker_public_key = next_epoch_worker_pubkey_bytes.map(Into::into);
996 message.next_epoch_network_address = next_epoch_net_address;
997 message.next_epoch_p2p_address = next_epoch_p2p_address;
998 message.next_epoch_primary_address = next_epoch_primary_address;
999 message.next_epoch_worker_address = next_epoch_worker_address;
1000 message.metadata_extra_fields = Some(metadata_extra_fields.into());
1001 message.voting_power = Some(voting_power);
1002 message.operation_cap_id = Some(operation_cap_id.bytes.to_canonical_string(true));
1003 message.gas_price = Some(gas_price);
1004 message.staking_pool = Some(staking_pool.into());
1005 message.commission_rate = Some(commission_rate);
1006 message.next_epoch_stake = Some(next_epoch_stake);
1007 message.next_epoch_gas_price = Some(next_epoch_gas_price);
1008 message.next_epoch_commission_rate = Some(next_epoch_commission_rate);
1009 message.extra_fields = Some(extra_fields.into());
1010 message
1011 }
1012}
1013
1014impl TryFrom<&SystemState>
1015 for crate::sui_system_state::sui_system_state_summary::SuiSystemStateSummary
1016{
1017 type Error = TryFromProtoError;
1018
1019 fn try_from(s: &SystemState) -> Result<Self, Self::Error> {
1020 Ok(Self {
1021 epoch: s.epoch(),
1022 protocol_version: s.protocol_version(),
1023 system_state_version: s.version(),
1024 storage_fund_total_object_storage_rebates: s
1025 .storage_fund()
1026 .total_object_storage_rebates(),
1027 storage_fund_non_refundable_balance: s.storage_fund().non_refundable_balance(),
1028 reference_gas_price: s.reference_gas_price(),
1029 safe_mode: s.safe_mode(),
1030 safe_mode_storage_rewards: s.safe_mode_storage_rewards(),
1031 safe_mode_computation_rewards: s.safe_mode_computation_rewards(),
1032 safe_mode_storage_rebates: s.safe_mode_storage_rebates(),
1033 safe_mode_non_refundable_storage_fee: s.safe_mode_non_refundable_storage_fee(),
1034 epoch_start_timestamp_ms: s.epoch_start_timestamp_ms(),
1035 epoch_duration_ms: s.parameters().epoch_duration_ms(),
1036 stake_subsidy_start_epoch: s.parameters().stake_subsidy_start_epoch(),
1037 max_validator_count: s.parameters().max_validator_count(),
1038 min_validator_joining_stake: s.parameters().min_validator_joining_stake(),
1039 validator_low_stake_threshold: s.parameters().validator_low_stake_threshold(),
1040 validator_very_low_stake_threshold: s.parameters().validator_very_low_stake_threshold(),
1041 validator_low_stake_grace_period: s.parameters().validator_low_stake_grace_period(),
1042 stake_subsidy_balance: s.stake_subsidy().balance(),
1043 stake_subsidy_distribution_counter: s.stake_subsidy().distribution_counter(),
1044 stake_subsidy_current_distribution_amount: s
1045 .stake_subsidy()
1046 .current_distribution_amount(),
1047 stake_subsidy_period_length: s.stake_subsidy().stake_subsidy_period_length(),
1048 stake_subsidy_decrease_rate: s.stake_subsidy().stake_subsidy_decrease_rate() as u16,
1049 total_stake: s.validators().total_stake(),
1050 active_validators: s
1051 .validators()
1052 .active_validators()
1053 .iter()
1054 .map(TryInto::try_into)
1055 .collect::<Result<_, _>>()?,
1056 pending_active_validators_id: s
1057 .validators()
1058 .pending_active_validators()
1059 .id()
1060 .parse()
1061 .map_err(|e| {
1062 TryFromProtoError::invalid("pending_active_validators_id", e)
1063 })?,
1064 pending_active_validators_size: s.validators().pending_active_validators().size(),
1065 pending_removals: s.validators().pending_removals().to_vec(),
1066 staking_pool_mappings_id: s
1067 .validators()
1068 .staking_pool_mappings()
1069 .id()
1070 .parse()
1071 .map_err(|e| TryFromProtoError::invalid("staking_pool_mappings_id", e))?,
1072 staking_pool_mappings_size: s.validators().staking_pool_mappings().size(),
1073 inactive_pools_id: s
1074 .validators()
1075 .inactive_validators()
1076 .id()
1077 .parse()
1078 .map_err(|e| TryFromProtoError::invalid("inactive_pools_id", e))?,
1079 inactive_pools_size: s.validators().inactive_validators().size(),
1080 validator_candidates_id: s
1081 .validators()
1082 .validator_candidates()
1083 .id()
1084 .parse()
1085 .map_err(|e| TryFromProtoError::invalid("validator_candidates", e))?,
1086 validator_candidates_size: s.validators().validator_candidates().size(),
1087 at_risk_validators: s
1088 .validators()
1089 .at_risk_validators()
1090 .iter()
1091 .map(|(address, epoch)| {
1092 address
1093 .parse()
1094 .map(|address| (address, *epoch))
1095 .map_err(|e| TryFromProtoError::invalid("at_risk_validators", e))
1096 })
1097 .collect::<Result<_, _>>()?,
1098 validator_report_records: s
1099 .validator_report_records()
1100 .iter()
1101 .map(|record| {
1102 let reported = record.reported().parse()?;
1103 let reporters = record
1104 .reporters()
1105 .iter()
1106 .map(|address| address.parse())
1107 .collect::<Result<Vec<_>, _>>()?;
1108 Ok((reported, reporters))
1109 })
1110 .collect::<Result<_, anyhow::Error>>()
1111 .map_err(|e| TryFromProtoError::invalid("validator_report_records", e))?,
1112 })
1113 }
1114}
1115
1116impl TryFrom<&Validator>
1117 for crate::sui_system_state::sui_system_state_summary::SuiValidatorSummary
1118{
1119 type Error = TryFromProtoError;
1120
1121 fn try_from(v: &Validator) -> Result<Self, Self::Error> {
1122 Ok(Self {
1123 sui_address: v
1124 .address()
1125 .parse()
1126 .map_err(|e| TryFromProtoError::invalid("address", e))?,
1127 protocol_pubkey_bytes: v.protocol_public_key().into(),
1128 network_pubkey_bytes: v.network_public_key().into(),
1129 worker_pubkey_bytes: v.worker_public_key().into(),
1130 proof_of_possession_bytes: v.proof_of_possession().into(),
1131 name: v.name().into(),
1132 description: v.description().into(),
1133 image_url: v.image_url().into(),
1134 project_url: v.project_url().into(),
1135 net_address: v.network_address().into(),
1136 p2p_address: v.p2p_address().into(),
1137 primary_address: v.primary_address().into(),
1138 worker_address: v.worker_address().into(),
1139 next_epoch_protocol_pubkey_bytes: v
1140 .next_epoch_protocol_public_key_opt()
1141 .map(Into::into),
1142 next_epoch_proof_of_possession: v.next_epoch_proof_of_possession_opt().map(Into::into),
1143 next_epoch_network_pubkey_bytes: v.next_epoch_network_public_key_opt().map(Into::into),
1144 next_epoch_worker_pubkey_bytes: v.next_epoch_worker_public_key_opt().map(Into::into),
1145 next_epoch_net_address: v.next_epoch_network_address_opt().map(Into::into),
1146 next_epoch_p2p_address: v.next_epoch_p2p_address_opt().map(Into::into),
1147 next_epoch_primary_address: v.next_epoch_primary_address_opt().map(Into::into),
1148 next_epoch_worker_address: v.next_epoch_worker_address_opt().map(Into::into),
1149 voting_power: v.voting_power(),
1150 operation_cap_id: v
1151 .operation_cap_id()
1152 .parse()
1153 .map_err(|e| TryFromProtoError::invalid("operation_cap_id", e))?,
1154 gas_price: v.gas_price(),
1155 commission_rate: v.commission_rate(),
1156 next_epoch_stake: v.next_epoch_stake(),
1157 next_epoch_gas_price: v.next_epoch_gas_price(),
1158 next_epoch_commission_rate: v.next_epoch_commission_rate(),
1159 staking_pool_id: v
1160 .staking_pool()
1161 .id()
1162 .parse()
1163 .map_err(|e| TryFromProtoError::invalid("staking_pool_id", e))?,
1164 staking_pool_activation_epoch: v.staking_pool().activation_epoch_opt(),
1165 staking_pool_deactivation_epoch: v.staking_pool().deactivation_epoch_opt(),
1166 staking_pool_sui_balance: v.staking_pool().sui_balance(),
1167 rewards_pool: v.staking_pool().rewards_pool(),
1168 pool_token_balance: v.staking_pool().pool_token_balance(),
1169 pending_stake: v.staking_pool().pending_stake(),
1170 pending_total_sui_withdraw: v.staking_pool().pending_total_sui_withdraw(),
1171 pending_pool_token_withdraw: v.staking_pool().pending_pool_token_withdraw(),
1172 exchange_rates_id: v
1173 .staking_pool()
1174 .exchange_rates()
1175 .id()
1176 .parse()
1177 .map_err(|e| TryFromProtoError::invalid("exchange_rates_id", e))?,
1178 exchange_rates_size: v.staking_pool().exchange_rates().size(),
1179 })
1180 }
1181}
1182
1183impl From<crate::execution_status::ExecutionStatus> for ExecutionStatus {
1188 fn from(value: crate::execution_status::ExecutionStatus) -> Self {
1189 let mut message = Self::default();
1190 match value {
1191 crate::execution_status::ExecutionStatus::Success => {
1192 message.success = Some(true);
1193 }
1194 crate::execution_status::ExecutionStatus::Failure(
1195 crate::execution_status::ExecutionFailure { error, command },
1196 ) => {
1197 let description = if let Some(command) = command {
1198 format!("{error:?} in command {command}")
1199 } else {
1200 format!("{error:?}")
1201 };
1202 let mut error_message = ExecutionError::from(error);
1203 error_message.command = command.map(|i| i as u64);
1204 error_message.description = Some(description);
1205
1206 message.success = Some(false);
1207 message.error = Some(error_message);
1208 }
1209 }
1210
1211 message
1212 }
1213}
1214
1215fn size_error(size: u64, max_size: u64) -> SizeError {
1220 let mut message = SizeError::default();
1221 message.size = Some(size);
1222 message.max_size = Some(max_size);
1223 message
1224}
1225
1226fn index_error(index: u32, secondary_idx: Option<u32>) -> IndexError {
1227 let mut message = IndexError::default();
1228 message.index = Some(index);
1229 message.subresult = secondary_idx;
1230 message
1231}
1232
1233impl From<crate::execution_status::ExecutionErrorKind> for ExecutionError {
1234 fn from(value: crate::execution_status::ExecutionErrorKind) -> Self {
1235 use crate::execution_status::ExecutionErrorKind as E;
1236 use execution_error::ErrorDetails;
1237 use execution_error::ExecutionErrorKind;
1238
1239 let mut message = Self::default();
1240
1241 let kind = match value {
1242 E::InsufficientGas => ExecutionErrorKind::InsufficientGas,
1243 E::InvalidGasObject => ExecutionErrorKind::InvalidGasObject,
1244 E::InvariantViolation => ExecutionErrorKind::InvariantViolation,
1245 E::FeatureNotYetSupported => ExecutionErrorKind::FeatureNotYetSupported,
1246 E::MoveObjectTooBig {
1247 object_size,
1248 max_object_size,
1249 } => {
1250 message.error_details = Some(ErrorDetails::SizeError(size_error(
1251 object_size,
1252 max_object_size,
1253 )));
1254 ExecutionErrorKind::ObjectTooBig
1255 }
1256 E::MovePackageTooBig {
1257 object_size,
1258 max_object_size,
1259 } => {
1260 message.error_details = Some(ErrorDetails::SizeError(size_error(
1261 object_size,
1262 max_object_size,
1263 )));
1264 ExecutionErrorKind::PackageTooBig
1265 }
1266 E::CircularObjectOwnership { object } => {
1267 message.error_details =
1268 Some(ErrorDetails::ObjectId(object.to_canonical_string(true)));
1269 ExecutionErrorKind::CircularObjectOwnership
1270 }
1271 E::InsufficientCoinBalance => ExecutionErrorKind::InsufficientCoinBalance,
1272 E::CoinBalanceOverflow => ExecutionErrorKind::CoinBalanceOverflow,
1273 E::PublishErrorNonZeroAddress => ExecutionErrorKind::PublishErrorNonZeroAddress,
1274 E::SuiMoveVerificationError => ExecutionErrorKind::SuiMoveVerificationError,
1275 E::MovePrimitiveRuntimeError(location) => {
1276 message.error_details = location.0.map(|l| {
1277 let mut abort = MoveAbort::default();
1278 abort.location = Some(l.into());
1279 ErrorDetails::Abort(abort)
1280 });
1281 ExecutionErrorKind::MovePrimitiveRuntimeError
1282 }
1283 E::MoveAbort(location, code) => {
1284 let mut abort = MoveAbort::default();
1285 abort.abort_code = Some(code);
1286 abort.location = Some(location.into());
1287 message.error_details = Some(ErrorDetails::Abort(abort));
1288 ExecutionErrorKind::MoveAbort
1289 }
1290 E::VMVerificationOrDeserializationError => {
1291 ExecutionErrorKind::VmVerificationOrDeserializationError
1292 }
1293 E::VMInvariantViolation => ExecutionErrorKind::VmInvariantViolation,
1294 E::FunctionNotFound => ExecutionErrorKind::FunctionNotFound,
1295 E::ArityMismatch => ExecutionErrorKind::ArityMismatch,
1296 E::TypeArityMismatch => ExecutionErrorKind::TypeArityMismatch,
1297 E::NonEntryFunctionInvoked => ExecutionErrorKind::NonEntryFunctionInvoked,
1298 E::CommandArgumentError { arg_idx, kind } => {
1299 let mut command_argument_error = CommandArgumentError::from(kind);
1300 command_argument_error.argument = Some(arg_idx.into());
1301 message.error_details =
1302 Some(ErrorDetails::CommandArgumentError(command_argument_error));
1303 ExecutionErrorKind::CommandArgumentError
1304 }
1305 E::TypeArgumentError { argument_idx, kind } => {
1306 let mut type_argument_error = TypeArgumentError::default();
1307 type_argument_error.type_argument = Some(argument_idx.into());
1308 type_argument_error.kind =
1309 Some(type_argument_error::TypeArgumentErrorKind::from(kind).into());
1310 message.error_details = Some(ErrorDetails::TypeArgumentError(type_argument_error));
1311 ExecutionErrorKind::TypeArgumentError
1312 }
1313 E::UnusedValueWithoutDrop {
1314 result_idx,
1315 secondary_idx,
1316 } => {
1317 message.error_details = Some(ErrorDetails::IndexError(index_error(
1318 result_idx.into(),
1319 Some(secondary_idx.into()),
1320 )));
1321 ExecutionErrorKind::UnusedValueWithoutDrop
1322 }
1323 E::InvalidPublicFunctionReturnType { idx } => {
1324 message.error_details =
1325 Some(ErrorDetails::IndexError(index_error(idx.into(), None)));
1326 ExecutionErrorKind::InvalidPublicFunctionReturnType
1327 }
1328 E::InvalidTransferObject => ExecutionErrorKind::InvalidTransferObject,
1329 E::EffectsTooLarge {
1330 current_size,
1331 max_size,
1332 } => {
1333 message.error_details =
1334 Some(ErrorDetails::SizeError(size_error(current_size, max_size)));
1335 ExecutionErrorKind::EffectsTooLarge
1336 }
1337 E::PublishUpgradeMissingDependency => {
1338 ExecutionErrorKind::PublishUpgradeMissingDependency
1339 }
1340 E::PublishUpgradeDependencyDowngrade => {
1341 ExecutionErrorKind::PublishUpgradeDependencyDowngrade
1342 }
1343 E::PackageUpgradeError { upgrade_error } => {
1344 message.error_details =
1345 Some(ErrorDetails::PackageUpgradeError(upgrade_error.into()));
1346 ExecutionErrorKind::PackageUpgradeError
1347 }
1348 E::WrittenObjectsTooLarge {
1349 current_size,
1350 max_size,
1351 } => {
1352 message.error_details =
1353 Some(ErrorDetails::SizeError(size_error(current_size, max_size)));
1354
1355 ExecutionErrorKind::WrittenObjectsTooLarge
1356 }
1357 E::CertificateDenied => ExecutionErrorKind::CertificateDenied,
1358 E::SuiMoveVerificationTimedout => ExecutionErrorKind::SuiMoveVerificationTimedout,
1359 E::SharedObjectOperationNotAllowed => {
1360 ExecutionErrorKind::ConsensusObjectOperationNotAllowed
1361 }
1362 E::InputObjectDeleted => ExecutionErrorKind::InputObjectDeleted,
1363 E::ExecutionCancelledDueToSharedObjectCongestion { congested_objects } => {
1364 message.error_details = Some(ErrorDetails::CongestedObjects({
1365 let mut message = CongestedObjects::default();
1366 message.objects = congested_objects
1367 .0
1368 .iter()
1369 .map(|o| o.to_canonical_string(true))
1370 .collect();
1371 message
1372 }));
1373
1374 ExecutionErrorKind::ExecutionCanceledDueToConsensusObjectCongestion
1375 }
1376 E::AddressDeniedForCoin { address, coin_type } => {
1377 message.error_details = Some(ErrorDetails::CoinDenyListError({
1378 let mut message = CoinDenyListError::default();
1379 message.address = Some(address.to_string());
1380 message.coin_type = Some(coin_type);
1381 message
1382 }));
1383 ExecutionErrorKind::AddressDeniedForCoin
1384 }
1385 E::CoinTypeGlobalPause { coin_type } => {
1386 message.error_details = Some(ErrorDetails::CoinDenyListError({
1387 let mut message = CoinDenyListError::default();
1388 message.coin_type = Some(coin_type);
1389 message
1390 }));
1391 ExecutionErrorKind::CoinTypeGlobalPause
1392 }
1393 E::ExecutionCancelledDueToRandomnessUnavailable => {
1394 ExecutionErrorKind::ExecutionCanceledDueToRandomnessUnavailable
1395 }
1396 E::MoveVectorElemTooBig {
1397 value_size,
1398 max_scaled_size,
1399 } => {
1400 message.error_details = Some(ErrorDetails::SizeError(size_error(
1401 value_size,
1402 max_scaled_size,
1403 )));
1404
1405 ExecutionErrorKind::MoveVectorElemTooBig
1406 }
1407 E::MoveRawValueTooBig {
1408 value_size,
1409 max_scaled_size,
1410 } => {
1411 message.error_details = Some(ErrorDetails::SizeError(size_error(
1412 value_size,
1413 max_scaled_size,
1414 )));
1415 ExecutionErrorKind::MoveRawValueTooBig
1416 }
1417 E::InvalidLinkage => ExecutionErrorKind::InvalidLinkage,
1418 E::InsufficientFundsForWithdraw => ExecutionErrorKind::InsufficientFundsForWithdraw,
1419 E::NonExclusiveWriteInputObjectModified { id } => {
1420 message.set_object_id(id.to_canonical_string(true));
1421 ExecutionErrorKind::NonExclusiveWriteInputObjectModified
1422 }
1423 };
1424
1425 message.set_kind(kind);
1426 message
1427 }
1428}
1429
1430impl From<crate::execution_status::CommandArgumentError> for CommandArgumentError {
1435 fn from(value: crate::execution_status::CommandArgumentError) -> Self {
1436 use crate::execution_status::CommandArgumentError as E;
1437 use command_argument_error::CommandArgumentErrorKind;
1438
1439 let mut message = Self::default();
1440
1441 let kind = match value {
1442 E::TypeMismatch => CommandArgumentErrorKind::TypeMismatch,
1443 E::InvalidBCSBytes => CommandArgumentErrorKind::InvalidBcsBytes,
1444 E::InvalidUsageOfPureArg => CommandArgumentErrorKind::InvalidUsageOfPureArgument,
1445 E::InvalidArgumentToPrivateEntryFunction => {
1446 CommandArgumentErrorKind::InvalidArgumentToPrivateEntryFunction
1447 }
1448 E::IndexOutOfBounds { idx } => {
1449 message.index_error = Some(index_error(idx.into(), None));
1450 CommandArgumentErrorKind::IndexOutOfBounds
1451 }
1452 E::SecondaryIndexOutOfBounds {
1453 result_idx,
1454 secondary_idx,
1455 } => {
1456 message.index_error =
1457 Some(index_error(result_idx.into(), Some(secondary_idx.into())));
1458 CommandArgumentErrorKind::SecondaryIndexOutOfBounds
1459 }
1460 E::InvalidResultArity { result_idx } => {
1461 message.index_error = Some(index_error(result_idx.into(), None));
1462 CommandArgumentErrorKind::InvalidResultArity
1463 }
1464 E::InvalidGasCoinUsage => CommandArgumentErrorKind::InvalidGasCoinUsage,
1465 E::InvalidValueUsage => CommandArgumentErrorKind::InvalidValueUsage,
1466 E::InvalidObjectByValue => CommandArgumentErrorKind::InvalidObjectByValue,
1467 E::InvalidObjectByMutRef => CommandArgumentErrorKind::InvalidObjectByMutRef,
1468 E::SharedObjectOperationNotAllowed => {
1469 CommandArgumentErrorKind::ConsensusObjectOperationNotAllowed
1470 }
1471 E::InvalidArgumentArity => CommandArgumentErrorKind::InvalidArgumentArity,
1472
1473 E::InvalidTransferObject => CommandArgumentErrorKind::InvalidTransferObject,
1474 E::InvalidMakeMoveVecNonObjectArgument => {
1475 CommandArgumentErrorKind::InvalidMakeMoveVecNonObjectArgument
1476 }
1477 E::ArgumentWithoutValue => CommandArgumentErrorKind::ArgumentWithoutValue,
1478 E::CannotMoveBorrowedValue => CommandArgumentErrorKind::CannotMoveBorrowedValue,
1479 E::CannotWriteToExtendedReference => {
1480 CommandArgumentErrorKind::CannotWriteToExtendedReference
1481 }
1482 E::InvalidReferenceArgument => CommandArgumentErrorKind::InvalidReferenceArgument,
1483 E::InvalidTxContext => CommandArgumentErrorKind::InvalidTxContext,
1484 };
1485
1486 message.set_kind(kind);
1487 message
1488 }
1489}
1490
1491impl From<crate::execution_status::TypeArgumentError>
1496 for type_argument_error::TypeArgumentErrorKind
1497{
1498 fn from(value: crate::execution_status::TypeArgumentError) -> Self {
1499 use crate::execution_status::TypeArgumentError::*;
1500
1501 match value {
1502 TypeNotFound => Self::TypeNotFound,
1503 ConstraintNotSatisfied => Self::ConstraintNotSatisfied,
1504 }
1505 }
1506}
1507
1508impl From<crate::execution_status::PackageUpgradeError> for PackageUpgradeError {
1513 fn from(value: crate::execution_status::PackageUpgradeError) -> Self {
1514 use crate::execution_status::PackageUpgradeError as E;
1515 use package_upgrade_error::PackageUpgradeErrorKind;
1516
1517 let mut message = Self::default();
1518
1519 let kind = match value {
1520 E::UnableToFetchPackage { package_id } => {
1521 message.package_id = Some(package_id.to_canonical_string(true));
1522 PackageUpgradeErrorKind::UnableToFetchPackage
1523 }
1524 E::NotAPackage { object_id } => {
1525 message.package_id = Some(object_id.to_canonical_string(true));
1526 PackageUpgradeErrorKind::NotAPackage
1527 }
1528 E::IncompatibleUpgrade => PackageUpgradeErrorKind::IncompatibleUpgrade,
1529 E::DigestDoesNotMatch { digest } => {
1530 message.digest = crate::digests::Digest::try_from(digest)
1531 .ok()
1532 .map(|d| d.to_string());
1533 PackageUpgradeErrorKind::DigestDoesNotMatch
1534 }
1535 E::UnknownUpgradePolicy { policy } => {
1536 message.policy = Some(policy.into());
1537 PackageUpgradeErrorKind::UnknownUpgradePolicy
1538 }
1539 E::PackageIDDoesNotMatch {
1540 package_id,
1541 ticket_id,
1542 } => {
1543 message.package_id = Some(package_id.to_canonical_string(true));
1544 message.ticket_id = Some(ticket_id.to_canonical_string(true));
1545 PackageUpgradeErrorKind::PackageIdDoesNotMatch
1546 }
1547 };
1548
1549 message.set_kind(kind);
1550 message
1551 }
1552}
1553
1554impl From<crate::execution_status::MoveLocation> for MoveLocation {
1559 fn from(value: crate::execution_status::MoveLocation) -> Self {
1560 let mut message = Self::default();
1561 message.package = Some(value.module.address().to_canonical_string(true));
1562 message.module = Some(value.module.name().to_string());
1563 message.function = Some(value.function.into());
1564 message.instruction = Some(value.instruction.into());
1565 message.function_name = value.function_name.map(|name| name.to_string());
1566 message
1567 }
1568}
1569
1570impl<const T: bool> From<crate::crypto::AuthorityQuorumSignInfo<T>>
1575 for ValidatorAggregatedSignature
1576{
1577 fn from(value: crate::crypto::AuthorityQuorumSignInfo<T>) -> Self {
1578 let mut bitmap = Vec::new();
1579 value.signers_map.serialize_into(&mut bitmap).unwrap();
1580
1581 Self::default()
1582 .with_epoch(value.epoch)
1583 .with_signature(value.signature.as_ref().to_vec())
1584 .with_bitmap(bitmap)
1585 }
1586}
1587
1588impl<const T: bool> TryFrom<&ValidatorAggregatedSignature>
1589 for crate::crypto::AuthorityQuorumSignInfo<T>
1590{
1591 type Error = TryFromProtoError;
1592
1593 fn try_from(value: &ValidatorAggregatedSignature) -> Result<Self, Self::Error> {
1594 Ok(Self {
1595 epoch: value.epoch(),
1596 signature: crate::crypto::AggregateAuthoritySignature::from_bytes(value.signature())
1597 .map_err(|e| TryFromProtoError::invalid("signature", e))?,
1598 signers_map: crate::sui_serde::deserialize_sui_bitmap(value.bitmap())
1599 .map_err(|e| TryFromProtoError::invalid("bitmap", e))?,
1600 })
1601 }
1602}
1603
1604impl From<crate::committee::Committee> for ValidatorCommittee {
1609 fn from(value: crate::committee::Committee) -> Self {
1610 let mut message = Self::default();
1611 message.epoch = Some(value.epoch);
1612 message.members = value
1613 .voting_rights
1614 .into_iter()
1615 .map(|(name, weight)| {
1616 let mut member = ValidatorCommitteeMember::default();
1617 member.public_key = Some(name.0.to_vec().into());
1618 member.weight = Some(weight);
1619 member
1620 })
1621 .collect();
1622 message
1623 }
1624}
1625
1626impl TryFrom<&ValidatorCommittee> for crate::committee::Committee {
1627 type Error = TryFromProtoError;
1628
1629 fn try_from(s: &ValidatorCommittee) -> Result<Self, Self::Error> {
1630 let members = s
1631 .members()
1632 .iter()
1633 .map(|member| {
1634 let public_key =
1635 crate::crypto::AuthorityPublicKeyBytes::from_bytes(member.public_key())
1636 .map_err(|e| TryFromProtoError::invalid("public_key", e))?;
1637 Ok((public_key, member.weight()))
1638 })
1639 .collect::<Result<_, _>>()?;
1640 Ok(Self::new(s.epoch(), members))
1641 }
1642}
1643
1644impl From<&crate::zk_login_authenticator::ZkLoginAuthenticator> for ZkLoginAuthenticator {
1649 fn from(value: &crate::zk_login_authenticator::ZkLoginAuthenticator) -> Self {
1650 let mut inputs = ZkLoginInputs::default();
1652 inputs.address_seed = Some(value.inputs.get_address_seed().to_string());
1653 let mut message = Self::default();
1654 message.inputs = Some(inputs);
1655 message.max_epoch = Some(value.get_max_epoch());
1656 message.signature = Some(value.user_signature.clone().into());
1657
1658 sui_sdk_types::ZkLoginAuthenticator::try_from(value.clone())
1659 .map(Into::into)
1660 .ok()
1661 .unwrap_or(message)
1662 }
1663}
1664
1665impl From<&crate::crypto::ZkLoginPublicIdentifier> for ZkLoginPublicIdentifier {
1670 fn from(value: &crate::crypto::ZkLoginPublicIdentifier) -> Self {
1671 sui_sdk_types::ZkLoginPublicIdentifier::try_from(value.to_owned())
1673 .map(|id| (&id).into())
1674 .ok()
1675 .unwrap_or_default()
1676 }
1677}
1678
1679impl From<crate::crypto::SignatureScheme> for SignatureScheme {
1684 fn from(value: crate::crypto::SignatureScheme) -> Self {
1685 use crate::crypto::SignatureScheme as S;
1686
1687 match value {
1688 S::ED25519 => Self::Ed25519,
1689 S::Secp256k1 => Self::Secp256k1,
1690 S::Secp256r1 => Self::Secp256r1,
1691 S::BLS12381 => Self::Bls12381,
1692 S::MultiSig => Self::Multisig,
1693 S::ZkLoginAuthenticator => Self::Zklogin,
1694 S::PasskeyAuthenticator => Self::Passkey,
1695 S::MLDSA65 => Self::Mldsa65,
1696 }
1697 }
1698}
1699
1700impl From<crate::crypto::Signature> for SimpleSignature {
1705 fn from(value: crate::crypto::Signature) -> Self {
1706 Self::from(&value)
1707 }
1708}
1709
1710impl From<&crate::crypto::Signature> for SimpleSignature {
1711 fn from(value: &crate::crypto::Signature) -> Self {
1712 let signature = value.signature_bytes();
1713 let public_key = value.public_key_bytes();
1714
1715 let mut message = Self::default();
1716 message.set_scheme(value.scheme().into());
1717 message.signature = Some(signature.to_vec().into());
1718 message.public_key = Some(public_key.to_vec().into());
1719 message
1720 }
1721}
1722
1723impl From<&crate::passkey_authenticator::PasskeyAuthenticator> for PasskeyAuthenticator {
1728 fn from(value: &crate::passkey_authenticator::PasskeyAuthenticator) -> Self {
1729 let mut message = Self::default();
1730 message.authenticator_data = Some(value.authenticator_data().to_vec().into());
1731 message.client_data_json = Some(value.client_data_json().to_owned());
1732 message.signature = Some(value.signature().into());
1733 message
1734 }
1735}
1736
1737impl From<&crate::crypto::PublicKey> for MultisigMemberPublicKey {
1742 fn from(value: &crate::crypto::PublicKey) -> Self {
1743 let mut message = Self::default();
1744
1745 match value {
1746 crate::crypto::PublicKey::Ed25519(_)
1747 | crate::crypto::PublicKey::Secp256k1(_)
1748 | crate::crypto::PublicKey::Secp256r1(_)
1749 | crate::crypto::PublicKey::Passkey(_)
1750 | crate::crypto::PublicKey::MLDSA65(_) => {
1751 message.public_key = Some(value.as_ref().to_vec().into());
1752 }
1753 crate::crypto::PublicKey::ZkLogin(z) => {
1754 message.zklogin = Some(z.into());
1755 }
1756 }
1757
1758 message.set_scheme(value.scheme().into());
1759 message
1760 }
1761}
1762
1763impl From<&crate::multisig::MultiSigPublicKey> for MultisigCommittee {
1768 fn from(value: &crate::multisig::MultiSigPublicKey) -> Self {
1769 let mut message = Self::default();
1770 message.members = value
1771 .pubkeys()
1772 .iter()
1773 .map(|(pk, weight)| {
1774 let mut member = MultisigMember::default();
1775 member.public_key = Some(pk.into());
1776 member.weight = Some((*weight).into());
1777 member
1778 })
1779 .collect();
1780 message.threshold = Some((*value.threshold()).into());
1781 message
1782 }
1783}
1784
1785impl From<&crate::multisig_legacy::MultiSigPublicKeyLegacy> for MultisigCommittee {
1786 fn from(value: &crate::multisig_legacy::MultiSigPublicKeyLegacy) -> Self {
1787 let mut message = Self::default();
1788 message.members = value
1789 .pubkeys()
1790 .iter()
1791 .map(|(pk, weight)| {
1792 let mut member = MultisigMember::default();
1793 member.public_key = Some(pk.into());
1794 member.weight = Some((*weight).into());
1795 member
1796 })
1797 .collect();
1798 message.threshold = Some((*value.threshold()).into());
1799 message
1800 }
1801}
1802
1803impl From<&crate::crypto::CompressedSignature> for MultisigMemberSignature {
1808 fn from(value: &crate::crypto::CompressedSignature) -> Self {
1809 let mut message = Self::default();
1810
1811 let scheme = match value {
1812 crate::crypto::CompressedSignature::Ed25519(b) => {
1813 message.signature = Some(b.0.to_vec().into());
1814 Some(SignatureScheme::Ed25519)
1815 }
1816 crate::crypto::CompressedSignature::Secp256k1(b) => {
1817 message.signature = Some(b.0.to_vec().into());
1818 Some(SignatureScheme::Secp256k1)
1819 }
1820 crate::crypto::CompressedSignature::Secp256r1(b) => {
1821 message.signature = Some(b.0.to_vec().into());
1822 Some(SignatureScheme::Secp256r1)
1823 }
1824 crate::crypto::CompressedSignature::ZkLogin(_z) => {
1825 Some(SignatureScheme::Zklogin)
1827 }
1828 crate::crypto::CompressedSignature::Passkey(_p) => {
1829 Some(SignatureScheme::Passkey)
1831 }
1832 crate::crypto::CompressedSignature::MLDSA65(b) => {
1833 message.signature = Some(b.0.to_vec().into());
1834 Some(SignatureScheme::Mldsa65)
1835 }
1836 };
1837
1838 if let Some(scheme) = scheme {
1839 message.set_scheme(scheme);
1840 }
1841 message
1842 }
1843}
1844
1845impl From<&crate::multisig_legacy::MultiSigLegacy> for MultisigAggregatedSignature {
1850 fn from(value: &crate::multisig_legacy::MultiSigLegacy) -> Self {
1851 let mut legacy_bitmap = Vec::new();
1852 value
1853 .get_bitmap()
1854 .serialize_into(&mut legacy_bitmap)
1855 .unwrap();
1856
1857 Self::default()
1858 .with_signatures(value.get_sigs().iter().map(Into::into).collect())
1859 .with_legacy_bitmap(legacy_bitmap)
1860 .with_committee(value.get_pk())
1861 }
1862}
1863
1864impl From<&crate::multisig::MultiSig> for MultisigAggregatedSignature {
1865 fn from(value: &crate::multisig::MultiSig) -> Self {
1866 let mut message = Self::default();
1867 message.signatures = value.get_sigs().iter().map(Into::into).collect();
1868 message.bitmap = Some(value.get_bitmap().into());
1869 message.committee = Some(value.get_pk().into());
1870 message
1871 }
1872}
1873
1874impl From<&crate::signature::GenericSignature> for UserSignature {
1879 fn from(value: &crate::signature::GenericSignature) -> Self {
1880 Self::merge_from(value, &FieldMaskTree::new_wildcard())
1881 }
1882}
1883
1884impl Merge<&crate::signature::GenericSignature> for UserSignature {
1885 fn merge(&mut self, source: &crate::signature::GenericSignature, mask: &FieldMaskTree) {
1886 use user_signature::Signature;
1887
1888 if mask.contains(Self::BCS_FIELD) {
1889 let mut bcs = Bcs::from(source.as_ref().to_vec());
1890 bcs.name = Some("UserSignatureBytes".to_owned());
1891 self.bcs = Some(bcs);
1892 }
1893
1894 let scheme = match source {
1895 crate::signature::GenericSignature::MultiSig(multi_sig) => {
1896 if mask.contains(Self::MULTISIG_FIELD) {
1897 self.signature = Some(Signature::Multisig(multi_sig.into()));
1898 }
1899 Some(SignatureScheme::Multisig)
1900 }
1901 crate::signature::GenericSignature::MultiSigLegacy(multi_sig_legacy) => {
1902 if mask.contains(Self::MULTISIG_FIELD) {
1903 self.signature = Some(Signature::Multisig(multi_sig_legacy.into()));
1904 }
1905 Some(SignatureScheme::Multisig)
1906 }
1907 crate::signature::GenericSignature::Signature(signature) => {
1908 let scheme = Some(SignatureScheme::from(signature.scheme()));
1909 if mask.contains(Self::SIMPLE_FIELD) {
1910 self.signature = Some(Signature::Simple(signature.into()));
1911 }
1912 scheme
1913 }
1914 crate::signature::GenericSignature::ZkLoginAuthenticator(z) => {
1915 if mask.contains(Self::ZKLOGIN_FIELD) {
1916 self.signature = Some(Signature::Zklogin(z.into()));
1917 }
1918 Some(SignatureScheme::Zklogin)
1919 }
1920 crate::signature::GenericSignature::PasskeyAuthenticator(p) => {
1921 if mask.contains(Self::PASSKEY_FIELD) {
1922 self.signature = Some(Signature::Passkey(p.into()));
1923 }
1924 Some(SignatureScheme::Passkey)
1925 }
1926 };
1927
1928 if mask.contains(Self::SCHEME_FIELD)
1929 && let Some(scheme) = scheme
1930 {
1931 self.set_scheme(scheme);
1932 }
1933 }
1934}
1935
1936impl From<crate::balance_change::BalanceChange> for BalanceChange {
1941 fn from(value: crate::balance_change::BalanceChange) -> Self {
1942 let mut message = Self::default();
1943 message.address = Some(value.address.to_string());
1944 message.coin_type = Some(value.coin_type.to_canonical_string(true));
1945 message.amount = Some(value.amount.to_string());
1946 message
1947 }
1948}
1949
1950impl TryFrom<&BalanceChange> for crate::balance_change::BalanceChange {
1951 type Error = TryFromProtoError;
1952
1953 fn try_from(value: &BalanceChange) -> Result<Self, Self::Error> {
1954 Ok(Self {
1955 address: value
1956 .address()
1957 .parse()
1958 .map_err(|e| TryFromProtoError::invalid(BalanceChange::ADDRESS_FIELD, e))?,
1959 coin_type: value
1960 .coin_type()
1961 .parse()
1962 .map_err(|e| TryFromProtoError::invalid(BalanceChange::COIN_TYPE_FIELD, e))?,
1963 amount: value
1964 .amount()
1965 .parse()
1966 .map_err(|e| TryFromProtoError::invalid(BalanceChange::AMOUNT_FIELD, e))?,
1967 })
1968 }
1969}
1970
1971pub const PACKAGE_TYPE: &str = "package";
1976
1977impl From<crate::object::Object> for Object {
1978 fn from(value: crate::object::Object) -> Self {
1979 Self::merge_from(&value, &FieldMaskTree::new_wildcard())
1980 }
1981}
1982
1983impl Merge<&crate::object::Object> for Object {
1984 fn merge(&mut self, source: &crate::object::Object, mask: &FieldMaskTree) {
1985 if mask.contains(Self::BCS_FIELD.name) {
1986 let mut bcs = Bcs::serialize(&source).unwrap();
1987 bcs.name = Some("Object".to_owned());
1988 self.bcs = Some(bcs);
1989 }
1990
1991 if mask.contains(Self::DIGEST_FIELD.name) {
1992 self.digest = Some(source.digest().to_string());
1993 }
1994
1995 if mask.contains(Self::OBJECT_ID_FIELD.name) {
1996 self.object_id = Some(source.id().to_canonical_string(true));
1997 }
1998
1999 if mask.contains(Self::VERSION_FIELD.name) {
2000 self.version = Some(source.version().value());
2001 }
2002
2003 if mask.contains(Self::OWNER_FIELD.name) {
2004 self.owner = Some(source.owner().to_owned().into());
2005 }
2006
2007 if mask.contains(Self::PREVIOUS_TRANSACTION_FIELD.name) {
2008 self.previous_transaction = Some(source.previous_transaction.to_string());
2009 }
2010
2011 if mask.contains(Self::STORAGE_REBATE_FIELD.name) {
2012 self.storage_rebate = Some(source.storage_rebate);
2013 }
2014
2015 if mask.contains(Self::BALANCE_FIELD) {
2016 self.balance = source.as_coin_maybe().map(|coin| coin.balance.value());
2017 }
2018
2019 self.merge(&source.data, mask);
2020 }
2021}
2022
2023impl Merge<&crate::object::MoveObject> for Object {
2024 fn merge(&mut self, source: &crate::object::MoveObject, mask: &FieldMaskTree) {
2025 self.object_id = Some(source.id().to_canonical_string(true));
2026 self.version = Some(source.version().value());
2027
2028 if mask.contains(Self::OBJECT_TYPE_FIELD.name) {
2029 self.object_type = Some(source.type_().to_canonical_string(true));
2030 }
2031
2032 if mask.contains(Self::HAS_PUBLIC_TRANSFER_FIELD.name) {
2033 self.has_public_transfer = Some(source.has_public_transfer());
2034 }
2035
2036 if mask.contains(Self::CONTENTS_FIELD.name) {
2037 let mut bcs = Bcs::from(source.contents().to_vec());
2038 bcs.name = Some(source.type_().to_canonical_string(true));
2039 self.contents = Some(bcs);
2040 }
2041 }
2042}
2043
2044impl Merge<&crate::move_package::MovePackage> for Object {
2045 fn merge(&mut self, source: &crate::move_package::MovePackage, mask: &FieldMaskTree) {
2046 self.object_id = Some(source.id().to_canonical_string(true));
2047 self.version = Some(source.version().value());
2048
2049 if mask.contains(Self::OBJECT_TYPE_FIELD.name) {
2050 self.object_type = Some(PACKAGE_TYPE.to_owned());
2051 }
2052
2053 if mask.contains(Self::PACKAGE_FIELD.name) {
2054 let mut package = Package::default();
2055 package.modules = source
2056 .serialized_module_map()
2057 .iter()
2058 .map(|(name, contents)| {
2059 let mut module = Module::default();
2060 module.name = Some(name.to_string());
2061 module.contents = Some(contents.clone().into());
2062 module
2063 })
2064 .collect();
2065 package.type_origins = source
2066 .type_origin_table()
2067 .clone()
2068 .into_iter()
2069 .map(Into::into)
2070 .collect();
2071 package.linkage = source
2072 .linkage_table()
2073 .iter()
2074 .map(
2075 |(
2076 original_id,
2077 crate::move_package::UpgradeInfo {
2078 upgraded_id,
2079 upgraded_version,
2080 },
2081 )| {
2082 let mut linkage = Linkage::default();
2083 linkage.original_id = Some(original_id.to_canonical_string(true));
2084 linkage.upgraded_id = Some(upgraded_id.to_canonical_string(true));
2085 linkage.upgraded_version = Some(upgraded_version.value());
2086 linkage
2087 },
2088 )
2089 .collect();
2090
2091 self.package = Some(package);
2092 }
2093 }
2094}
2095
2096impl Merge<&crate::object::Data> for Object {
2097 fn merge(&mut self, source: &crate::object::Data, mask: &FieldMaskTree) {
2098 match source {
2099 crate::object::Data::Move(object) => self.merge(object, mask),
2100 crate::object::Data::Package(package) => self.merge(package, mask),
2101 }
2102 }
2103}
2104
2105impl From<crate::move_package::TypeOrigin> for TypeOrigin {
2110 fn from(value: crate::move_package::TypeOrigin) -> Self {
2111 let mut message = Self::default();
2112 message.module_name = Some(value.module_name.to_string());
2113 message.datatype_name = Some(value.datatype_name.to_string());
2114 message.package_id = Some(value.package.to_canonical_string(true));
2115 message
2116 }
2117}
2118
2119impl From<crate::transaction::GenesisObject> for Object {
2124 fn from(value: crate::transaction::GenesisObject) -> Self {
2125 let crate::transaction::GenesisObject::RawObject { data, owner } = value;
2126 let mut message = Self::default();
2127 message.owner = Some(owner.into());
2128
2129 message.merge(&data, &FieldMaskTree::new_wildcard());
2130
2131 message
2132 }
2133}
2134
2135pub trait ObjectRefExt {
2140 fn to_proto(self) -> ObjectReference;
2141}
2142
2143pub trait ObjectReferenceExt {
2144 fn try_to_object_ref(&self) -> Result<crate::base_types::ObjectRef, anyhow::Error>;
2145}
2146
2147impl ObjectRefExt for crate::base_types::ObjectRef {
2148 fn to_proto(self) -> ObjectReference {
2149 let (object_id, version, digest) = self;
2150 let mut message = ObjectReference::default();
2151 message.object_id = Some(object_id.to_canonical_string(true));
2152 message.version = Some(version.value());
2153 message.digest = Some(digest.to_string());
2154 message
2155 }
2156}
2157
2158impl ObjectReferenceExt for ObjectReference {
2159 fn try_to_object_ref(&self) -> Result<crate::base_types::ObjectRef, anyhow::Error> {
2160 use anyhow::Context;
2161
2162 let object_id = self
2163 .object_id_opt()
2164 .ok_or_else(|| anyhow::anyhow!("missing object_id"))?;
2165 let object_id = crate::base_types::ObjectID::from_hex_literal(object_id)
2166 .with_context(|| format!("Failed to parse object_id: {}", object_id))?;
2167
2168 let version = self
2169 .version_opt()
2170 .ok_or_else(|| anyhow::anyhow!("missing version"))?;
2171 let version = crate::base_types::SequenceNumber::from(version);
2172
2173 let digest = self
2174 .digest_opt()
2175 .ok_or_else(|| anyhow::anyhow!("missing digest"))?;
2176 let digest = digest
2177 .parse::<crate::digests::ObjectDigest>()
2178 .with_context(|| format!("Failed to parse digest: {}", digest))?;
2179
2180 Ok((object_id, version, digest))
2181 }
2182}
2183
2184impl From<&crate::storage::ObjectKey> for ObjectReference {
2185 fn from(value: &crate::storage::ObjectKey) -> Self {
2186 Self::default()
2187 .with_object_id(value.0.to_canonical_string(true))
2188 .with_version(value.1.value())
2189 }
2190}
2191
2192impl From<crate::object::Owner> for Owner {
2197 fn from(value: crate::object::Owner) -> Self {
2198 use crate::object::Owner as O;
2199 use owner::OwnerKind;
2200
2201 let mut message = Self::default();
2202
2203 let kind = match value {
2204 O::AddressOwner(address) => {
2205 message.address = Some(address.to_string());
2206 OwnerKind::Address
2207 }
2208 O::ObjectOwner(address) => {
2209 message.address = Some(address.to_string());
2210 OwnerKind::Object
2211 }
2212 O::Shared {
2213 initial_shared_version,
2214 } => {
2215 message.version = Some(initial_shared_version.value());
2216 OwnerKind::Shared
2217 }
2218 O::Immutable => OwnerKind::Immutable,
2219 O::ConsensusAddressOwner {
2220 start_version,
2221 owner,
2222 } => {
2223 message.version = Some(start_version.value());
2224 message.address = Some(owner.to_string());
2225 OwnerKind::ConsensusAddress
2226 }
2227 O::Party { .. } => todo!("Party WIP"),
2229 };
2230
2231 message.set_kind(kind);
2232 message
2233 }
2234}
2235
2236impl From<crate::transaction::TransactionData> for Transaction {
2241 fn from(value: crate::transaction::TransactionData) -> Self {
2242 Self::merge_from(&value, &FieldMaskTree::new_wildcard())
2243 }
2244}
2245
2246impl Merge<&crate::transaction::TransactionData> for Transaction {
2247 fn merge(&mut self, source: &crate::transaction::TransactionData, mask: &FieldMaskTree) {
2248 merge_transaction_data(self, source, None, mask);
2249 }
2250}
2251
2252fn merge_transaction_data(
2253 message: &mut Transaction,
2254 source: &crate::transaction::TransactionData,
2255 precomputed_digest_string: Option<String>,
2256 mask: &FieldMaskTree,
2257) {
2258 if mask.contains(Transaction::BCS_FIELD.name) {
2259 let mut bcs = Bcs::serialize(&source).unwrap();
2260 bcs.name = Some("TransactionData".to_owned());
2261 message.bcs = Some(bcs);
2262 }
2263
2264 if mask.contains(Transaction::DIGEST_FIELD.name) {
2265 message.digest =
2266 Some(precomputed_digest_string.unwrap_or_else(|| source.digest().base58_encode()));
2267 }
2268
2269 if mask.contains(Transaction::VERSION_FIELD.name) {
2270 message.version = Some(1);
2271 }
2272
2273 let crate::transaction::TransactionData::V1(source) = source;
2274
2275 if mask.contains(Transaction::KIND_FIELD.name) {
2276 message.kind = Some(source.kind.clone().into());
2277 }
2278
2279 if mask.contains(Transaction::SENDER_FIELD.name) {
2280 message.sender = Some(source.sender.to_string());
2281 }
2282
2283 if mask.contains(Transaction::GAS_PAYMENT_FIELD.name) {
2284 message.gas_payment = Some((&source.gas_data).into());
2285 }
2286
2287 if mask.contains(Transaction::EXPIRATION_FIELD.name) {
2288 message.expiration = Some(source.expiration.clone().into());
2289 }
2290}
2291
2292impl From<&crate::transaction::GasData> for GasPayment {
2297 fn from(value: &crate::transaction::GasData) -> Self {
2298 let mut message = Self::default();
2299 message.objects = value
2300 .payment
2301 .iter()
2302 .map(|obj_ref| obj_ref.to_proto())
2303 .collect();
2304 message.owner = Some(value.owner.to_string());
2305 message.price = Some(value.price);
2306 message.budget = Some(value.budget);
2307 message
2308 }
2309}
2310
2311impl From<crate::transaction::TransactionExpiration> for TransactionExpiration {
2316 fn from(value: crate::transaction::TransactionExpiration) -> Self {
2317 use crate::transaction::TransactionExpiration as E;
2318 use transaction_expiration::TransactionExpirationKind;
2319
2320 let mut message = Self::default();
2321
2322 let kind = match value {
2323 E::None => TransactionExpirationKind::None,
2324 E::Epoch(epoch) => {
2325 message.epoch = Some(epoch);
2326 TransactionExpirationKind::Epoch
2327 }
2328 E::ValidDuring {
2329 min_epoch,
2330 max_epoch,
2331 min_timestamp,
2332 max_timestamp,
2333 chain,
2334 nonce,
2335 } => {
2336 message.epoch = max_epoch;
2337 message.min_epoch = min_epoch;
2338 message.min_timestamp = min_timestamp.map(ms_to_timestamp);
2339 message.max_timestamp = max_timestamp.map(ms_to_timestamp);
2340 message.set_chain(sui_sdk_types::Digest::new(*chain.as_bytes()));
2341 message.set_nonce(nonce);
2342
2343 TransactionExpirationKind::ValidDuring
2344 }
2345 E::Validity {
2346 min_epoch,
2347 max_epoch,
2348 min_timestamp,
2349 max_timestamp,
2350 chain,
2351 nonce,
2352 allowed_proposers,
2353 } => {
2354 message.epoch = max_epoch;
2355 message.min_epoch = min_epoch;
2356 message.min_timestamp = min_timestamp.map(ms_to_timestamp);
2357 message.max_timestamp = max_timestamp.map(ms_to_timestamp);
2358 message.set_chain(sui_sdk_types::Digest::new(*chain.as_bytes()));
2359 message.set_nonce(nonce);
2360 if let Some(allowed) = allowed_proposers {
2361 let mut proposers = AllowedProposers::default();
2362 proposers.set_epoch(allowed.epoch);
2363 proposers.proposers = allowed.proposers.into();
2364 message.set_allowed_proposers(proposers);
2365 }
2366
2367 TransactionExpirationKind::Validity
2368 }
2369 };
2370
2371 message.set_kind(kind);
2372 message
2373 }
2374}
2375
2376impl TryFrom<&TransactionExpiration> for crate::transaction::TransactionExpiration {
2377 type Error = &'static str;
2378
2379 fn try_from(value: &TransactionExpiration) -> Result<Self, Self::Error> {
2380 use transaction_expiration::TransactionExpirationKind;
2381
2382 Ok(match value.kind() {
2383 TransactionExpirationKind::None => Self::None,
2384 TransactionExpirationKind::Epoch => Self::Epoch(value.epoch()),
2385 kind @ (TransactionExpirationKind::ValidDuring
2386 | TransactionExpirationKind::Validity) => {
2387 let chain_str = value
2388 .chain
2389 .as_deref()
2390 .ok_or("ValidDuring expiration is missing chain")?;
2391 let chain_digest: sui_sdk_types::Digest = chain_str
2392 .parse()
2393 .map_err(|_| "ValidDuring expiration has invalid chain digest")?;
2394 let chain = crate::digests::ChainIdentifier::from(
2395 crate::digests::CheckpointDigest::new(chain_digest.into_inner()),
2396 );
2397 let nonce = value
2398 .nonce
2399 .ok_or("ValidDuring expiration is missing nonce")?;
2400 let min_timestamp = value
2401 .min_timestamp
2402 .as_ref()
2403 .map(timestamp_to_ms)
2404 .transpose()?;
2405 let max_timestamp = value
2406 .max_timestamp
2407 .as_ref()
2408 .map(timestamp_to_ms)
2409 .transpose()?;
2410 let min_epoch = value.min_epoch;
2411 let max_epoch = value.epoch;
2412
2413 if kind == TransactionExpirationKind::ValidDuring {
2414 Self::ValidDuring {
2415 min_epoch,
2416 max_epoch,
2417 min_timestamp,
2418 max_timestamp,
2419 chain,
2420 nonce,
2421 }
2422 } else {
2423 let allowed_proposers = value
2424 .allowed_proposers
2425 .as_ref()
2426 .map(|allowed| -> Result<_, Self::Error> {
2427 Ok(crate::transaction::AllowedProposers {
2428 epoch: allowed.epoch(),
2429 proposers: NonEmpty::from_vec(allowed.proposers.clone())
2430 .ok_or("allowed_proposers must not be empty")?,
2431 })
2432 })
2433 .transpose()?;
2434 Self::Validity {
2435 min_epoch,
2436 max_epoch,
2437 min_timestamp,
2438 max_timestamp,
2439 chain,
2440 nonce,
2441 allowed_proposers,
2442 }
2443 }
2444 }
2445 TransactionExpirationKind::Unknown | _ => {
2446 return Err("unknown TransactionExpirationKind");
2447 }
2448 })
2449 }
2450}
2451
2452impl From<crate::transaction::TransactionKind> for TransactionKind {
2457 fn from(value: crate::transaction::TransactionKind) -> Self {
2458 use crate::transaction::TransactionKind as K;
2459 use transaction_kind::Kind;
2460
2461 let message = Self::default();
2462
2463 match value {
2464 K::ProgrammableTransaction(ptb) => message
2465 .with_programmable_transaction(ptb)
2466 .with_kind(Kind::ProgrammableTransaction),
2467 K::ChangeEpoch(change_epoch) => message
2468 .with_change_epoch(change_epoch)
2469 .with_kind(Kind::ChangeEpoch),
2470 K::Genesis(genesis) => message.with_genesis(genesis).with_kind(Kind::Genesis),
2471 K::ConsensusCommitPrologue(prologue) => message
2472 .with_consensus_commit_prologue(prologue)
2473 .with_kind(Kind::ConsensusCommitPrologueV1),
2474 K::AuthenticatorStateUpdate(update) => message
2475 .with_authenticator_state_update(update)
2476 .with_kind(Kind::AuthenticatorStateUpdate),
2477 K::EndOfEpochTransaction(transactions) => message
2478 .with_end_of_epoch({
2479 EndOfEpochTransaction::default()
2480 .with_transactions(transactions.into_iter().map(Into::into).collect())
2481 })
2482 .with_kind(Kind::EndOfEpoch),
2483 K::RandomnessStateUpdate(update) => message
2484 .with_randomness_state_update(update)
2485 .with_kind(Kind::RandomnessStateUpdate),
2486 K::ConsensusCommitPrologueV2(prologue) => message
2487 .with_consensus_commit_prologue(prologue)
2488 .with_kind(Kind::ConsensusCommitPrologueV2),
2489 K::ConsensusCommitPrologueV3(prologue) => message
2490 .with_consensus_commit_prologue(prologue)
2491 .with_kind(Kind::ConsensusCommitPrologueV3),
2492 K::ConsensusCommitPrologueV4(prologue) => message
2493 .with_consensus_commit_prologue(prologue)
2494 .with_kind(Kind::ConsensusCommitPrologueV4),
2495 K::ProgrammableSystemTransaction(ptb) => message
2496 .with_programmable_transaction(ptb)
2497 .with_kind(Kind::ProgrammableSystemTransaction),
2498 }
2499 }
2500}
2501
2502impl From<crate::messages_consensus::ConsensusCommitPrologue> for ConsensusCommitPrologue {
2507 fn from(value: crate::messages_consensus::ConsensusCommitPrologue) -> Self {
2508 let mut message = Self::default();
2509 message.epoch = Some(value.epoch);
2510 message.round = Some(value.round);
2511 message.commit_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(
2512 value.commit_timestamp_ms,
2513 ));
2514 message
2515 }
2516}
2517
2518impl From<crate::messages_consensus::ConsensusCommitPrologueV2> for ConsensusCommitPrologue {
2519 fn from(value: crate::messages_consensus::ConsensusCommitPrologueV2) -> Self {
2520 let mut message = Self::default();
2521 message.epoch = Some(value.epoch);
2522 message.round = Some(value.round);
2523 message.commit_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(
2524 value.commit_timestamp_ms,
2525 ));
2526 message.consensus_commit_digest = Some(value.consensus_commit_digest.to_string());
2527 message
2528 }
2529}
2530
2531impl From<crate::messages_consensus::ConsensusCommitPrologueV3> for ConsensusCommitPrologue {
2532 fn from(value: crate::messages_consensus::ConsensusCommitPrologueV3) -> Self {
2533 let mut message = Self::default();
2534 message.epoch = Some(value.epoch);
2535 message.round = Some(value.round);
2536 message.commit_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(
2537 value.commit_timestamp_ms,
2538 ));
2539 message.consensus_commit_digest = Some(value.consensus_commit_digest.to_string());
2540 message.sub_dag_index = value.sub_dag_index;
2541 message.consensus_determined_version_assignments =
2542 Some(value.consensus_determined_version_assignments.into());
2543 message
2544 }
2545}
2546
2547impl From<crate::messages_consensus::ConsensusCommitPrologueV4> for ConsensusCommitPrologue {
2548 fn from(
2549 crate::messages_consensus::ConsensusCommitPrologueV4 {
2550 epoch,
2551 round,
2552 sub_dag_index,
2553 commit_timestamp_ms,
2554 consensus_commit_digest,
2555 consensus_determined_version_assignments,
2556 additional_state_digest,
2557 }: crate::messages_consensus::ConsensusCommitPrologueV4,
2558 ) -> Self {
2559 let mut message = Self::default();
2560 message.epoch = Some(epoch);
2561 message.round = Some(round);
2562 message.commit_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(commit_timestamp_ms));
2563 message.consensus_commit_digest = Some(consensus_commit_digest.to_string());
2564 message.sub_dag_index = sub_dag_index;
2565 message.consensus_determined_version_assignments =
2566 Some(consensus_determined_version_assignments.into());
2567 message.additional_state_digest = Some(additional_state_digest.to_string());
2568 message
2569 }
2570}
2571
2572impl From<crate::messages_consensus::ConsensusDeterminedVersionAssignments>
2577 for ConsensusDeterminedVersionAssignments
2578{
2579 fn from(value: crate::messages_consensus::ConsensusDeterminedVersionAssignments) -> Self {
2580 use crate::messages_consensus::ConsensusDeterminedVersionAssignments as A;
2581
2582 let mut message = Self::default();
2583
2584 let version = match value {
2585 A::CancelledTransactions(canceled_transactions) => {
2586 message.canceled_transactions = canceled_transactions
2587 .into_iter()
2588 .map(|(tx_digest, assignments)| {
2589 let mut message = CanceledTransaction::default();
2590 message.digest = Some(tx_digest.to_string());
2591 message.version_assignments = assignments
2592 .into_iter()
2593 .map(|(id, version)| {
2594 let mut message = VersionAssignment::default();
2595 message.object_id = Some(id.to_canonical_string(true));
2596 message.version = Some(version.value());
2597 message
2598 })
2599 .collect();
2600 message
2601 })
2602 .collect();
2603 1
2604 }
2605 A::CancelledTransactionsV2(canceled_transactions) => {
2606 message.canceled_transactions = canceled_transactions
2607 .into_iter()
2608 .map(|(tx_digest, assignments)| {
2609 let mut message = CanceledTransaction::default();
2610 message.digest = Some(tx_digest.to_string());
2611 message.version_assignments = assignments
2612 .into_iter()
2613 .map(|((id, start_version), version)| {
2614 let mut message = VersionAssignment::default();
2615 message.object_id = Some(id.to_canonical_string(true));
2616 message.start_version = Some(start_version.value());
2617 message.version = Some(version.value());
2618 message
2619 })
2620 .collect();
2621 message
2622 })
2623 .collect();
2624 2
2625 }
2626 };
2627
2628 message.version = Some(version);
2629 message
2630 }
2631}
2632
2633impl From<crate::transaction::GenesisTransaction> for GenesisTransaction {
2638 fn from(value: crate::transaction::GenesisTransaction) -> Self {
2639 let mut message = Self::default();
2640 message.objects = value.objects.into_iter().map(Into::into).collect();
2641 message
2642 }
2643}
2644
2645impl From<crate::transaction::RandomnessStateUpdate> for RandomnessStateUpdate {
2650 fn from(value: crate::transaction::RandomnessStateUpdate) -> Self {
2651 let mut message = Self::default();
2652 message.epoch = Some(value.epoch);
2653 message.randomness_round = Some(value.randomness_round.0);
2654 message.random_bytes = Some(value.random_bytes.into());
2655 message.randomness_object_initial_shared_version =
2656 Some(value.randomness_obj_initial_shared_version.value());
2657 message
2658 }
2659}
2660
2661impl From<crate::transaction::AuthenticatorStateUpdate> for AuthenticatorStateUpdate {
2666 fn from(value: crate::transaction::AuthenticatorStateUpdate) -> Self {
2667 let mut message = Self::default();
2668 message.epoch = Some(value.epoch);
2669 message.round = Some(value.round);
2670 message.new_active_jwks = value.new_active_jwks.into_iter().map(Into::into).collect();
2671 message.authenticator_object_initial_shared_version =
2672 Some(value.authenticator_obj_initial_shared_version.value());
2673 message
2674 }
2675}
2676
2677impl From<crate::authenticator_state::ActiveJwk> for ActiveJwk {
2682 fn from(value: crate::authenticator_state::ActiveJwk) -> Self {
2683 let mut jwk_id = JwkId::default();
2684 jwk_id.iss = Some(value.jwk_id.iss);
2685 jwk_id.kid = Some(value.jwk_id.kid);
2686
2687 let mut jwk = Jwk::default();
2688 jwk.kty = Some(value.jwk.kty);
2689 jwk.e = Some(value.jwk.e);
2690 jwk.n = Some(value.jwk.n);
2691 jwk.alg = Some(value.jwk.alg);
2692
2693 let mut message = Self::default();
2694 message.id = Some(jwk_id);
2695 message.jwk = Some(jwk);
2696 message.epoch = Some(value.epoch);
2697 message
2698 }
2699}
2700
2701impl From<crate::transaction::ChangeEpoch> for ChangeEpoch {
2706 fn from(value: crate::transaction::ChangeEpoch) -> Self {
2707 let mut message = Self::default();
2708 message.epoch = Some(value.epoch);
2709 message.protocol_version = Some(value.protocol_version.as_u64());
2710 message.storage_charge = Some(value.storage_charge);
2711 message.computation_charge = Some(value.computation_charge);
2712 message.storage_rebate = Some(value.storage_rebate);
2713 message.non_refundable_storage_fee = Some(value.non_refundable_storage_fee);
2714 message.epoch_start_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(
2715 value.epoch_start_timestamp_ms,
2716 ));
2717 message.system_packages = value
2718 .system_packages
2719 .into_iter()
2720 .map(|(version, modules, dependencies)| {
2721 let mut message = SystemPackage::default();
2722 message.version = Some(version.value());
2723 message.modules = modules.into_iter().map(Into::into).collect();
2724 message.dependencies = dependencies
2725 .iter()
2726 .map(|d| d.to_canonical_string(true))
2727 .collect();
2728 message
2729 })
2730 .collect();
2731 message
2732 }
2733}
2734
2735impl From<crate::transaction::EndOfEpochTransactionKind> for EndOfEpochTransactionKind {
2740 fn from(value: crate::transaction::EndOfEpochTransactionKind) -> Self {
2741 use crate::transaction::EndOfEpochTransactionKind as K;
2742 use end_of_epoch_transaction_kind::Kind;
2743
2744 let message = Self::default();
2745
2746 match value {
2747 K::ChangeEpoch(change_epoch) => message
2748 .with_change_epoch(change_epoch)
2749 .with_kind(Kind::ChangeEpoch),
2750 K::AuthenticatorStateCreate => message.with_kind(Kind::AuthenticatorStateCreate),
2751 K::AuthenticatorStateExpire(expire) => message
2752 .with_authenticator_state_expire(expire)
2753 .with_kind(Kind::AuthenticatorStateExpire),
2754 K::RandomnessStateCreate => message.with_kind(Kind::RandomnessStateCreate),
2755 K::DenyListStateCreate => message.with_kind(Kind::DenyListStateCreate),
2756 K::BridgeStateCreate(chain_id) => message
2757 .with_bridge_chain_id(chain_id.to_string())
2758 .with_kind(Kind::BridgeStateCreate),
2759 K::BridgeCommitteeInit(bridge_object_version) => message
2760 .with_bridge_object_version(bridge_object_version.into())
2761 .with_kind(Kind::BridgeCommitteeInit),
2762 K::StoreExecutionTimeObservations(observations) => message
2763 .with_execution_time_observations(observations)
2764 .with_kind(Kind::StoreExecutionTimeObservations),
2765 K::AccumulatorRootCreate => message.with_kind(Kind::AccumulatorRootCreate),
2766 K::CoinRegistryCreate => message.with_kind(Kind::CoinRegistryCreate),
2767 K::DisplayRegistryCreate => message.with_kind(Kind::DisplayRegistryCreate),
2768 K::AddressAliasStateCreate => message.with_kind(Kind::AddressAliasStateCreate),
2769 K::ForwardingAddressRegistryCreate => {
2770 message.with_kind(Kind::ForwardingAddressRegistryCreate)
2771 }
2772 K::WriteAccumulatorStorageCost(storage_cost) => message
2773 .with_kind(Kind::WriteAccumulatorStorageCost)
2774 .with_storage_cost(storage_cost.storage_cost),
2775 }
2776 }
2777}
2778
2779impl From<crate::transaction::AuthenticatorStateExpire> for AuthenticatorStateExpire {
2784 fn from(value: crate::transaction::AuthenticatorStateExpire) -> Self {
2785 let mut message = Self::default();
2786 message.min_epoch = Some(value.min_epoch);
2787 message.authenticator_object_initial_shared_version =
2788 Some(value.authenticator_obj_initial_shared_version.value());
2789 message
2790 }
2791}
2792
2793impl From<crate::transaction::StoredExecutionTimeObservations> for ExecutionTimeObservations {
2796 fn from(value: crate::transaction::StoredExecutionTimeObservations) -> Self {
2797 let mut message = Self::default();
2798 match value {
2799 crate::transaction::StoredExecutionTimeObservations::V1(vec) => {
2800 message.version = Some(1);
2801 message.observations = vec
2802 .into_iter()
2803 .map(|(key, observation)| {
2804 use crate::execution::ExecutionTimeObservationKey as K;
2805 use execution_time_observation::ExecutionTimeObservationKind;
2806
2807 let mut message = ExecutionTimeObservation::default();
2808
2809 let kind = match key {
2810 K::MoveEntryPoint {
2811 package,
2812 module,
2813 function,
2814 type_arguments,
2815 } => {
2816 message.move_entry_point = Some({
2817 let mut message = MoveCall::default();
2818 message.package = Some(package.to_canonical_string(true));
2819 message.module = Some(module);
2820 message.function = Some(function);
2821 message.type_arguments = type_arguments
2822 .into_iter()
2823 .map(|ty| ty.to_canonical_string(true))
2824 .collect();
2825 message
2826 });
2827 ExecutionTimeObservationKind::MoveEntryPoint
2828 }
2829 K::TransferObjects => ExecutionTimeObservationKind::TransferObjects,
2830 K::SplitCoins => ExecutionTimeObservationKind::SplitCoins,
2831 K::MergeCoins => ExecutionTimeObservationKind::MergeCoins,
2832 K::Publish => ExecutionTimeObservationKind::Publish,
2833 K::MakeMoveVec => ExecutionTimeObservationKind::MakeMoveVector,
2834 K::Upgrade => ExecutionTimeObservationKind::Upgrade,
2835 };
2836
2837 message.validator_observations = observation
2838 .into_iter()
2839 .map(|(name, duration)| {
2840 let mut message = ValidatorExecutionTimeObservation::default();
2841 message.validator = Some(name.0.to_vec().into());
2842 message.duration = Some(prost_types::Duration {
2843 seconds: duration.as_secs() as i64,
2844 nanos: duration.subsec_nanos() as i32,
2845 });
2846 message
2847 })
2848 .collect();
2849
2850 message.set_kind(kind);
2851 message
2852 })
2853 .collect();
2854 }
2855 }
2856
2857 message
2858 }
2859}
2860
2861impl From<crate::transaction::ProgrammableTransaction> for ProgrammableTransaction {
2866 fn from(value: crate::transaction::ProgrammableTransaction) -> Self {
2867 let mut message = Self::default();
2868 message.inputs = value.inputs.into_iter().map(Into::into).collect();
2869 message.commands = value.commands.into_iter().map(Into::into).collect();
2870 message
2871 }
2872}
2873
2874impl From<crate::transaction::CallArg> for Input {
2879 fn from(value: crate::transaction::CallArg) -> Self {
2880 use crate::transaction::CallArg as I;
2881 use crate::transaction::ObjectArg as O;
2882 use input::InputKind;
2883 use input::Mutability;
2884
2885 let mut message = Self::default();
2886
2887 let kind = match value {
2888 I::Pure(value) => {
2889 message.pure = Some(value.into());
2890 InputKind::Pure
2891 }
2892 I::Object(o) => match o {
2893 O::ImmOrOwnedObject((id, version, digest)) => {
2894 message.object_id = Some(id.to_canonical_string(true));
2895 message.version = Some(version.value());
2896 message.digest = Some(digest.to_string());
2897 InputKind::ImmutableOrOwned
2898 }
2899 O::SharedObject {
2900 id,
2901 initial_shared_version,
2902 mutability,
2903 } => {
2904 message.object_id = Some(id.to_canonical_string(true));
2905 message.version = Some(initial_shared_version.value());
2906 message.mutable = Some(mutability.is_exclusive());
2907 message.set_mutability(match mutability {
2908 crate::transaction::SharedObjectMutability::Immutable => {
2909 Mutability::Immutable
2910 }
2911 crate::transaction::SharedObjectMutability::Mutable => Mutability::Mutable,
2912 crate::transaction::SharedObjectMutability::NonExclusiveWrite => {
2913 Mutability::NonExclusiveWrite
2914 }
2915 });
2916 InputKind::Shared
2917 }
2918 O::Receiving((id, version, digest)) => {
2919 message.object_id = Some(id.to_canonical_string(true));
2920 message.version = Some(version.value());
2921 message.digest = Some(digest.to_string());
2922 InputKind::Receiving
2923 }
2924 },
2925 I::FundsWithdrawal(withdrawal) => {
2926 message.set_funds_withdrawal(withdrawal);
2927 InputKind::FundsWithdrawal
2928 }
2929 };
2930
2931 message.set_kind(kind);
2932 message
2933 }
2934}
2935
2936impl From<crate::transaction::FundsWithdrawalArg> for FundsWithdrawal {
2937 fn from(value: crate::transaction::FundsWithdrawalArg) -> Self {
2938 use funds_withdrawal::Source;
2939
2940 let mut message = Self::default();
2941
2942 message.amount = match value.reservation {
2943 crate::transaction::Reservation::MaxAmountU64(amount) => Some(amount),
2944 };
2945 let crate::transaction::WithdrawalTypeArg::Balance(coin_type) = value.type_arg;
2946 message.coin_type = Some(coin_type.to_canonical_string(true));
2947 let source = match value.withdraw_from {
2948 crate::transaction::WithdrawFrom::Sender => Source::Sender,
2949 crate::transaction::WithdrawFrom::Sponsor => Source::Sponsor,
2950 crate::transaction::WithdrawFrom::SenderAllowance { funder, allowance } => {
2951 message.funder = Some(funder.to_string());
2952 message.allowance = Some(allowance.to_string());
2953 Source::SenderAllowance
2954 }
2955 };
2956 message.set_source(source);
2957
2958 message
2959 }
2960}
2961
2962impl From<crate::transaction::Argument> for Argument {
2967 fn from(value: crate::transaction::Argument) -> Self {
2968 use crate::transaction::Argument as A;
2969 use argument::ArgumentKind;
2970
2971 let mut message = Self::default();
2972
2973 let kind = match value {
2974 A::GasCoin => ArgumentKind::Gas,
2975 A::Input(input) => {
2976 message.input = Some(input.into());
2977 ArgumentKind::Input
2978 }
2979 A::Result(result) => {
2980 message.result = Some(result.into());
2981 ArgumentKind::Result
2982 }
2983 A::NestedResult(result, subresult) => {
2984 message.result = Some(result.into());
2985 message.subresult = Some(subresult.into());
2986 ArgumentKind::Result
2987 }
2988 };
2989
2990 message.set_kind(kind);
2991 message
2992 }
2993}
2994
2995impl From<crate::transaction::Command> for Command {
3000 fn from(value: crate::transaction::Command) -> Self {
3001 use crate::transaction::Command as C;
3002 use command::Command;
3003
3004 let command = match value {
3005 C::MoveCall(move_call) => Command::MoveCall((*move_call).into()),
3006 C::TransferObjects(objects, address) => Command::TransferObjects({
3007 let mut message = TransferObjects::default();
3008 message.objects = objects.into_iter().map(Into::into).collect();
3009 message.address = Some(address.into());
3010 message
3011 }),
3012 C::SplitCoins(coin, amounts) => Command::SplitCoins({
3013 let mut message = SplitCoins::default();
3014 message.coin = Some(coin.into());
3015 message.amounts = amounts.into_iter().map(Into::into).collect();
3016 message
3017 }),
3018 C::MergeCoins(coin, coins_to_merge) => Command::MergeCoins({
3019 let mut message = MergeCoins::default();
3020 message.coin = Some(coin.into());
3021 message.coins_to_merge = coins_to_merge.into_iter().map(Into::into).collect();
3022 message
3023 }),
3024 C::Publish(modules, dependencies) => Command::Publish({
3025 let mut message = Publish::default();
3026 message.modules = modules.into_iter().map(Into::into).collect();
3027 message.dependencies = dependencies
3028 .iter()
3029 .map(|d| d.to_canonical_string(true))
3030 .collect();
3031 message
3032 }),
3033 C::MakeMoveVec(element_type, elements) => Command::MakeMoveVector({
3034 let mut message = MakeMoveVector::default();
3035 message.element_type = element_type.map(|t| t.to_canonical_string(true));
3036 message.elements = elements.into_iter().map(Into::into).collect();
3037 message
3038 }),
3039 C::Upgrade(modules, dependencies, package, ticket) => Command::Upgrade({
3040 let mut message = Upgrade::default();
3041 message.modules = modules.into_iter().map(Into::into).collect();
3042 message.dependencies = dependencies
3043 .iter()
3044 .map(|d| d.to_canonical_string(true))
3045 .collect();
3046 message.package = Some(package.to_canonical_string(true));
3047 message.ticket = Some(ticket.into());
3048 message
3049 }),
3050 };
3051
3052 let mut message = Self::default();
3053 message.command = Some(command);
3054 message
3055 }
3056}
3057
3058impl From<crate::transaction::ProgrammableMoveCall> for MoveCall {
3063 fn from(value: crate::transaction::ProgrammableMoveCall) -> Self {
3064 let mut message = Self::default();
3065 message.package = Some(value.package.to_canonical_string(true));
3066 message.module = Some(value.module.to_string());
3067 message.function = Some(value.function.to_string());
3068 message.type_arguments = value
3069 .type_arguments
3070 .iter()
3071 .map(|t| t.to_canonical_string(true))
3072 .collect();
3073 message.arguments = value.arguments.into_iter().map(Into::into).collect();
3074 message
3075 }
3076}
3077
3078impl From<crate::effects::TransactionEffects> for TransactionEffects {
3083 fn from(value: crate::effects::TransactionEffects) -> Self {
3084 Self::merge_from(&value, &FieldMaskTree::new_wildcard())
3085 }
3086}
3087
3088impl Merge<&crate::effects::TransactionEffects> for TransactionEffects {
3089 fn merge(&mut self, source: &crate::effects::TransactionEffects, mask: &FieldMaskTree) {
3090 if mask.contains(Self::BCS_FIELD.name) {
3091 let mut bcs = Bcs::serialize(&source).unwrap();
3092 bcs.name = Some("TransactionEffects".to_owned());
3093 self.bcs = Some(bcs);
3094 }
3095
3096 if mask.contains(Self::DIGEST_FIELD.name) {
3097 self.digest = Some(source.digest().to_string());
3098 }
3099
3100 match source {
3101 crate::effects::TransactionEffects::V1(v1) => self.merge(v1, mask),
3102 crate::effects::TransactionEffects::V2(v2) => self.merge(v2, mask),
3103 }
3104 }
3105}
3106
3107impl Merge<&crate::effects::TransactionEffectsV1> for TransactionEffects {
3112 fn merge(&mut self, value: &crate::effects::TransactionEffectsV1, mask: &FieldMaskTree) {
3113 use crate::effects::TransactionEffectsAPI;
3114
3115 if mask.contains(Self::VERSION_FIELD.name) {
3116 self.version = Some(1);
3117 }
3118
3119 if mask.contains(Self::STATUS_FIELD.name) {
3120 self.status = Some(value.status().clone().into());
3121 }
3122
3123 if mask.contains(Self::EPOCH_FIELD.name) {
3124 self.epoch = Some(value.executed_epoch());
3125 }
3126
3127 if mask.contains(Self::GAS_USED_FIELD.name) {
3128 self.gas_used = Some(value.gas_cost_summary().clone().into());
3129 }
3130
3131 if mask.contains(Self::TRANSACTION_DIGEST_FIELD.name) {
3132 self.transaction_digest = Some(value.transaction_digest().to_string());
3133 }
3134
3135 if mask.contains(Self::EVENTS_DIGEST_FIELD.name) {
3136 self.events_digest = value.events_digest().map(|d| d.to_string());
3137 }
3138
3139 if mask.contains(Self::DEPENDENCIES_FIELD.name) {
3140 self.dependencies = value
3141 .dependencies()
3142 .iter()
3143 .map(ToString::to_string)
3144 .collect();
3145 }
3146
3147 if mask.contains(Self::LAMPORT_VERSION_FIELD.name) {
3148 self.lamport_version = Some(value.lamport_version().value());
3149 }
3150
3151 if mask.contains(Self::CHANGED_OBJECTS_FIELD.name)
3152 || mask.contains(Self::UNCHANGED_CONSENSUS_OBJECTS_FIELD.name)
3153 || mask.contains(Self::GAS_OBJECT_FIELD.name)
3154 {
3155 let mut changed_objects = Vec::new();
3156 let mut unchanged_consensus_objects = Vec::new();
3157
3158 for ((id, version, digest), owner) in value.created() {
3159 let mut change = ChangedObject::default();
3160 change.object_id = Some(id.to_canonical_string(true));
3161 change.input_state = Some(changed_object::InputObjectState::DoesNotExist.into());
3162 change.output_state = Some(changed_object::OutputObjectState::ObjectWrite.into());
3163 change.output_version = Some(version.value());
3164 change.output_digest = Some(digest.to_string());
3165 change.output_owner = Some(owner.clone().into());
3166 change.id_operation = Some(changed_object::IdOperation::Created.into());
3167
3168 changed_objects.push(change);
3169 }
3170
3171 for ((id, version, digest), owner) in value.mutated() {
3172 let mut change = ChangedObject::default();
3173 change.object_id = Some(id.to_canonical_string(true));
3174 change.input_state = Some(changed_object::InputObjectState::Exists.into());
3175 change.output_state = Some(changed_object::OutputObjectState::ObjectWrite.into());
3176 change.output_version = Some(version.value());
3177 change.output_digest = Some(digest.to_string());
3178 change.output_owner = Some(owner.clone().into());
3179 change.id_operation = Some(changed_object::IdOperation::None.into());
3180
3181 changed_objects.push(change);
3182 }
3183
3184 for ((id, version, digest), owner) in value.unwrapped() {
3185 let mut change = ChangedObject::default();
3186 change.object_id = Some(id.to_canonical_string(true));
3187 change.input_state = Some(changed_object::InputObjectState::DoesNotExist.into());
3188 change.output_state = Some(changed_object::OutputObjectState::ObjectWrite.into());
3189 change.output_version = Some(version.value());
3190 change.output_digest = Some(digest.to_string());
3191 change.output_owner = Some(owner.clone().into());
3192 change.id_operation = Some(changed_object::IdOperation::None.into());
3193
3194 changed_objects.push(change);
3195 }
3196
3197 for (id, version, digest) in value.deleted() {
3198 let mut change = ChangedObject::default();
3199 change.object_id = Some(id.to_canonical_string(true));
3200 change.input_state = Some(changed_object::InputObjectState::Exists.into());
3201 change.output_state = Some(changed_object::OutputObjectState::DoesNotExist.into());
3202 change.output_version = Some(version.value());
3203 change.output_digest = Some(digest.to_string());
3204 change.id_operation = Some(changed_object::IdOperation::Deleted.into());
3205
3206 changed_objects.push(change);
3207 }
3208
3209 for (id, version, digest) in value.unwrapped_then_deleted() {
3210 let mut change = ChangedObject::default();
3211 change.object_id = Some(id.to_canonical_string(true));
3212 change.input_state = Some(changed_object::InputObjectState::DoesNotExist.into());
3213 change.output_state = Some(changed_object::OutputObjectState::DoesNotExist.into());
3214 change.output_version = Some(version.value());
3215 change.output_digest = Some(digest.to_string());
3216 change.id_operation = Some(changed_object::IdOperation::Deleted.into());
3217
3218 changed_objects.push(change);
3219 }
3220
3221 for (id, version, digest) in value.wrapped() {
3222 let mut change = ChangedObject::default();
3223 change.object_id = Some(id.to_canonical_string(true));
3224 change.input_state = Some(changed_object::InputObjectState::Exists.into());
3225 change.output_state = Some(changed_object::OutputObjectState::DoesNotExist.into());
3226 change.output_version = Some(version.value());
3227 change.output_digest = Some(digest.to_string());
3228 change.id_operation = Some(changed_object::IdOperation::Deleted.into());
3229
3230 changed_objects.push(change);
3231 }
3232
3233 for (object_id, version) in value.modified_at_versions() {
3234 let object_id = object_id.to_canonical_string(true);
3235 let version = version.value();
3236 if let Some(changed_object) = changed_objects
3237 .iter_mut()
3238 .find(|object| object.object_id() == object_id)
3239 {
3240 changed_object.input_version = Some(version);
3241 }
3242 }
3243
3244 for (id, version, digest) in value.shared_objects() {
3245 let object_id = id.to_canonical_string(true);
3246 let version = version.value();
3247 let digest = digest.to_string();
3248
3249 if let Some(changed_object) = changed_objects
3250 .iter_mut()
3251 .find(|object| object.object_id() == object_id)
3252 {
3253 changed_object.input_version = Some(version);
3254 changed_object.input_digest = Some(digest);
3255 } else {
3256 let mut unchanged_consensus_object = UnchangedConsensusObject::default();
3257 unchanged_consensus_object.kind = Some(
3258 unchanged_consensus_object::UnchangedConsensusObjectKind::ReadOnlyRoot
3259 .into(),
3260 );
3261 unchanged_consensus_object.object_id = Some(object_id);
3262 unchanged_consensus_object.version = Some(version);
3263 unchanged_consensus_object.digest = Some(digest);
3264
3265 unchanged_consensus_objects.push(unchanged_consensus_object);
3266 }
3267 }
3268
3269 if mask.contains(Self::GAS_OBJECT_FIELD.name)
3270 && let Some(((gas_id, _, _), _)) = value.gas_object()
3271 {
3272 let gas_object_id = gas_id.to_canonical_string(true);
3273 self.gas_object = changed_objects
3274 .iter()
3275 .find(|object| object.object_id() == gas_object_id)
3276 .cloned();
3277 }
3278
3279 if mask.contains(Self::CHANGED_OBJECTS_FIELD.name) {
3280 self.changed_objects = changed_objects;
3281 }
3282
3283 if mask.contains(Self::UNCHANGED_CONSENSUS_OBJECTS_FIELD.name) {
3284 self.unchanged_consensus_objects = unchanged_consensus_objects;
3285 }
3286 }
3287 }
3288}
3289
3290impl Merge<&crate::effects::TransactionEffectsV2> for TransactionEffects {
3295 fn merge(
3296 &mut self,
3297 crate::effects::TransactionEffectsV2 {
3298 status,
3299 executed_epoch,
3300 gas_used,
3301 transaction_digest,
3302 gas_object_index,
3303 events_digest,
3304 dependencies,
3305 lamport_version,
3306 changed_objects,
3307 unchanged_consensus_objects,
3308 aux_data_digest,
3309 }: &crate::effects::TransactionEffectsV2,
3310 mask: &FieldMaskTree,
3311 ) {
3312 if mask.contains(Self::VERSION_FIELD.name) {
3313 self.version = Some(2);
3314 }
3315
3316 if mask.contains(Self::STATUS_FIELD.name) {
3317 self.status = Some(status.clone().into());
3318 }
3319
3320 if mask.contains(Self::EPOCH_FIELD.name) {
3321 self.epoch = Some(*executed_epoch);
3322 }
3323
3324 if mask.contains(Self::GAS_USED_FIELD.name) {
3325 self.gas_used = Some(gas_used.clone().into());
3326 }
3327
3328 if mask.contains(Self::TRANSACTION_DIGEST_FIELD.name) {
3329 self.transaction_digest = Some(transaction_digest.to_string());
3330 }
3331
3332 if mask.contains(Self::GAS_OBJECT_FIELD.name) {
3333 self.gas_object = gas_object_index
3334 .map(|index| {
3335 changed_objects
3336 .get(index as usize)
3337 .cloned()
3338 .map(|(id, change)| {
3339 let mut message = ChangedObject::from(change);
3340 message.object_id = Some(id.to_canonical_string(true));
3341 message
3342 })
3343 })
3344 .flatten();
3345 }
3346
3347 if mask.contains(Self::EVENTS_DIGEST_FIELD.name) {
3348 self.events_digest = events_digest.map(|d| d.to_string());
3349 }
3350
3351 if mask.contains(Self::DEPENDENCIES_FIELD.name) {
3352 self.dependencies = dependencies.iter().map(ToString::to_string).collect();
3353 }
3354
3355 if mask.contains(Self::LAMPORT_VERSION_FIELD.name) {
3356 self.lamport_version = Some(lamport_version.value());
3357 }
3358
3359 if mask.contains(Self::CHANGED_OBJECTS_FIELD.name) {
3360 self.changed_objects = changed_objects
3361 .clone()
3362 .into_iter()
3363 .map(|(id, change)| {
3364 let mut message = ChangedObject::from(change);
3365 message.object_id = Some(id.to_canonical_string(true));
3366 message
3367 })
3368 .collect();
3369 }
3370
3371 for object in self.changed_objects.iter_mut().chain(&mut self.gas_object) {
3372 if object.output_digest.is_some() && object.output_version.is_none() {
3373 object.output_version = Some(lamport_version.value());
3374 }
3375 }
3376
3377 if mask.contains(Self::UNCHANGED_CONSENSUS_OBJECTS_FIELD.name) {
3378 self.unchanged_consensus_objects = unchanged_consensus_objects
3379 .clone()
3380 .into_iter()
3381 .map(|(id, unchanged)| {
3382 let mut message = UnchangedConsensusObject::from(unchanged);
3383 message.object_id = Some(id.to_canonical_string(true));
3384 message
3385 })
3386 .collect();
3387 }
3388
3389 if mask.contains(Self::AUXILIARY_DATA_DIGEST_FIELD.name) {
3390 self.auxiliary_data_digest = aux_data_digest.map(|d| d.to_string());
3391 }
3392 }
3393}
3394
3395impl From<crate::effects::EffectsObjectChange> for ChangedObject {
3400 fn from(value: crate::effects::EffectsObjectChange) -> Self {
3401 use crate::effects::ObjectIn;
3402 use crate::effects::ObjectOut;
3403 use changed_object::InputObjectState;
3404 use changed_object::OutputObjectState;
3405
3406 let mut message = Self::default();
3407
3408 let input_state = match value.input_state {
3410 ObjectIn::NotExist => InputObjectState::DoesNotExist,
3411 ObjectIn::Exist(((version, digest), owner)) => {
3412 message.input_version = Some(version.value());
3413 message.input_digest = Some(digest.to_string());
3414 message.input_owner = Some(owner.into());
3415 InputObjectState::Exists
3416 }
3417 };
3418 message.set_input_state(input_state);
3419
3420 let output_state = match value.output_state {
3422 ObjectOut::NotExist => OutputObjectState::DoesNotExist,
3423 ObjectOut::ObjectWrite((digest, owner)) => {
3424 message.output_digest = Some(digest.to_string());
3425 message.output_owner = Some(owner.into());
3426 OutputObjectState::ObjectWrite
3427 }
3428 ObjectOut::PackageWrite((version, digest)) => {
3429 message.output_version = Some(version.value());
3430 message.output_digest = Some(digest.to_string());
3431 OutputObjectState::PackageWrite
3432 }
3433 ObjectOut::AccumulatorWriteV1(accumulator_write) => {
3434 message.set_accumulator_write(accumulator_write);
3435 OutputObjectState::AccumulatorWrite
3436 }
3437 };
3438 message.set_output_state(output_state);
3439
3440 message.set_id_operation(value.id_operation.into());
3441 message
3442 }
3443}
3444
3445impl From<crate::effects::AccumulatorWriteV1> for AccumulatorWrite {
3446 fn from(value: crate::effects::AccumulatorWriteV1) -> Self {
3447 use accumulator_write::AccumulatorOperation;
3448
3449 let mut message = Self::default();
3450
3451 message.set_address(value.address.address.to_string());
3452 message.set_accumulator_type(value.address.ty.to_canonical_string(true));
3453 message.set_operation(match value.operation {
3454 crate::effects::AccumulatorOperation::Merge => AccumulatorOperation::Merge,
3455 crate::effects::AccumulatorOperation::Split => AccumulatorOperation::Split,
3456 });
3457 match value.value {
3458 crate::effects::AccumulatorValue::Integer(value) => message.set_integer_value(value),
3459 crate::effects::AccumulatorValue::IntegerTuple(_, _)
3461 | crate::effects::AccumulatorValue::EventDigest(_) => {}
3462 }
3463
3464 message
3465 }
3466}
3467
3468impl From<crate::effects::IDOperation> for changed_object::IdOperation {
3473 fn from(value: crate::effects::IDOperation) -> Self {
3474 use crate::effects::IDOperation as I;
3475
3476 match value {
3477 I::None => Self::None,
3478 I::Created => Self::Created,
3479 I::Deleted => Self::Deleted,
3480 }
3481 }
3482}
3483
3484impl From<crate::effects::UnchangedConsensusKind> for UnchangedConsensusObject {
3489 fn from(value: crate::effects::UnchangedConsensusKind) -> Self {
3490 use crate::effects::UnchangedConsensusKind as K;
3491 use unchanged_consensus_object::UnchangedConsensusObjectKind;
3492
3493 let mut message = Self::default();
3494
3495 let kind = match value {
3496 K::ReadOnlyRoot((version, digest)) => {
3497 message.version = Some(version.value());
3498 message.digest = Some(digest.to_string());
3499 UnchangedConsensusObjectKind::ReadOnlyRoot
3500 }
3501 K::MutateConsensusStreamEnded(version) => {
3502 message.version = Some(version.value());
3503 UnchangedConsensusObjectKind::MutateConsensusStreamEnded
3504 }
3505 K::ReadConsensusStreamEnded(version) => {
3506 message.version = Some(version.value());
3507 UnchangedConsensusObjectKind::ReadConsensusStreamEnded
3508 }
3509 K::Cancelled(version) => {
3510 message.version = Some(version.value());
3511 UnchangedConsensusObjectKind::Canceled
3512 }
3513 K::PerEpochConfig => UnchangedConsensusObjectKind::PerEpochConfig,
3514 };
3519
3520 message.set_kind(kind);
3521 message
3522 }
3523}
3524
3525impl From<simulate_transaction_request::TransactionChecks>
3530 for crate::transaction_executor::TransactionChecks
3531{
3532 fn from(value: simulate_transaction_request::TransactionChecks) -> Self {
3533 match value {
3534 simulate_transaction_request::TransactionChecks::Enabled => Self::Enabled,
3535 simulate_transaction_request::TransactionChecks::Disabled => Self::Disabled,
3536 _ => Self::Enabled,
3538 }
3539 }
3540}
3541
3542impl From<crate::coin_registry::MetadataCapState> for coin_metadata::MetadataCapState {
3547 fn from(value: crate::coin_registry::MetadataCapState) -> Self {
3548 match value {
3549 crate::coin_registry::MetadataCapState::Claimed(_) => {
3550 coin_metadata::MetadataCapState::Claimed
3551 }
3552 crate::coin_registry::MetadataCapState::Unclaimed => {
3553 coin_metadata::MetadataCapState::Unclaimed
3554 }
3555 crate::coin_registry::MetadataCapState::Deleted => {
3556 coin_metadata::MetadataCapState::Deleted
3557 }
3558 }
3559 }
3560}
3561
3562impl From<&crate::coin_registry::Currency> for CoinMetadata {
3563 fn from(value: &crate::coin_registry::Currency) -> Self {
3564 let mut metadata = CoinMetadata::default();
3565 metadata.id = Some(sui_sdk_types::Address::from(value.id.into_bytes()).to_string());
3566 metadata.decimals = Some(value.decimals.into());
3567 metadata.name = Some(value.name.clone());
3568 metadata.symbol = Some(value.symbol.clone());
3569 metadata.description = Some(value.description.clone());
3570 metadata.icon_url = Some(value.icon_url.clone());
3571
3572 match &value.metadata_cap_id {
3573 crate::coin_registry::MetadataCapState::Claimed(id) => {
3574 metadata.metadata_cap_state = Some(coin_metadata::MetadataCapState::Claimed as i32);
3575 metadata.metadata_cap_id = Some(sui_sdk_types::Address::from(*id).to_string());
3576 }
3577 crate::coin_registry::MetadataCapState::Unclaimed => {
3578 metadata.metadata_cap_state =
3579 Some(coin_metadata::MetadataCapState::Unclaimed as i32);
3580 }
3581 crate::coin_registry::MetadataCapState::Deleted => {
3582 metadata.metadata_cap_state = Some(coin_metadata::MetadataCapState::Deleted as i32);
3583 }
3584 }
3585
3586 metadata
3587 }
3588}
3589
3590impl From<crate::coin::CoinMetadata> for CoinMetadata {
3591 fn from(value: crate::coin::CoinMetadata) -> Self {
3592 let mut metadata = CoinMetadata::default();
3593 metadata.id = Some(sui_sdk_types::Address::from(value.id.id.bytes).to_string());
3594 metadata.decimals = Some(value.decimals.into());
3595 metadata.name = Some(value.name);
3596 metadata.symbol = Some(value.symbol);
3597 metadata.description = Some(value.description);
3598 metadata.icon_url = value.icon_url;
3599 metadata
3600 }
3601}
3602
3603impl From<crate::coin_registry::SupplyState> for coin_treasury::SupplyState {
3604 fn from(value: crate::coin_registry::SupplyState) -> Self {
3605 match value {
3606 crate::coin_registry::SupplyState::Fixed(_) => coin_treasury::SupplyState::Fixed,
3607 crate::coin_registry::SupplyState::BurnOnly(_) => coin_treasury::SupplyState::BurnOnly,
3608 crate::coin_registry::SupplyState::Unknown => coin_treasury::SupplyState::Unknown,
3609 }
3610 }
3611}
3612
3613impl From<crate::coin::TreasuryCap> for CoinTreasury {
3614 fn from(value: crate::coin::TreasuryCap) -> Self {
3615 let mut treasury = CoinTreasury::default();
3616 treasury.id = Some(sui_sdk_types::Address::from(value.id.id.bytes).to_string());
3617 treasury.total_supply = Some(value.total_supply.value);
3618 treasury
3619 }
3620}
3621
3622impl From<&crate::coin_registry::RegulatedState> for RegulatedCoinMetadata {
3623 fn from(value: &crate::coin_registry::RegulatedState) -> Self {
3624 let mut regulated = RegulatedCoinMetadata::default();
3625
3626 match value {
3627 crate::coin_registry::RegulatedState::Regulated {
3628 cap,
3629 allow_global_pause,
3630 variant,
3631 } => {
3632 regulated.deny_cap_object = Some(sui_sdk_types::Address::from(*cap).to_string());
3633 regulated.allow_global_pause = *allow_global_pause;
3634 regulated.variant = Some(*variant as u32);
3635 regulated.coin_regulated_state =
3636 Some(regulated_coin_metadata::CoinRegulatedState::Regulated as i32);
3637 }
3638 crate::coin_registry::RegulatedState::Unregulated => {
3639 regulated.coin_regulated_state =
3640 Some(regulated_coin_metadata::CoinRegulatedState::Unregulated as i32);
3641 }
3642 crate::coin_registry::RegulatedState::Unknown => {
3643 regulated.coin_regulated_state =
3644 Some(regulated_coin_metadata::CoinRegulatedState::Unknown as i32);
3645 }
3646 }
3647
3648 regulated
3649 }
3650}
3651
3652impl From<crate::coin_registry::RegulatedState> for RegulatedCoinMetadata {
3653 fn from(value: crate::coin_registry::RegulatedState) -> Self {
3654 (&value).into()
3655 }
3656}
3657
3658impl From<crate::coin::RegulatedCoinMetadata> for RegulatedCoinMetadata {
3659 fn from(value: crate::coin::RegulatedCoinMetadata) -> Self {
3660 let mut message = RegulatedCoinMetadata::default();
3661 message.id = Some(sui_sdk_types::Address::from(value.id.id.bytes).to_string());
3662 message.coin_metadata_object =
3663 Some(sui_sdk_types::Address::from(value.coin_metadata_object.bytes).to_string());
3664 message.deny_cap_object =
3665 Some(sui_sdk_types::Address::from(value.deny_cap_object.bytes).to_string());
3666 message.coin_regulated_state =
3667 Some(regulated_coin_metadata::CoinRegulatedState::Regulated as i32);
3668 message
3669 }
3670}
3671
3672impl TryFrom<&ObjectSet> for crate::full_checkpoint_content::ObjectSet {
3673 type Error = TryFromProtoError;
3674
3675 fn try_from(value: &ObjectSet) -> Result<Self, Self::Error> {
3676 let mut objects = Self::default();
3677
3678 for o in value.objects() {
3679 objects.insert(
3680 o.bcs()
3681 .deserialize()
3682 .map_err(|e| TryFromProtoError::invalid("object.bcs", e))?,
3683 );
3684 }
3685
3686 Ok(objects)
3687 }
3688}
3689
3690#[cfg(test)]
3691mod tests {
3692 use crate::effects::TransactionEffectsAPI;
3693
3694 #[test]
3695 fn transaction_effects_v1_proto_includes_lamport_version() {
3696 let effects = crate::effects::TransactionEffectsV1::default();
3697 let lamport_version = effects.lamport_version().value();
3698 let proto: sui_rpc::proto::sui::rpc::v2::TransactionEffects =
3699 crate::effects::TransactionEffects::V1(effects).into();
3700
3701 assert_eq!(proto.lamport_version, Some(lamport_version));
3702 }
3703}