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 }
1696 }
1697}
1698
1699impl From<crate::crypto::Signature> for SimpleSignature {
1704 fn from(value: crate::crypto::Signature) -> Self {
1705 Self::from(&value)
1706 }
1707}
1708
1709impl From<&crate::crypto::Signature> for SimpleSignature {
1710 fn from(value: &crate::crypto::Signature) -> Self {
1711 let scheme: SignatureScheme = value.scheme().into();
1712 let signature = value.signature_bytes();
1713 let public_key = value.public_key_bytes();
1714
1715 let mut message = Self::default();
1716 message.scheme = Some(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 message.public_key = Some(value.as_ref().to_vec().into());
1751 }
1752 crate::crypto::PublicKey::ZkLogin(z) => {
1753 message.zklogin = Some(z.into());
1754 }
1755 }
1756
1757 message.set_scheme(value.scheme().into());
1758 message
1759 }
1760}
1761
1762impl From<&crate::multisig::MultiSigPublicKey> for MultisigCommittee {
1767 fn from(value: &crate::multisig::MultiSigPublicKey) -> Self {
1768 let mut message = Self::default();
1769 message.members = value
1770 .pubkeys()
1771 .iter()
1772 .map(|(pk, weight)| {
1773 let mut member = MultisigMember::default();
1774 member.public_key = Some(pk.into());
1775 member.weight = Some((*weight).into());
1776 member
1777 })
1778 .collect();
1779 message.threshold = Some((*value.threshold()).into());
1780 message
1781 }
1782}
1783
1784impl From<&crate::multisig_legacy::MultiSigPublicKeyLegacy> for MultisigCommittee {
1785 fn from(value: &crate::multisig_legacy::MultiSigPublicKeyLegacy) -> Self {
1786 let mut message = Self::default();
1787 message.members = value
1788 .pubkeys()
1789 .iter()
1790 .map(|(pk, weight)| {
1791 let mut member = MultisigMember::default();
1792 member.public_key = Some(pk.into());
1793 member.weight = Some((*weight).into());
1794 member
1795 })
1796 .collect();
1797 message.threshold = Some((*value.threshold()).into());
1798 message
1799 }
1800}
1801
1802impl From<&crate::crypto::CompressedSignature> for MultisigMemberSignature {
1807 fn from(value: &crate::crypto::CompressedSignature) -> Self {
1808 let mut message = Self::default();
1809
1810 let scheme = match value {
1811 crate::crypto::CompressedSignature::Ed25519(b) => {
1812 message.signature = Some(b.0.to_vec().into());
1813 SignatureScheme::Ed25519
1814 }
1815 crate::crypto::CompressedSignature::Secp256k1(b) => {
1816 message.signature = Some(b.0.to_vec().into());
1817 SignatureScheme::Secp256k1
1818 }
1819 crate::crypto::CompressedSignature::Secp256r1(b) => {
1820 message.signature = Some(b.0.to_vec().into());
1821 SignatureScheme::Secp256r1
1822 }
1823 crate::crypto::CompressedSignature::ZkLogin(_z) => {
1824 SignatureScheme::Zklogin
1826 }
1827 crate::crypto::CompressedSignature::Passkey(_p) => {
1828 SignatureScheme::Passkey
1830 }
1831 };
1832
1833 message.set_scheme(scheme);
1834 message
1835 }
1836}
1837
1838impl From<&crate::multisig_legacy::MultiSigLegacy> for MultisigAggregatedSignature {
1843 fn from(value: &crate::multisig_legacy::MultiSigLegacy) -> Self {
1844 let mut legacy_bitmap = Vec::new();
1845 value
1846 .get_bitmap()
1847 .serialize_into(&mut legacy_bitmap)
1848 .unwrap();
1849
1850 Self::default()
1851 .with_signatures(value.get_sigs().iter().map(Into::into).collect())
1852 .with_legacy_bitmap(legacy_bitmap)
1853 .with_committee(value.get_pk())
1854 }
1855}
1856
1857impl From<&crate::multisig::MultiSig> for MultisigAggregatedSignature {
1858 fn from(value: &crate::multisig::MultiSig) -> Self {
1859 let mut message = Self::default();
1860 message.signatures = value.get_sigs().iter().map(Into::into).collect();
1861 message.bitmap = Some(value.get_bitmap().into());
1862 message.committee = Some(value.get_pk().into());
1863 message
1864 }
1865}
1866
1867impl From<&crate::signature::GenericSignature> for UserSignature {
1872 fn from(value: &crate::signature::GenericSignature) -> Self {
1873 Self::merge_from(value, &FieldMaskTree::new_wildcard())
1874 }
1875}
1876
1877impl Merge<&crate::signature::GenericSignature> for UserSignature {
1878 fn merge(&mut self, source: &crate::signature::GenericSignature, mask: &FieldMaskTree) {
1879 use user_signature::Signature;
1880
1881 if mask.contains(Self::BCS_FIELD) {
1882 let mut bcs = Bcs::from(source.as_ref().to_vec());
1883 bcs.name = Some("UserSignatureBytes".to_owned());
1884 self.bcs = Some(bcs);
1885 }
1886
1887 let scheme = match source {
1888 crate::signature::GenericSignature::MultiSig(multi_sig) => {
1889 if mask.contains(Self::MULTISIG_FIELD) {
1890 self.signature = Some(Signature::Multisig(multi_sig.into()));
1891 }
1892 SignatureScheme::Multisig
1893 }
1894 crate::signature::GenericSignature::MultiSigLegacy(multi_sig_legacy) => {
1895 if mask.contains(Self::MULTISIG_FIELD) {
1896 self.signature = Some(Signature::Multisig(multi_sig_legacy.into()));
1897 }
1898 SignatureScheme::Multisig
1899 }
1900 crate::signature::GenericSignature::Signature(signature) => {
1901 let scheme = signature.scheme().into();
1902 if mask.contains(Self::SIMPLE_FIELD) {
1903 self.signature = Some(Signature::Simple(signature.into()));
1904 }
1905 scheme
1906 }
1907 crate::signature::GenericSignature::ZkLoginAuthenticator(z) => {
1908 if mask.contains(Self::ZKLOGIN_FIELD) {
1909 self.signature = Some(Signature::Zklogin(z.into()));
1910 }
1911 SignatureScheme::Zklogin
1912 }
1913 crate::signature::GenericSignature::PasskeyAuthenticator(p) => {
1914 if mask.contains(Self::PASSKEY_FIELD) {
1915 self.signature = Some(Signature::Passkey(p.into()));
1916 }
1917 SignatureScheme::Passkey
1918 }
1919 };
1920
1921 if mask.contains(Self::SCHEME_FIELD) {
1922 self.set_scheme(scheme);
1923 }
1924 }
1925}
1926
1927impl From<crate::balance_change::BalanceChange> for BalanceChange {
1932 fn from(value: crate::balance_change::BalanceChange) -> Self {
1933 let mut message = Self::default();
1934 message.address = Some(value.address.to_string());
1935 message.coin_type = Some(value.coin_type.to_canonical_string(true));
1936 message.amount = Some(value.amount.to_string());
1937 message
1938 }
1939}
1940
1941impl TryFrom<&BalanceChange> for crate::balance_change::BalanceChange {
1942 type Error = TryFromProtoError;
1943
1944 fn try_from(value: &BalanceChange) -> Result<Self, Self::Error> {
1945 Ok(Self {
1946 address: value
1947 .address()
1948 .parse()
1949 .map_err(|e| TryFromProtoError::invalid(BalanceChange::ADDRESS_FIELD, e))?,
1950 coin_type: value
1951 .coin_type()
1952 .parse()
1953 .map_err(|e| TryFromProtoError::invalid(BalanceChange::COIN_TYPE_FIELD, e))?,
1954 amount: value
1955 .amount()
1956 .parse()
1957 .map_err(|e| TryFromProtoError::invalid(BalanceChange::AMOUNT_FIELD, e))?,
1958 })
1959 }
1960}
1961
1962pub const PACKAGE_TYPE: &str = "package";
1967
1968impl From<crate::object::Object> for Object {
1969 fn from(value: crate::object::Object) -> Self {
1970 Self::merge_from(&value, &FieldMaskTree::new_wildcard())
1971 }
1972}
1973
1974impl Merge<&crate::object::Object> for Object {
1975 fn merge(&mut self, source: &crate::object::Object, mask: &FieldMaskTree) {
1976 if mask.contains(Self::BCS_FIELD.name) {
1977 let mut bcs = Bcs::serialize(&source).unwrap();
1978 bcs.name = Some("Object".to_owned());
1979 self.bcs = Some(bcs);
1980 }
1981
1982 if mask.contains(Self::DIGEST_FIELD.name) {
1983 self.digest = Some(source.digest().to_string());
1984 }
1985
1986 if mask.contains(Self::OBJECT_ID_FIELD.name) {
1987 self.object_id = Some(source.id().to_canonical_string(true));
1988 }
1989
1990 if mask.contains(Self::VERSION_FIELD.name) {
1991 self.version = Some(source.version().value());
1992 }
1993
1994 if mask.contains(Self::OWNER_FIELD.name) {
1995 self.owner = Some(source.owner().to_owned().into());
1996 }
1997
1998 if mask.contains(Self::PREVIOUS_TRANSACTION_FIELD.name) {
1999 self.previous_transaction = Some(source.previous_transaction.to_string());
2000 }
2001
2002 if mask.contains(Self::STORAGE_REBATE_FIELD.name) {
2003 self.storage_rebate = Some(source.storage_rebate);
2004 }
2005
2006 if mask.contains(Self::BALANCE_FIELD) {
2007 self.balance = source.as_coin_maybe().map(|coin| coin.balance.value());
2008 }
2009
2010 self.merge(&source.data, mask);
2011 }
2012}
2013
2014impl Merge<&crate::object::MoveObject> for Object {
2015 fn merge(&mut self, source: &crate::object::MoveObject, mask: &FieldMaskTree) {
2016 self.object_id = Some(source.id().to_canonical_string(true));
2017 self.version = Some(source.version().value());
2018
2019 if mask.contains(Self::OBJECT_TYPE_FIELD.name) {
2020 self.object_type = Some(source.type_().to_canonical_string(true));
2021 }
2022
2023 if mask.contains(Self::HAS_PUBLIC_TRANSFER_FIELD.name) {
2024 self.has_public_transfer = Some(source.has_public_transfer());
2025 }
2026
2027 if mask.contains(Self::CONTENTS_FIELD.name) {
2028 let mut bcs = Bcs::from(source.contents().to_vec());
2029 bcs.name = Some(source.type_().to_canonical_string(true));
2030 self.contents = Some(bcs);
2031 }
2032 }
2033}
2034
2035impl Merge<&crate::move_package::MovePackage> for Object {
2036 fn merge(&mut self, source: &crate::move_package::MovePackage, mask: &FieldMaskTree) {
2037 self.object_id = Some(source.id().to_canonical_string(true));
2038 self.version = Some(source.version().value());
2039
2040 if mask.contains(Self::OBJECT_TYPE_FIELD.name) {
2041 self.object_type = Some(PACKAGE_TYPE.to_owned());
2042 }
2043
2044 if mask.contains(Self::PACKAGE_FIELD.name) {
2045 let mut package = Package::default();
2046 package.modules = source
2047 .serialized_module_map()
2048 .iter()
2049 .map(|(name, contents)| {
2050 let mut module = Module::default();
2051 module.name = Some(name.to_string());
2052 module.contents = Some(contents.clone().into());
2053 module
2054 })
2055 .collect();
2056 package.type_origins = source
2057 .type_origin_table()
2058 .clone()
2059 .into_iter()
2060 .map(Into::into)
2061 .collect();
2062 package.linkage = source
2063 .linkage_table()
2064 .iter()
2065 .map(
2066 |(
2067 original_id,
2068 crate::move_package::UpgradeInfo {
2069 upgraded_id,
2070 upgraded_version,
2071 },
2072 )| {
2073 let mut linkage = Linkage::default();
2074 linkage.original_id = Some(original_id.to_canonical_string(true));
2075 linkage.upgraded_id = Some(upgraded_id.to_canonical_string(true));
2076 linkage.upgraded_version = Some(upgraded_version.value());
2077 linkage
2078 },
2079 )
2080 .collect();
2081
2082 self.package = Some(package);
2083 }
2084 }
2085}
2086
2087impl Merge<&crate::object::Data> for Object {
2088 fn merge(&mut self, source: &crate::object::Data, mask: &FieldMaskTree) {
2089 match source {
2090 crate::object::Data::Move(object) => self.merge(object, mask),
2091 crate::object::Data::Package(package) => self.merge(package, mask),
2092 }
2093 }
2094}
2095
2096impl From<crate::move_package::TypeOrigin> for TypeOrigin {
2101 fn from(value: crate::move_package::TypeOrigin) -> Self {
2102 let mut message = Self::default();
2103 message.module_name = Some(value.module_name.to_string());
2104 message.datatype_name = Some(value.datatype_name.to_string());
2105 message.package_id = Some(value.package.to_canonical_string(true));
2106 message
2107 }
2108}
2109
2110impl From<crate::transaction::GenesisObject> for Object {
2115 fn from(value: crate::transaction::GenesisObject) -> Self {
2116 let crate::transaction::GenesisObject::RawObject { data, owner } = value;
2117 let mut message = Self::default();
2118 message.owner = Some(owner.into());
2119
2120 message.merge(&data, &FieldMaskTree::new_wildcard());
2121
2122 message
2123 }
2124}
2125
2126pub trait ObjectRefExt {
2131 fn to_proto(self) -> ObjectReference;
2132}
2133
2134pub trait ObjectReferenceExt {
2135 fn try_to_object_ref(&self) -> Result<crate::base_types::ObjectRef, anyhow::Error>;
2136}
2137
2138impl ObjectRefExt for crate::base_types::ObjectRef {
2139 fn to_proto(self) -> ObjectReference {
2140 let (object_id, version, digest) = self;
2141 let mut message = ObjectReference::default();
2142 message.object_id = Some(object_id.to_canonical_string(true));
2143 message.version = Some(version.value());
2144 message.digest = Some(digest.to_string());
2145 message
2146 }
2147}
2148
2149impl ObjectReferenceExt for ObjectReference {
2150 fn try_to_object_ref(&self) -> Result<crate::base_types::ObjectRef, anyhow::Error> {
2151 use anyhow::Context;
2152
2153 let object_id = self
2154 .object_id_opt()
2155 .ok_or_else(|| anyhow::anyhow!("missing object_id"))?;
2156 let object_id = crate::base_types::ObjectID::from_hex_literal(object_id)
2157 .with_context(|| format!("Failed to parse object_id: {}", object_id))?;
2158
2159 let version = self
2160 .version_opt()
2161 .ok_or_else(|| anyhow::anyhow!("missing version"))?;
2162 let version = crate::base_types::SequenceNumber::from(version);
2163
2164 let digest = self
2165 .digest_opt()
2166 .ok_or_else(|| anyhow::anyhow!("missing digest"))?;
2167 let digest = digest
2168 .parse::<crate::digests::ObjectDigest>()
2169 .with_context(|| format!("Failed to parse digest: {}", digest))?;
2170
2171 Ok((object_id, version, digest))
2172 }
2173}
2174
2175impl From<&crate::storage::ObjectKey> for ObjectReference {
2176 fn from(value: &crate::storage::ObjectKey) -> Self {
2177 Self::default()
2178 .with_object_id(value.0.to_canonical_string(true))
2179 .with_version(value.1.value())
2180 }
2181}
2182
2183impl From<crate::object::Owner> for Owner {
2188 fn from(value: crate::object::Owner) -> Self {
2189 use crate::object::Owner as O;
2190 use owner::OwnerKind;
2191
2192 let mut message = Self::default();
2193
2194 let kind = match value {
2195 O::AddressOwner(address) => {
2196 message.address = Some(address.to_string());
2197 OwnerKind::Address
2198 }
2199 O::ObjectOwner(address) => {
2200 message.address = Some(address.to_string());
2201 OwnerKind::Object
2202 }
2203 O::Shared {
2204 initial_shared_version,
2205 } => {
2206 message.version = Some(initial_shared_version.value());
2207 OwnerKind::Shared
2208 }
2209 O::Immutable => OwnerKind::Immutable,
2210 O::ConsensusAddressOwner {
2211 start_version,
2212 owner,
2213 } => {
2214 message.version = Some(start_version.value());
2215 message.address = Some(owner.to_string());
2216 OwnerKind::ConsensusAddress
2217 }
2218 O::Party { .. } => todo!("Party WIP"),
2220 };
2221
2222 message.set_kind(kind);
2223 message
2224 }
2225}
2226
2227impl From<crate::transaction::TransactionData> for Transaction {
2232 fn from(value: crate::transaction::TransactionData) -> Self {
2233 Self::merge_from(&value, &FieldMaskTree::new_wildcard())
2234 }
2235}
2236
2237impl Merge<&crate::transaction::TransactionData> for Transaction {
2238 fn merge(&mut self, source: &crate::transaction::TransactionData, mask: &FieldMaskTree) {
2239 merge_transaction_data(self, source, None, mask);
2240 }
2241}
2242
2243fn merge_transaction_data(
2244 message: &mut Transaction,
2245 source: &crate::transaction::TransactionData,
2246 precomputed_digest_string: Option<String>,
2247 mask: &FieldMaskTree,
2248) {
2249 if mask.contains(Transaction::BCS_FIELD.name) {
2250 let mut bcs = Bcs::serialize(&source).unwrap();
2251 bcs.name = Some("TransactionData".to_owned());
2252 message.bcs = Some(bcs);
2253 }
2254
2255 if mask.contains(Transaction::DIGEST_FIELD.name) {
2256 message.digest =
2257 Some(precomputed_digest_string.unwrap_or_else(|| source.digest().base58_encode()));
2258 }
2259
2260 if mask.contains(Transaction::VERSION_FIELD.name) {
2261 message.version = Some(1);
2262 }
2263
2264 let crate::transaction::TransactionData::V1(source) = source;
2265
2266 if mask.contains(Transaction::KIND_FIELD.name) {
2267 message.kind = Some(source.kind.clone().into());
2268 }
2269
2270 if mask.contains(Transaction::SENDER_FIELD.name) {
2271 message.sender = Some(source.sender.to_string());
2272 }
2273
2274 if mask.contains(Transaction::GAS_PAYMENT_FIELD.name) {
2275 message.gas_payment = Some((&source.gas_data).into());
2276 }
2277
2278 if mask.contains(Transaction::EXPIRATION_FIELD.name) {
2279 message.expiration = Some(source.expiration.clone().into());
2280 }
2281}
2282
2283impl From<&crate::transaction::GasData> for GasPayment {
2288 fn from(value: &crate::transaction::GasData) -> Self {
2289 let mut message = Self::default();
2290 message.objects = value
2291 .payment
2292 .iter()
2293 .map(|obj_ref| obj_ref.to_proto())
2294 .collect();
2295 message.owner = Some(value.owner.to_string());
2296 message.price = Some(value.price);
2297 message.budget = Some(value.budget);
2298 message
2299 }
2300}
2301
2302impl From<crate::transaction::TransactionExpiration> for TransactionExpiration {
2307 fn from(value: crate::transaction::TransactionExpiration) -> Self {
2308 use crate::transaction::TransactionExpiration as E;
2309 use transaction_expiration::TransactionExpirationKind;
2310
2311 let mut message = Self::default();
2312
2313 let kind = match value {
2314 E::None => TransactionExpirationKind::None,
2315 E::Epoch(epoch) => {
2316 message.epoch = Some(epoch);
2317 TransactionExpirationKind::Epoch
2318 }
2319 E::ValidDuring {
2320 min_epoch,
2321 max_epoch,
2322 min_timestamp,
2323 max_timestamp,
2324 chain,
2325 nonce,
2326 } => {
2327 message.epoch = max_epoch;
2328 message.min_epoch = min_epoch;
2329 message.min_timestamp = min_timestamp.map(ms_to_timestamp);
2330 message.max_timestamp = max_timestamp.map(ms_to_timestamp);
2331 message.set_chain(sui_sdk_types::Digest::new(*chain.as_bytes()));
2332 message.set_nonce(nonce);
2333
2334 TransactionExpirationKind::ValidDuring
2335 }
2336 E::Validity {
2337 min_epoch,
2338 max_epoch,
2339 min_timestamp,
2340 max_timestamp,
2341 chain,
2342 nonce,
2343 allowed_proposers,
2344 } => {
2345 message.epoch = max_epoch;
2346 message.min_epoch = min_epoch;
2347 message.min_timestamp = min_timestamp.map(ms_to_timestamp);
2348 message.max_timestamp = max_timestamp.map(ms_to_timestamp);
2349 message.set_chain(sui_sdk_types::Digest::new(*chain.as_bytes()));
2350 message.set_nonce(nonce);
2351 if let Some(allowed) = allowed_proposers {
2352 let mut proposers = AllowedProposers::default();
2353 proposers.set_epoch(allowed.epoch);
2354 proposers.proposers = allowed.proposers.into();
2355 message.set_allowed_proposers(proposers);
2356 }
2357
2358 TransactionExpirationKind::Validity
2359 }
2360 };
2361
2362 message.set_kind(kind);
2363 message
2364 }
2365}
2366
2367impl TryFrom<&TransactionExpiration> for crate::transaction::TransactionExpiration {
2368 type Error = &'static str;
2369
2370 fn try_from(value: &TransactionExpiration) -> Result<Self, Self::Error> {
2371 use transaction_expiration::TransactionExpirationKind;
2372
2373 Ok(match value.kind() {
2374 TransactionExpirationKind::None => Self::None,
2375 TransactionExpirationKind::Epoch => Self::Epoch(value.epoch()),
2376 kind @ (TransactionExpirationKind::ValidDuring
2377 | TransactionExpirationKind::Validity) => {
2378 let chain_str = value
2379 .chain
2380 .as_deref()
2381 .ok_or("ValidDuring expiration is missing chain")?;
2382 let chain_digest: sui_sdk_types::Digest = chain_str
2383 .parse()
2384 .map_err(|_| "ValidDuring expiration has invalid chain digest")?;
2385 let chain = crate::digests::ChainIdentifier::from(
2386 crate::digests::CheckpointDigest::new(chain_digest.into_inner()),
2387 );
2388 let nonce = value
2389 .nonce
2390 .ok_or("ValidDuring expiration is missing nonce")?;
2391 let min_timestamp = value
2392 .min_timestamp
2393 .as_ref()
2394 .map(timestamp_to_ms)
2395 .transpose()?;
2396 let max_timestamp = value
2397 .max_timestamp
2398 .as_ref()
2399 .map(timestamp_to_ms)
2400 .transpose()?;
2401 let min_epoch = value.min_epoch;
2402 let max_epoch = value.epoch;
2403
2404 if kind == TransactionExpirationKind::ValidDuring {
2405 Self::ValidDuring {
2406 min_epoch,
2407 max_epoch,
2408 min_timestamp,
2409 max_timestamp,
2410 chain,
2411 nonce,
2412 }
2413 } else {
2414 let allowed_proposers = value
2415 .allowed_proposers
2416 .as_ref()
2417 .map(|allowed| -> Result<_, Self::Error> {
2418 Ok(crate::transaction::AllowedProposers {
2419 epoch: allowed.epoch(),
2420 proposers: NonEmpty::from_vec(allowed.proposers.clone())
2421 .ok_or("allowed_proposers must not be empty")?,
2422 })
2423 })
2424 .transpose()?;
2425 Self::Validity {
2426 min_epoch,
2427 max_epoch,
2428 min_timestamp,
2429 max_timestamp,
2430 chain,
2431 nonce,
2432 allowed_proposers,
2433 }
2434 }
2435 }
2436 TransactionExpirationKind::Unknown | _ => {
2437 return Err("unknown TransactionExpirationKind");
2438 }
2439 })
2440 }
2441}
2442
2443impl From<crate::transaction::TransactionKind> for TransactionKind {
2448 fn from(value: crate::transaction::TransactionKind) -> Self {
2449 use crate::transaction::TransactionKind as K;
2450 use transaction_kind::Kind;
2451
2452 let message = Self::default();
2453
2454 match value {
2455 K::ProgrammableTransaction(ptb) => message
2456 .with_programmable_transaction(ptb)
2457 .with_kind(Kind::ProgrammableTransaction),
2458 K::ChangeEpoch(change_epoch) => message
2459 .with_change_epoch(change_epoch)
2460 .with_kind(Kind::ChangeEpoch),
2461 K::Genesis(genesis) => message.with_genesis(genesis).with_kind(Kind::Genesis),
2462 K::ConsensusCommitPrologue(prologue) => message
2463 .with_consensus_commit_prologue(prologue)
2464 .with_kind(Kind::ConsensusCommitPrologueV1),
2465 K::AuthenticatorStateUpdate(update) => message
2466 .with_authenticator_state_update(update)
2467 .with_kind(Kind::AuthenticatorStateUpdate),
2468 K::EndOfEpochTransaction(transactions) => message
2469 .with_end_of_epoch({
2470 EndOfEpochTransaction::default()
2471 .with_transactions(transactions.into_iter().map(Into::into).collect())
2472 })
2473 .with_kind(Kind::EndOfEpoch),
2474 K::RandomnessStateUpdate(update) => message
2475 .with_randomness_state_update(update)
2476 .with_kind(Kind::RandomnessStateUpdate),
2477 K::ConsensusCommitPrologueV2(prologue) => message
2478 .with_consensus_commit_prologue(prologue)
2479 .with_kind(Kind::ConsensusCommitPrologueV2),
2480 K::ConsensusCommitPrologueV3(prologue) => message
2481 .with_consensus_commit_prologue(prologue)
2482 .with_kind(Kind::ConsensusCommitPrologueV3),
2483 K::ConsensusCommitPrologueV4(prologue) => message
2484 .with_consensus_commit_prologue(prologue)
2485 .with_kind(Kind::ConsensusCommitPrologueV4),
2486 K::ProgrammableSystemTransaction(ptb) => message
2487 .with_programmable_transaction(ptb)
2488 .with_kind(Kind::ProgrammableSystemTransaction),
2489 }
2490 }
2491}
2492
2493impl From<crate::messages_consensus::ConsensusCommitPrologue> for ConsensusCommitPrologue {
2498 fn from(value: crate::messages_consensus::ConsensusCommitPrologue) -> Self {
2499 let mut message = Self::default();
2500 message.epoch = Some(value.epoch);
2501 message.round = Some(value.round);
2502 message.commit_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(
2503 value.commit_timestamp_ms,
2504 ));
2505 message
2506 }
2507}
2508
2509impl From<crate::messages_consensus::ConsensusCommitPrologueV2> for ConsensusCommitPrologue {
2510 fn from(value: crate::messages_consensus::ConsensusCommitPrologueV2) -> Self {
2511 let mut message = Self::default();
2512 message.epoch = Some(value.epoch);
2513 message.round = Some(value.round);
2514 message.commit_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(
2515 value.commit_timestamp_ms,
2516 ));
2517 message.consensus_commit_digest = Some(value.consensus_commit_digest.to_string());
2518 message
2519 }
2520}
2521
2522impl From<crate::messages_consensus::ConsensusCommitPrologueV3> for ConsensusCommitPrologue {
2523 fn from(value: crate::messages_consensus::ConsensusCommitPrologueV3) -> Self {
2524 let mut message = Self::default();
2525 message.epoch = Some(value.epoch);
2526 message.round = Some(value.round);
2527 message.commit_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(
2528 value.commit_timestamp_ms,
2529 ));
2530 message.consensus_commit_digest = Some(value.consensus_commit_digest.to_string());
2531 message.sub_dag_index = value.sub_dag_index;
2532 message.consensus_determined_version_assignments =
2533 Some(value.consensus_determined_version_assignments.into());
2534 message
2535 }
2536}
2537
2538impl From<crate::messages_consensus::ConsensusCommitPrologueV4> for ConsensusCommitPrologue {
2539 fn from(
2540 crate::messages_consensus::ConsensusCommitPrologueV4 {
2541 epoch,
2542 round,
2543 sub_dag_index,
2544 commit_timestamp_ms,
2545 consensus_commit_digest,
2546 consensus_determined_version_assignments,
2547 additional_state_digest,
2548 }: crate::messages_consensus::ConsensusCommitPrologueV4,
2549 ) -> Self {
2550 let mut message = Self::default();
2551 message.epoch = Some(epoch);
2552 message.round = Some(round);
2553 message.commit_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(commit_timestamp_ms));
2554 message.consensus_commit_digest = Some(consensus_commit_digest.to_string());
2555 message.sub_dag_index = sub_dag_index;
2556 message.consensus_determined_version_assignments =
2557 Some(consensus_determined_version_assignments.into());
2558 message.additional_state_digest = Some(additional_state_digest.to_string());
2559 message
2560 }
2561}
2562
2563impl From<crate::messages_consensus::ConsensusDeterminedVersionAssignments>
2568 for ConsensusDeterminedVersionAssignments
2569{
2570 fn from(value: crate::messages_consensus::ConsensusDeterminedVersionAssignments) -> Self {
2571 use crate::messages_consensus::ConsensusDeterminedVersionAssignments as A;
2572
2573 let mut message = Self::default();
2574
2575 let version = match value {
2576 A::CancelledTransactions(canceled_transactions) => {
2577 message.canceled_transactions = canceled_transactions
2578 .into_iter()
2579 .map(|(tx_digest, assignments)| {
2580 let mut message = CanceledTransaction::default();
2581 message.digest = Some(tx_digest.to_string());
2582 message.version_assignments = assignments
2583 .into_iter()
2584 .map(|(id, version)| {
2585 let mut message = VersionAssignment::default();
2586 message.object_id = Some(id.to_canonical_string(true));
2587 message.version = Some(version.value());
2588 message
2589 })
2590 .collect();
2591 message
2592 })
2593 .collect();
2594 1
2595 }
2596 A::CancelledTransactionsV2(canceled_transactions) => {
2597 message.canceled_transactions = canceled_transactions
2598 .into_iter()
2599 .map(|(tx_digest, assignments)| {
2600 let mut message = CanceledTransaction::default();
2601 message.digest = Some(tx_digest.to_string());
2602 message.version_assignments = assignments
2603 .into_iter()
2604 .map(|((id, start_version), version)| {
2605 let mut message = VersionAssignment::default();
2606 message.object_id = Some(id.to_canonical_string(true));
2607 message.start_version = Some(start_version.value());
2608 message.version = Some(version.value());
2609 message
2610 })
2611 .collect();
2612 message
2613 })
2614 .collect();
2615 2
2616 }
2617 };
2618
2619 message.version = Some(version);
2620 message
2621 }
2622}
2623
2624impl From<crate::transaction::GenesisTransaction> for GenesisTransaction {
2629 fn from(value: crate::transaction::GenesisTransaction) -> Self {
2630 let mut message = Self::default();
2631 message.objects = value.objects.into_iter().map(Into::into).collect();
2632 message
2633 }
2634}
2635
2636impl From<crate::transaction::RandomnessStateUpdate> for RandomnessStateUpdate {
2641 fn from(value: crate::transaction::RandomnessStateUpdate) -> Self {
2642 let mut message = Self::default();
2643 message.epoch = Some(value.epoch);
2644 message.randomness_round = Some(value.randomness_round.0);
2645 message.random_bytes = Some(value.random_bytes.into());
2646 message.randomness_object_initial_shared_version =
2647 Some(value.randomness_obj_initial_shared_version.value());
2648 message
2649 }
2650}
2651
2652impl From<crate::transaction::AuthenticatorStateUpdate> for AuthenticatorStateUpdate {
2657 fn from(value: crate::transaction::AuthenticatorStateUpdate) -> Self {
2658 let mut message = Self::default();
2659 message.epoch = Some(value.epoch);
2660 message.round = Some(value.round);
2661 message.new_active_jwks = value.new_active_jwks.into_iter().map(Into::into).collect();
2662 message.authenticator_object_initial_shared_version =
2663 Some(value.authenticator_obj_initial_shared_version.value());
2664 message
2665 }
2666}
2667
2668impl From<crate::authenticator_state::ActiveJwk> for ActiveJwk {
2673 fn from(value: crate::authenticator_state::ActiveJwk) -> Self {
2674 let mut jwk_id = JwkId::default();
2675 jwk_id.iss = Some(value.jwk_id.iss);
2676 jwk_id.kid = Some(value.jwk_id.kid);
2677
2678 let mut jwk = Jwk::default();
2679 jwk.kty = Some(value.jwk.kty);
2680 jwk.e = Some(value.jwk.e);
2681 jwk.n = Some(value.jwk.n);
2682 jwk.alg = Some(value.jwk.alg);
2683
2684 let mut message = Self::default();
2685 message.id = Some(jwk_id);
2686 message.jwk = Some(jwk);
2687 message.epoch = Some(value.epoch);
2688 message
2689 }
2690}
2691
2692impl From<crate::transaction::ChangeEpoch> for ChangeEpoch {
2697 fn from(value: crate::transaction::ChangeEpoch) -> Self {
2698 let mut message = Self::default();
2699 message.epoch = Some(value.epoch);
2700 message.protocol_version = Some(value.protocol_version.as_u64());
2701 message.storage_charge = Some(value.storage_charge);
2702 message.computation_charge = Some(value.computation_charge);
2703 message.storage_rebate = Some(value.storage_rebate);
2704 message.non_refundable_storage_fee = Some(value.non_refundable_storage_fee);
2705 message.epoch_start_timestamp = Some(sui_rpc::proto::timestamp_ms_to_proto(
2706 value.epoch_start_timestamp_ms,
2707 ));
2708 message.system_packages = value
2709 .system_packages
2710 .into_iter()
2711 .map(|(version, modules, dependencies)| {
2712 let mut message = SystemPackage::default();
2713 message.version = Some(version.value());
2714 message.modules = modules.into_iter().map(Into::into).collect();
2715 message.dependencies = dependencies
2716 .iter()
2717 .map(|d| d.to_canonical_string(true))
2718 .collect();
2719 message
2720 })
2721 .collect();
2722 message
2723 }
2724}
2725
2726impl From<crate::transaction::EndOfEpochTransactionKind> for EndOfEpochTransactionKind {
2731 fn from(value: crate::transaction::EndOfEpochTransactionKind) -> Self {
2732 use crate::transaction::EndOfEpochTransactionKind as K;
2733 use end_of_epoch_transaction_kind::Kind;
2734
2735 let message = Self::default();
2736
2737 match value {
2738 K::ChangeEpoch(change_epoch) => message
2739 .with_change_epoch(change_epoch)
2740 .with_kind(Kind::ChangeEpoch),
2741 K::AuthenticatorStateCreate => message.with_kind(Kind::AuthenticatorStateCreate),
2742 K::AuthenticatorStateExpire(expire) => message
2743 .with_authenticator_state_expire(expire)
2744 .with_kind(Kind::AuthenticatorStateExpire),
2745 K::RandomnessStateCreate => message.with_kind(Kind::RandomnessStateCreate),
2746 K::DenyListStateCreate => message.with_kind(Kind::DenyListStateCreate),
2747 K::BridgeStateCreate(chain_id) => message
2748 .with_bridge_chain_id(chain_id.to_string())
2749 .with_kind(Kind::BridgeStateCreate),
2750 K::BridgeCommitteeInit(bridge_object_version) => message
2751 .with_bridge_object_version(bridge_object_version.into())
2752 .with_kind(Kind::BridgeCommitteeInit),
2753 K::StoreExecutionTimeObservations(observations) => message
2754 .with_execution_time_observations(observations)
2755 .with_kind(Kind::StoreExecutionTimeObservations),
2756 K::AccumulatorRootCreate => message.with_kind(Kind::AccumulatorRootCreate),
2757 K::CoinRegistryCreate => message.with_kind(Kind::CoinRegistryCreate),
2758 K::DisplayRegistryCreate => message.with_kind(Kind::DisplayRegistryCreate),
2759 K::AddressAliasStateCreate => message.with_kind(Kind::AddressAliasStateCreate),
2760 K::ForwardingAddressRegistryCreate => {
2761 message.with_kind(Kind::ForwardingAddressRegistryCreate)
2762 }
2763 K::WriteAccumulatorStorageCost(storage_cost) => message
2764 .with_kind(Kind::WriteAccumulatorStorageCost)
2765 .with_storage_cost(storage_cost.storage_cost),
2766 }
2767 }
2768}
2769
2770impl From<crate::transaction::AuthenticatorStateExpire> for AuthenticatorStateExpire {
2775 fn from(value: crate::transaction::AuthenticatorStateExpire) -> Self {
2776 let mut message = Self::default();
2777 message.min_epoch = Some(value.min_epoch);
2778 message.authenticator_object_initial_shared_version =
2779 Some(value.authenticator_obj_initial_shared_version.value());
2780 message
2781 }
2782}
2783
2784impl From<crate::transaction::StoredExecutionTimeObservations> for ExecutionTimeObservations {
2787 fn from(value: crate::transaction::StoredExecutionTimeObservations) -> Self {
2788 let mut message = Self::default();
2789 match value {
2790 crate::transaction::StoredExecutionTimeObservations::V1(vec) => {
2791 message.version = Some(1);
2792 message.observations = vec
2793 .into_iter()
2794 .map(|(key, observation)| {
2795 use crate::execution::ExecutionTimeObservationKey as K;
2796 use execution_time_observation::ExecutionTimeObservationKind;
2797
2798 let mut message = ExecutionTimeObservation::default();
2799
2800 let kind = match key {
2801 K::MoveEntryPoint {
2802 package,
2803 module,
2804 function,
2805 type_arguments,
2806 } => {
2807 message.move_entry_point = Some({
2808 let mut message = MoveCall::default();
2809 message.package = Some(package.to_canonical_string(true));
2810 message.module = Some(module);
2811 message.function = Some(function);
2812 message.type_arguments = type_arguments
2813 .into_iter()
2814 .map(|ty| ty.to_canonical_string(true))
2815 .collect();
2816 message
2817 });
2818 ExecutionTimeObservationKind::MoveEntryPoint
2819 }
2820 K::TransferObjects => ExecutionTimeObservationKind::TransferObjects,
2821 K::SplitCoins => ExecutionTimeObservationKind::SplitCoins,
2822 K::MergeCoins => ExecutionTimeObservationKind::MergeCoins,
2823 K::Publish => ExecutionTimeObservationKind::Publish,
2824 K::MakeMoveVec => ExecutionTimeObservationKind::MakeMoveVector,
2825 K::Upgrade => ExecutionTimeObservationKind::Upgrade,
2826 };
2827
2828 message.validator_observations = observation
2829 .into_iter()
2830 .map(|(name, duration)| {
2831 let mut message = ValidatorExecutionTimeObservation::default();
2832 message.validator = Some(name.0.to_vec().into());
2833 message.duration = Some(prost_types::Duration {
2834 seconds: duration.as_secs() as i64,
2835 nanos: duration.subsec_nanos() as i32,
2836 });
2837 message
2838 })
2839 .collect();
2840
2841 message.set_kind(kind);
2842 message
2843 })
2844 .collect();
2845 }
2846 }
2847
2848 message
2849 }
2850}
2851
2852impl From<crate::transaction::ProgrammableTransaction> for ProgrammableTransaction {
2857 fn from(value: crate::transaction::ProgrammableTransaction) -> Self {
2858 let mut message = Self::default();
2859 message.inputs = value.inputs.into_iter().map(Into::into).collect();
2860 message.commands = value.commands.into_iter().map(Into::into).collect();
2861 message
2862 }
2863}
2864
2865impl From<crate::transaction::CallArg> for Input {
2870 fn from(value: crate::transaction::CallArg) -> Self {
2871 use crate::transaction::CallArg as I;
2872 use crate::transaction::ObjectArg as O;
2873 use input::InputKind;
2874 use input::Mutability;
2875
2876 let mut message = Self::default();
2877
2878 let kind = match value {
2879 I::Pure(value) => {
2880 message.pure = Some(value.into());
2881 InputKind::Pure
2882 }
2883 I::Object(o) => match o {
2884 O::ImmOrOwnedObject((id, version, digest)) => {
2885 message.object_id = Some(id.to_canonical_string(true));
2886 message.version = Some(version.value());
2887 message.digest = Some(digest.to_string());
2888 InputKind::ImmutableOrOwned
2889 }
2890 O::SharedObject {
2891 id,
2892 initial_shared_version,
2893 mutability,
2894 } => {
2895 message.object_id = Some(id.to_canonical_string(true));
2896 message.version = Some(initial_shared_version.value());
2897 message.mutable = Some(mutability.is_exclusive());
2898 message.set_mutability(match mutability {
2899 crate::transaction::SharedObjectMutability::Immutable => {
2900 Mutability::Immutable
2901 }
2902 crate::transaction::SharedObjectMutability::Mutable => Mutability::Mutable,
2903 crate::transaction::SharedObjectMutability::NonExclusiveWrite => {
2904 Mutability::NonExclusiveWrite
2905 }
2906 });
2907 InputKind::Shared
2908 }
2909 O::Receiving((id, version, digest)) => {
2910 message.object_id = Some(id.to_canonical_string(true));
2911 message.version = Some(version.value());
2912 message.digest = Some(digest.to_string());
2913 InputKind::Receiving
2914 }
2915 },
2916 I::FundsWithdrawal(withdrawal) => {
2917 message.set_funds_withdrawal(withdrawal);
2918 InputKind::FundsWithdrawal
2919 }
2920 };
2921
2922 message.set_kind(kind);
2923 message
2924 }
2925}
2926
2927impl From<crate::transaction::FundsWithdrawalArg> for FundsWithdrawal {
2928 fn from(value: crate::transaction::FundsWithdrawalArg) -> Self {
2929 use funds_withdrawal::Source;
2930
2931 let mut message = Self::default();
2932
2933 message.amount = match value.reservation {
2934 crate::transaction::Reservation::MaxAmountU64(amount) => Some(amount),
2935 };
2936 let crate::transaction::WithdrawalTypeArg::Balance(coin_type) = value.type_arg;
2937 message.coin_type = Some(coin_type.to_canonical_string(true));
2938 let source = match value.withdraw_from {
2939 crate::transaction::WithdrawFrom::Sender => Source::Sender,
2940 crate::transaction::WithdrawFrom::Sponsor => Source::Sponsor,
2941 crate::transaction::WithdrawFrom::SenderAllowance { funder, allowance } => {
2942 message.funder = Some(funder.to_string());
2943 message.allowance = Some(allowance.to_string());
2944 Source::SenderAllowance
2945 }
2946 };
2947 message.set_source(source);
2948
2949 message
2950 }
2951}
2952
2953impl From<crate::transaction::Argument> for Argument {
2958 fn from(value: crate::transaction::Argument) -> Self {
2959 use crate::transaction::Argument as A;
2960 use argument::ArgumentKind;
2961
2962 let mut message = Self::default();
2963
2964 let kind = match value {
2965 A::GasCoin => ArgumentKind::Gas,
2966 A::Input(input) => {
2967 message.input = Some(input.into());
2968 ArgumentKind::Input
2969 }
2970 A::Result(result) => {
2971 message.result = Some(result.into());
2972 ArgumentKind::Result
2973 }
2974 A::NestedResult(result, subresult) => {
2975 message.result = Some(result.into());
2976 message.subresult = Some(subresult.into());
2977 ArgumentKind::Result
2978 }
2979 };
2980
2981 message.set_kind(kind);
2982 message
2983 }
2984}
2985
2986impl From<crate::transaction::Command> for Command {
2991 fn from(value: crate::transaction::Command) -> Self {
2992 use crate::transaction::Command as C;
2993 use command::Command;
2994
2995 let command = match value {
2996 C::MoveCall(move_call) => Command::MoveCall((*move_call).into()),
2997 C::TransferObjects(objects, address) => Command::TransferObjects({
2998 let mut message = TransferObjects::default();
2999 message.objects = objects.into_iter().map(Into::into).collect();
3000 message.address = Some(address.into());
3001 message
3002 }),
3003 C::SplitCoins(coin, amounts) => Command::SplitCoins({
3004 let mut message = SplitCoins::default();
3005 message.coin = Some(coin.into());
3006 message.amounts = amounts.into_iter().map(Into::into).collect();
3007 message
3008 }),
3009 C::MergeCoins(coin, coins_to_merge) => Command::MergeCoins({
3010 let mut message = MergeCoins::default();
3011 message.coin = Some(coin.into());
3012 message.coins_to_merge = coins_to_merge.into_iter().map(Into::into).collect();
3013 message
3014 }),
3015 C::Publish(modules, dependencies) => Command::Publish({
3016 let mut message = Publish::default();
3017 message.modules = modules.into_iter().map(Into::into).collect();
3018 message.dependencies = dependencies
3019 .iter()
3020 .map(|d| d.to_canonical_string(true))
3021 .collect();
3022 message
3023 }),
3024 C::MakeMoveVec(element_type, elements) => Command::MakeMoveVector({
3025 let mut message = MakeMoveVector::default();
3026 message.element_type = element_type.map(|t| t.to_canonical_string(true));
3027 message.elements = elements.into_iter().map(Into::into).collect();
3028 message
3029 }),
3030 C::Upgrade(modules, dependencies, package, ticket) => Command::Upgrade({
3031 let mut message = Upgrade::default();
3032 message.modules = modules.into_iter().map(Into::into).collect();
3033 message.dependencies = dependencies
3034 .iter()
3035 .map(|d| d.to_canonical_string(true))
3036 .collect();
3037 message.package = Some(package.to_canonical_string(true));
3038 message.ticket = Some(ticket.into());
3039 message
3040 }),
3041 };
3042
3043 let mut message = Self::default();
3044 message.command = Some(command);
3045 message
3046 }
3047}
3048
3049impl From<crate::transaction::ProgrammableMoveCall> for MoveCall {
3054 fn from(value: crate::transaction::ProgrammableMoveCall) -> Self {
3055 let mut message = Self::default();
3056 message.package = Some(value.package.to_canonical_string(true));
3057 message.module = Some(value.module.to_string());
3058 message.function = Some(value.function.to_string());
3059 message.type_arguments = value
3060 .type_arguments
3061 .iter()
3062 .map(|t| t.to_canonical_string(true))
3063 .collect();
3064 message.arguments = value.arguments.into_iter().map(Into::into).collect();
3065 message
3066 }
3067}
3068
3069impl From<crate::effects::TransactionEffects> for TransactionEffects {
3074 fn from(value: crate::effects::TransactionEffects) -> Self {
3075 Self::merge_from(&value, &FieldMaskTree::new_wildcard())
3076 }
3077}
3078
3079impl Merge<&crate::effects::TransactionEffects> for TransactionEffects {
3080 fn merge(&mut self, source: &crate::effects::TransactionEffects, mask: &FieldMaskTree) {
3081 if mask.contains(Self::BCS_FIELD.name) {
3082 let mut bcs = Bcs::serialize(&source).unwrap();
3083 bcs.name = Some("TransactionEffects".to_owned());
3084 self.bcs = Some(bcs);
3085 }
3086
3087 if mask.contains(Self::DIGEST_FIELD.name) {
3088 self.digest = Some(source.digest().to_string());
3089 }
3090
3091 match source {
3092 crate::effects::TransactionEffects::V1(v1) => self.merge(v1, mask),
3093 crate::effects::TransactionEffects::V2(v2) => self.merge(v2, mask),
3094 }
3095 }
3096}
3097
3098impl Merge<&crate::effects::TransactionEffectsV1> for TransactionEffects {
3103 fn merge(&mut self, value: &crate::effects::TransactionEffectsV1, mask: &FieldMaskTree) {
3104 use crate::effects::TransactionEffectsAPI;
3105
3106 if mask.contains(Self::VERSION_FIELD.name) {
3107 self.version = Some(1);
3108 }
3109
3110 if mask.contains(Self::STATUS_FIELD.name) {
3111 self.status = Some(value.status().clone().into());
3112 }
3113
3114 if mask.contains(Self::EPOCH_FIELD.name) {
3115 self.epoch = Some(value.executed_epoch());
3116 }
3117
3118 if mask.contains(Self::GAS_USED_FIELD.name) {
3119 self.gas_used = Some(value.gas_cost_summary().clone().into());
3120 }
3121
3122 if mask.contains(Self::TRANSACTION_DIGEST_FIELD.name) {
3123 self.transaction_digest = Some(value.transaction_digest().to_string());
3124 }
3125
3126 if mask.contains(Self::EVENTS_DIGEST_FIELD.name) {
3127 self.events_digest = value.events_digest().map(|d| d.to_string());
3128 }
3129
3130 if mask.contains(Self::DEPENDENCIES_FIELD.name) {
3131 self.dependencies = value
3132 .dependencies()
3133 .iter()
3134 .map(ToString::to_string)
3135 .collect();
3136 }
3137
3138 if mask.contains(Self::LAMPORT_VERSION_FIELD.name) {
3139 self.lamport_version = Some(value.lamport_version().value());
3140 }
3141
3142 if mask.contains(Self::CHANGED_OBJECTS_FIELD.name)
3143 || mask.contains(Self::UNCHANGED_CONSENSUS_OBJECTS_FIELD.name)
3144 || mask.contains(Self::GAS_OBJECT_FIELD.name)
3145 {
3146 let mut changed_objects = Vec::new();
3147 let mut unchanged_consensus_objects = Vec::new();
3148
3149 for ((id, version, digest), owner) in value.created() {
3150 let mut change = ChangedObject::default();
3151 change.object_id = Some(id.to_canonical_string(true));
3152 change.input_state = Some(changed_object::InputObjectState::DoesNotExist.into());
3153 change.output_state = Some(changed_object::OutputObjectState::ObjectWrite.into());
3154 change.output_version = Some(version.value());
3155 change.output_digest = Some(digest.to_string());
3156 change.output_owner = Some(owner.clone().into());
3157 change.id_operation = Some(changed_object::IdOperation::Created.into());
3158
3159 changed_objects.push(change);
3160 }
3161
3162 for ((id, version, digest), owner) in value.mutated() {
3163 let mut change = ChangedObject::default();
3164 change.object_id = Some(id.to_canonical_string(true));
3165 change.input_state = Some(changed_object::InputObjectState::Exists.into());
3166 change.output_state = Some(changed_object::OutputObjectState::ObjectWrite.into());
3167 change.output_version = Some(version.value());
3168 change.output_digest = Some(digest.to_string());
3169 change.output_owner = Some(owner.clone().into());
3170 change.id_operation = Some(changed_object::IdOperation::None.into());
3171
3172 changed_objects.push(change);
3173 }
3174
3175 for ((id, version, digest), owner) in value.unwrapped() {
3176 let mut change = ChangedObject::default();
3177 change.object_id = Some(id.to_canonical_string(true));
3178 change.input_state = Some(changed_object::InputObjectState::DoesNotExist.into());
3179 change.output_state = Some(changed_object::OutputObjectState::ObjectWrite.into());
3180 change.output_version = Some(version.value());
3181 change.output_digest = Some(digest.to_string());
3182 change.output_owner = Some(owner.clone().into());
3183 change.id_operation = Some(changed_object::IdOperation::None.into());
3184
3185 changed_objects.push(change);
3186 }
3187
3188 for (id, version, digest) in value.deleted() {
3189 let mut change = ChangedObject::default();
3190 change.object_id = Some(id.to_canonical_string(true));
3191 change.input_state = Some(changed_object::InputObjectState::Exists.into());
3192 change.output_state = Some(changed_object::OutputObjectState::DoesNotExist.into());
3193 change.output_version = Some(version.value());
3194 change.output_digest = Some(digest.to_string());
3195 change.id_operation = Some(changed_object::IdOperation::Deleted.into());
3196
3197 changed_objects.push(change);
3198 }
3199
3200 for (id, version, digest) in value.unwrapped_then_deleted() {
3201 let mut change = ChangedObject::default();
3202 change.object_id = Some(id.to_canonical_string(true));
3203 change.input_state = Some(changed_object::InputObjectState::DoesNotExist.into());
3204 change.output_state = Some(changed_object::OutputObjectState::DoesNotExist.into());
3205 change.output_version = Some(version.value());
3206 change.output_digest = Some(digest.to_string());
3207 change.id_operation = Some(changed_object::IdOperation::Deleted.into());
3208
3209 changed_objects.push(change);
3210 }
3211
3212 for (id, version, digest) in value.wrapped() {
3213 let mut change = ChangedObject::default();
3214 change.object_id = Some(id.to_canonical_string(true));
3215 change.input_state = Some(changed_object::InputObjectState::Exists.into());
3216 change.output_state = Some(changed_object::OutputObjectState::DoesNotExist.into());
3217 change.output_version = Some(version.value());
3218 change.output_digest = Some(digest.to_string());
3219 change.id_operation = Some(changed_object::IdOperation::Deleted.into());
3220
3221 changed_objects.push(change);
3222 }
3223
3224 for (object_id, version) in value.modified_at_versions() {
3225 let object_id = object_id.to_canonical_string(true);
3226 let version = version.value();
3227 if let Some(changed_object) = changed_objects
3228 .iter_mut()
3229 .find(|object| object.object_id() == object_id)
3230 {
3231 changed_object.input_version = Some(version);
3232 }
3233 }
3234
3235 for (id, version, digest) in value.shared_objects() {
3236 let object_id = id.to_canonical_string(true);
3237 let version = version.value();
3238 let digest = digest.to_string();
3239
3240 if let Some(changed_object) = changed_objects
3241 .iter_mut()
3242 .find(|object| object.object_id() == object_id)
3243 {
3244 changed_object.input_version = Some(version);
3245 changed_object.input_digest = Some(digest);
3246 } else {
3247 let mut unchanged_consensus_object = UnchangedConsensusObject::default();
3248 unchanged_consensus_object.kind = Some(
3249 unchanged_consensus_object::UnchangedConsensusObjectKind::ReadOnlyRoot
3250 .into(),
3251 );
3252 unchanged_consensus_object.object_id = Some(object_id);
3253 unchanged_consensus_object.version = Some(version);
3254 unchanged_consensus_object.digest = Some(digest);
3255
3256 unchanged_consensus_objects.push(unchanged_consensus_object);
3257 }
3258 }
3259
3260 if mask.contains(Self::GAS_OBJECT_FIELD.name)
3261 && let Some(((gas_id, _, _), _)) = value.gas_object()
3262 {
3263 let gas_object_id = gas_id.to_canonical_string(true);
3264 self.gas_object = changed_objects
3265 .iter()
3266 .find(|object| object.object_id() == gas_object_id)
3267 .cloned();
3268 }
3269
3270 if mask.contains(Self::CHANGED_OBJECTS_FIELD.name) {
3271 self.changed_objects = changed_objects;
3272 }
3273
3274 if mask.contains(Self::UNCHANGED_CONSENSUS_OBJECTS_FIELD.name) {
3275 self.unchanged_consensus_objects = unchanged_consensus_objects;
3276 }
3277 }
3278 }
3279}
3280
3281impl Merge<&crate::effects::TransactionEffectsV2> for TransactionEffects {
3286 fn merge(
3287 &mut self,
3288 crate::effects::TransactionEffectsV2 {
3289 status,
3290 executed_epoch,
3291 gas_used,
3292 transaction_digest,
3293 gas_object_index,
3294 events_digest,
3295 dependencies,
3296 lamport_version,
3297 changed_objects,
3298 unchanged_consensus_objects,
3299 aux_data_digest,
3300 }: &crate::effects::TransactionEffectsV2,
3301 mask: &FieldMaskTree,
3302 ) {
3303 if mask.contains(Self::VERSION_FIELD.name) {
3304 self.version = Some(2);
3305 }
3306
3307 if mask.contains(Self::STATUS_FIELD.name) {
3308 self.status = Some(status.clone().into());
3309 }
3310
3311 if mask.contains(Self::EPOCH_FIELD.name) {
3312 self.epoch = Some(*executed_epoch);
3313 }
3314
3315 if mask.contains(Self::GAS_USED_FIELD.name) {
3316 self.gas_used = Some(gas_used.clone().into());
3317 }
3318
3319 if mask.contains(Self::TRANSACTION_DIGEST_FIELD.name) {
3320 self.transaction_digest = Some(transaction_digest.to_string());
3321 }
3322
3323 if mask.contains(Self::GAS_OBJECT_FIELD.name) {
3324 self.gas_object = gas_object_index
3325 .map(|index| {
3326 changed_objects
3327 .get(index as usize)
3328 .cloned()
3329 .map(|(id, change)| {
3330 let mut message = ChangedObject::from(change);
3331 message.object_id = Some(id.to_canonical_string(true));
3332 message
3333 })
3334 })
3335 .flatten();
3336 }
3337
3338 if mask.contains(Self::EVENTS_DIGEST_FIELD.name) {
3339 self.events_digest = events_digest.map(|d| d.to_string());
3340 }
3341
3342 if mask.contains(Self::DEPENDENCIES_FIELD.name) {
3343 self.dependencies = dependencies.iter().map(ToString::to_string).collect();
3344 }
3345
3346 if mask.contains(Self::LAMPORT_VERSION_FIELD.name) {
3347 self.lamport_version = Some(lamport_version.value());
3348 }
3349
3350 if mask.contains(Self::CHANGED_OBJECTS_FIELD.name) {
3351 self.changed_objects = changed_objects
3352 .clone()
3353 .into_iter()
3354 .map(|(id, change)| {
3355 let mut message = ChangedObject::from(change);
3356 message.object_id = Some(id.to_canonical_string(true));
3357 message
3358 })
3359 .collect();
3360 }
3361
3362 for object in self.changed_objects.iter_mut().chain(&mut self.gas_object) {
3363 if object.output_digest.is_some() && object.output_version.is_none() {
3364 object.output_version = Some(lamport_version.value());
3365 }
3366 }
3367
3368 if mask.contains(Self::UNCHANGED_CONSENSUS_OBJECTS_FIELD.name) {
3369 self.unchanged_consensus_objects = unchanged_consensus_objects
3370 .clone()
3371 .into_iter()
3372 .map(|(id, unchanged)| {
3373 let mut message = UnchangedConsensusObject::from(unchanged);
3374 message.object_id = Some(id.to_canonical_string(true));
3375 message
3376 })
3377 .collect();
3378 }
3379
3380 if mask.contains(Self::AUXILIARY_DATA_DIGEST_FIELD.name) {
3381 self.auxiliary_data_digest = aux_data_digest.map(|d| d.to_string());
3382 }
3383 }
3384}
3385
3386impl From<crate::effects::EffectsObjectChange> for ChangedObject {
3391 fn from(value: crate::effects::EffectsObjectChange) -> Self {
3392 use crate::effects::ObjectIn;
3393 use crate::effects::ObjectOut;
3394 use changed_object::InputObjectState;
3395 use changed_object::OutputObjectState;
3396
3397 let mut message = Self::default();
3398
3399 let input_state = match value.input_state {
3401 ObjectIn::NotExist => InputObjectState::DoesNotExist,
3402 ObjectIn::Exist(((version, digest), owner)) => {
3403 message.input_version = Some(version.value());
3404 message.input_digest = Some(digest.to_string());
3405 message.input_owner = Some(owner.into());
3406 InputObjectState::Exists
3407 }
3408 };
3409 message.set_input_state(input_state);
3410
3411 let output_state = match value.output_state {
3413 ObjectOut::NotExist => OutputObjectState::DoesNotExist,
3414 ObjectOut::ObjectWrite((digest, owner)) => {
3415 message.output_digest = Some(digest.to_string());
3416 message.output_owner = Some(owner.into());
3417 OutputObjectState::ObjectWrite
3418 }
3419 ObjectOut::PackageWrite((version, digest)) => {
3420 message.output_version = Some(version.value());
3421 message.output_digest = Some(digest.to_string());
3422 OutputObjectState::PackageWrite
3423 }
3424 ObjectOut::AccumulatorWriteV1(accumulator_write) => {
3425 message.set_accumulator_write(accumulator_write);
3426 OutputObjectState::AccumulatorWrite
3427 }
3428 };
3429 message.set_output_state(output_state);
3430
3431 message.set_id_operation(value.id_operation.into());
3432 message
3433 }
3434}
3435
3436impl From<crate::effects::AccumulatorWriteV1> for AccumulatorWrite {
3437 fn from(value: crate::effects::AccumulatorWriteV1) -> Self {
3438 use accumulator_write::AccumulatorOperation;
3439
3440 let mut message = Self::default();
3441
3442 message.set_address(value.address.address.to_string());
3443 message.set_accumulator_type(value.address.ty.to_canonical_string(true));
3444 message.set_operation(match value.operation {
3445 crate::effects::AccumulatorOperation::Merge => AccumulatorOperation::Merge,
3446 crate::effects::AccumulatorOperation::Split => AccumulatorOperation::Split,
3447 });
3448 match value.value {
3449 crate::effects::AccumulatorValue::Integer(value) => message.set_integer_value(value),
3450 crate::effects::AccumulatorValue::IntegerTuple(_, _)
3452 | crate::effects::AccumulatorValue::EventDigest(_) => {}
3453 }
3454
3455 message
3456 }
3457}
3458
3459impl From<crate::effects::IDOperation> for changed_object::IdOperation {
3464 fn from(value: crate::effects::IDOperation) -> Self {
3465 use crate::effects::IDOperation as I;
3466
3467 match value {
3468 I::None => Self::None,
3469 I::Created => Self::Created,
3470 I::Deleted => Self::Deleted,
3471 }
3472 }
3473}
3474
3475impl From<crate::effects::UnchangedConsensusKind> for UnchangedConsensusObject {
3480 fn from(value: crate::effects::UnchangedConsensusKind) -> Self {
3481 use crate::effects::UnchangedConsensusKind as K;
3482 use unchanged_consensus_object::UnchangedConsensusObjectKind;
3483
3484 let mut message = Self::default();
3485
3486 let kind = match value {
3487 K::ReadOnlyRoot((version, digest)) => {
3488 message.version = Some(version.value());
3489 message.digest = Some(digest.to_string());
3490 UnchangedConsensusObjectKind::ReadOnlyRoot
3491 }
3492 K::MutateConsensusStreamEnded(version) => {
3493 message.version = Some(version.value());
3494 UnchangedConsensusObjectKind::MutateConsensusStreamEnded
3495 }
3496 K::ReadConsensusStreamEnded(version) => {
3497 message.version = Some(version.value());
3498 UnchangedConsensusObjectKind::ReadConsensusStreamEnded
3499 }
3500 K::Cancelled(version) => {
3501 message.version = Some(version.value());
3502 UnchangedConsensusObjectKind::Canceled
3503 }
3504 K::PerEpochConfig => UnchangedConsensusObjectKind::PerEpochConfig,
3505 };
3510
3511 message.set_kind(kind);
3512 message
3513 }
3514}
3515
3516impl From<simulate_transaction_request::TransactionChecks>
3521 for crate::transaction_executor::TransactionChecks
3522{
3523 fn from(value: simulate_transaction_request::TransactionChecks) -> Self {
3524 match value {
3525 simulate_transaction_request::TransactionChecks::Enabled => Self::Enabled,
3526 simulate_transaction_request::TransactionChecks::Disabled => Self::Disabled,
3527 _ => Self::Enabled,
3529 }
3530 }
3531}
3532
3533impl From<crate::coin_registry::MetadataCapState> for coin_metadata::MetadataCapState {
3538 fn from(value: crate::coin_registry::MetadataCapState) -> Self {
3539 match value {
3540 crate::coin_registry::MetadataCapState::Claimed(_) => {
3541 coin_metadata::MetadataCapState::Claimed
3542 }
3543 crate::coin_registry::MetadataCapState::Unclaimed => {
3544 coin_metadata::MetadataCapState::Unclaimed
3545 }
3546 crate::coin_registry::MetadataCapState::Deleted => {
3547 coin_metadata::MetadataCapState::Deleted
3548 }
3549 }
3550 }
3551}
3552
3553impl From<&crate::coin_registry::Currency> for CoinMetadata {
3554 fn from(value: &crate::coin_registry::Currency) -> Self {
3555 let mut metadata = CoinMetadata::default();
3556 metadata.id = Some(sui_sdk_types::Address::from(value.id.into_bytes()).to_string());
3557 metadata.decimals = Some(value.decimals.into());
3558 metadata.name = Some(value.name.clone());
3559 metadata.symbol = Some(value.symbol.clone());
3560 metadata.description = Some(value.description.clone());
3561 metadata.icon_url = Some(value.icon_url.clone());
3562
3563 match &value.metadata_cap_id {
3564 crate::coin_registry::MetadataCapState::Claimed(id) => {
3565 metadata.metadata_cap_state = Some(coin_metadata::MetadataCapState::Claimed as i32);
3566 metadata.metadata_cap_id = Some(sui_sdk_types::Address::from(*id).to_string());
3567 }
3568 crate::coin_registry::MetadataCapState::Unclaimed => {
3569 metadata.metadata_cap_state =
3570 Some(coin_metadata::MetadataCapState::Unclaimed as i32);
3571 }
3572 crate::coin_registry::MetadataCapState::Deleted => {
3573 metadata.metadata_cap_state = Some(coin_metadata::MetadataCapState::Deleted as i32);
3574 }
3575 }
3576
3577 metadata
3578 }
3579}
3580
3581impl From<crate::coin::CoinMetadata> for CoinMetadata {
3582 fn from(value: crate::coin::CoinMetadata) -> Self {
3583 let mut metadata = CoinMetadata::default();
3584 metadata.id = Some(sui_sdk_types::Address::from(value.id.id.bytes).to_string());
3585 metadata.decimals = Some(value.decimals.into());
3586 metadata.name = Some(value.name);
3587 metadata.symbol = Some(value.symbol);
3588 metadata.description = Some(value.description);
3589 metadata.icon_url = value.icon_url;
3590 metadata
3591 }
3592}
3593
3594impl From<crate::coin_registry::SupplyState> for coin_treasury::SupplyState {
3595 fn from(value: crate::coin_registry::SupplyState) -> Self {
3596 match value {
3597 crate::coin_registry::SupplyState::Fixed(_) => coin_treasury::SupplyState::Fixed,
3598 crate::coin_registry::SupplyState::BurnOnly(_) => coin_treasury::SupplyState::BurnOnly,
3599 crate::coin_registry::SupplyState::Unknown => coin_treasury::SupplyState::Unknown,
3600 }
3601 }
3602}
3603
3604impl From<crate::coin::TreasuryCap> for CoinTreasury {
3605 fn from(value: crate::coin::TreasuryCap) -> Self {
3606 let mut treasury = CoinTreasury::default();
3607 treasury.id = Some(sui_sdk_types::Address::from(value.id.id.bytes).to_string());
3608 treasury.total_supply = Some(value.total_supply.value);
3609 treasury
3610 }
3611}
3612
3613impl From<&crate::coin_registry::RegulatedState> for RegulatedCoinMetadata {
3614 fn from(value: &crate::coin_registry::RegulatedState) -> Self {
3615 let mut regulated = RegulatedCoinMetadata::default();
3616
3617 match value {
3618 crate::coin_registry::RegulatedState::Regulated {
3619 cap,
3620 allow_global_pause,
3621 variant,
3622 } => {
3623 regulated.deny_cap_object = Some(sui_sdk_types::Address::from(*cap).to_string());
3624 regulated.allow_global_pause = *allow_global_pause;
3625 regulated.variant = Some(*variant as u32);
3626 regulated.coin_regulated_state =
3627 Some(regulated_coin_metadata::CoinRegulatedState::Regulated as i32);
3628 }
3629 crate::coin_registry::RegulatedState::Unregulated => {
3630 regulated.coin_regulated_state =
3631 Some(regulated_coin_metadata::CoinRegulatedState::Unregulated as i32);
3632 }
3633 crate::coin_registry::RegulatedState::Unknown => {
3634 regulated.coin_regulated_state =
3635 Some(regulated_coin_metadata::CoinRegulatedState::Unknown as i32);
3636 }
3637 }
3638
3639 regulated
3640 }
3641}
3642
3643impl From<crate::coin_registry::RegulatedState> for RegulatedCoinMetadata {
3644 fn from(value: crate::coin_registry::RegulatedState) -> Self {
3645 (&value).into()
3646 }
3647}
3648
3649impl From<crate::coin::RegulatedCoinMetadata> for RegulatedCoinMetadata {
3650 fn from(value: crate::coin::RegulatedCoinMetadata) -> Self {
3651 let mut message = RegulatedCoinMetadata::default();
3652 message.id = Some(sui_sdk_types::Address::from(value.id.id.bytes).to_string());
3653 message.coin_metadata_object =
3654 Some(sui_sdk_types::Address::from(value.coin_metadata_object.bytes).to_string());
3655 message.deny_cap_object =
3656 Some(sui_sdk_types::Address::from(value.deny_cap_object.bytes).to_string());
3657 message.coin_regulated_state =
3658 Some(regulated_coin_metadata::CoinRegulatedState::Regulated as i32);
3659 message
3660 }
3661}
3662
3663impl TryFrom<&ObjectSet> for crate::full_checkpoint_content::ObjectSet {
3664 type Error = TryFromProtoError;
3665
3666 fn try_from(value: &ObjectSet) -> Result<Self, Self::Error> {
3667 let mut objects = Self::default();
3668
3669 for o in value.objects() {
3670 objects.insert(
3671 o.bcs()
3672 .deserialize()
3673 .map_err(|e| TryFromProtoError::invalid("object.bcs", e))?,
3674 );
3675 }
3676
3677 Ok(objects)
3678 }
3679}
3680
3681#[cfg(test)]
3682mod tests {
3683 use crate::effects::TransactionEffectsAPI;
3684
3685 #[test]
3686 fn transaction_effects_v1_proto_includes_lamport_version() {
3687 let effects = crate::effects::TransactionEffectsV1::default();
3688 let lamport_version = effects.lamport_version().value();
3689 let proto: sui_rpc::proto::sui::rpc::v2::TransactionEffects =
3690 crate::effects::TransactionEffects::V1(effects).into();
3691
3692 assert_eq!(proto.lamport_version, Some(lamport_version));
3693 }
3694}