1#![allow(clippy::field_reassign_with_default)]
9
10use core::convert::TryFrom;
11
12use alloc::{
13 boxed::Box,
14 format,
15 string::{String, ToString},
16 vec,
17 vec::Vec,
18};
19
20#[cfg(feature = "datasize")]
21use datasize::DataSize;
22use num::{FromPrimitive, ToPrimitive};
23use num_derive::{FromPrimitive, ToPrimitive};
24#[cfg(feature = "json-schema")]
25use once_cell::sync::Lazy;
26use rand::{
27 distributions::{Distribution, Standard},
28 seq::SliceRandom,
29 Rng,
30};
31#[cfg(feature = "json-schema")]
32use schemars::JsonSchema;
33use serde::{Deserialize, Serialize};
34
35#[cfg(feature = "json-schema")]
36use crate::KEY_HASH_LENGTH;
37use crate::{
38 account::AccountHash,
39 bytesrepr::{self, FromBytes, ToBytes, U8_SERIALIZED_LENGTH},
40 system::auction::{Bid, EraInfo, UnbondingPurse, WithdrawPurse},
41 CLValue, DeployInfo, NamedKey, Transfer, TransferAddr, U128, U256, U512,
42};
43
44#[derive(FromPrimitive, ToPrimitive, Debug)]
45#[repr(u8)]
46enum ExecutionResultTag {
47 Failure = 0,
48 Success = 1,
49}
50
51impl TryFrom<u8> for ExecutionResultTag {
52 type Error = bytesrepr::Error;
53
54 fn try_from(value: u8) -> Result<Self, Self::Error> {
55 FromPrimitive::from_u8(value).ok_or(bytesrepr::Error::Formatting)
56 }
57}
58
59#[derive(FromPrimitive, ToPrimitive, Debug)]
60#[repr(u8)]
61enum OpTag {
62 Read = 0,
63 Write = 1,
64 Add = 2,
65 NoOp = 3,
66}
67
68impl TryFrom<u8> for OpTag {
69 type Error = bytesrepr::Error;
70
71 fn try_from(value: u8) -> Result<Self, Self::Error> {
72 FromPrimitive::from_u8(value).ok_or(bytesrepr::Error::Formatting)
73 }
74}
75
76#[derive(FromPrimitive, ToPrimitive, Debug)]
77#[repr(u8)]
78enum TransformTag {
79 Identity = 0,
80 WriteCLValue = 1,
81 WriteAccount = 2,
82 WriteContractWasm = 3,
83 WriteContract = 4,
84 WriteContractPackage = 5,
85 WriteDeployInfo = 6,
86 WriteTransfer = 7,
87 WriteEraInfo = 8,
88 WriteBid = 9,
89 WriteWithdraw = 10,
90 AddInt32 = 11,
91 AddUInt64 = 12,
92 AddUInt128 = 13,
93 AddUInt256 = 14,
94 AddUInt512 = 15,
95 AddKeys = 16,
96 Failure = 17,
97 WriteUnbonding = 18,
98}
99
100impl TryFrom<u8> for TransformTag {
101 type Error = bytesrepr::Error;
102
103 fn try_from(value: u8) -> Result<Self, Self::Error> {
104 FromPrimitive::from_u8(value).ok_or(bytesrepr::Error::Formatting)
105 }
106}
107
108#[cfg(feature = "json-schema")]
109static EXECUTION_RESULT: Lazy<ExecutionResult> = Lazy::new(|| {
110 let operations = vec![
111 Operation {
112 key: "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb"
113 .to_string(),
114 kind: OpKind::Write,
115 },
116 Operation {
117 key: "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1"
118 .to_string(),
119 kind: OpKind::Read,
120 },
121 ];
122
123 let transforms = vec![
124 TransformEntry {
125 key: "uref-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb-007"
126 .to_string(),
127 transform: Transform::AddUInt64(8u64),
128 },
129 TransformEntry {
130 key: "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1"
131 .to_string(),
132 transform: Transform::Identity,
133 },
134 ];
135
136 let effect = ExecutionEffect {
137 operations,
138 transforms,
139 };
140
141 let transfers = vec![
142 TransferAddr::new([89; KEY_HASH_LENGTH]),
143 TransferAddr::new([130; KEY_HASH_LENGTH]),
144 ];
145
146 ExecutionResult::Success {
147 effect,
148 transfers,
149 cost: U512::from(123_456),
150 }
151});
152
153#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Debug)]
155#[cfg_attr(feature = "datasize", derive(DataSize))]
156#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
157#[serde(deny_unknown_fields)]
158pub enum ExecutionResult {
159 Failure {
161 effect: ExecutionEffect,
163 transfers: Vec<TransferAddr>,
165 cost: U512,
167 error_message: String,
169 },
170 Success {
172 effect: ExecutionEffect,
174 transfers: Vec<TransferAddr>,
176 cost: U512,
178 },
179}
180
181impl ExecutionResult {
182 #[doc(hidden)]
184 #[cfg(feature = "json-schema")]
185 pub fn example() -> &'static Self {
186 &EXECUTION_RESULT
187 }
188
189 fn tag(&self) -> ExecutionResultTag {
190 match self {
191 ExecutionResult::Failure {
192 effect: _,
193 transfers: _,
194 cost: _,
195 error_message: _,
196 } => ExecutionResultTag::Failure,
197 ExecutionResult::Success {
198 effect: _,
199 transfers: _,
200 cost: _,
201 } => ExecutionResultTag::Success,
202 }
203 }
204}
205
206impl Distribution<ExecutionResult> for Standard {
207 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> ExecutionResult {
208 let op_count = rng.gen_range(0..6);
209 let mut operations = Vec::new();
210 for _ in 0..op_count {
211 let op = [OpKind::Read, OpKind::Add, OpKind::NoOp, OpKind::Write]
212 .choose(rng)
213 .unwrap();
214 operations.push(Operation {
215 key: rng.gen::<u64>().to_string(),
216 kind: *op,
217 });
218 }
219
220 let transform_count = rng.gen_range(0..6);
221 let mut transforms = Vec::new();
222 for _ in 0..transform_count {
223 transforms.push(TransformEntry {
224 key: rng.gen::<u64>().to_string(),
225 transform: rng.gen(),
226 });
227 }
228
229 let execution_effect = ExecutionEffect::new(transforms);
230
231 let transfer_count = rng.gen_range(0..6);
232 let mut transfers = vec![];
233 for _ in 0..transfer_count {
234 transfers.push(TransferAddr::new(rng.gen()))
235 }
236
237 if rng.gen() {
238 ExecutionResult::Failure {
239 effect: execution_effect,
240 transfers,
241 cost: rng.gen::<u64>().into(),
242 error_message: format!("Error message {}", rng.gen::<u64>()),
243 }
244 } else {
245 ExecutionResult::Success {
246 effect: execution_effect,
247 transfers,
248 cost: rng.gen::<u64>().into(),
249 }
250 }
251 }
252}
253
254impl ToBytes for ExecutionResult {
256 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
257 let mut buffer = bytesrepr::allocate_buffer(self)?;
258 let tag_byte = self.tag().to_u8().ok_or(bytesrepr::Error::Formatting)?;
259 buffer.push(tag_byte);
260 match self {
261 ExecutionResult::Failure {
262 effect,
263 transfers,
264 cost,
265 error_message,
266 } => {
267 buffer.extend(effect.to_bytes()?);
268 buffer.extend(transfers.to_bytes()?);
269 buffer.extend(cost.to_bytes()?);
270 buffer.extend(error_message.to_bytes()?);
271 }
272 ExecutionResult::Success {
273 effect,
274 transfers,
275 cost,
276 } => {
277 buffer.extend(effect.to_bytes()?);
278 buffer.extend(transfers.to_bytes()?);
279 buffer.extend(cost.to_bytes()?);
280 }
281 }
282 Ok(buffer)
283 }
284
285 fn serialized_length(&self) -> usize {
286 U8_SERIALIZED_LENGTH
287 + match self {
288 ExecutionResult::Failure {
289 effect: execution_effect,
290 transfers,
291 cost,
292 error_message,
293 } => {
294 execution_effect.serialized_length()
295 + transfers.serialized_length()
296 + cost.serialized_length()
297 + error_message.serialized_length()
298 }
299 ExecutionResult::Success {
300 effect: execution_effect,
301 transfers,
302 cost,
303 } => {
304 execution_effect.serialized_length()
305 + transfers.serialized_length()
306 + cost.serialized_length()
307 }
308 }
309 }
310}
311
312impl FromBytes for ExecutionResult {
313 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
314 let (tag, remainder) = u8::from_bytes(bytes)?;
315 match TryFrom::try_from(tag)? {
316 ExecutionResultTag::Failure => {
317 let (effect, remainder) = ExecutionEffect::from_bytes(remainder)?;
318 let (transfers, remainder) = Vec::<TransferAddr>::from_bytes(remainder)?;
319 let (cost, remainder) = U512::from_bytes(remainder)?;
320 let (error_message, remainder) = String::from_bytes(remainder)?;
321 let execution_result = ExecutionResult::Failure {
322 effect,
323 transfers,
324 cost,
325 error_message,
326 };
327 Ok((execution_result, remainder))
328 }
329 ExecutionResultTag::Success => {
330 let (execution_effect, remainder) = ExecutionEffect::from_bytes(remainder)?;
331 let (transfers, remainder) = Vec::<TransferAddr>::from_bytes(remainder)?;
332 let (cost, remainder) = U512::from_bytes(remainder)?;
333 let execution_result = ExecutionResult::Success {
334 effect: execution_effect,
335 transfers,
336 cost,
337 };
338 Ok((execution_result, remainder))
339 }
340 }
341 }
342}
343
344#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Default, Debug)]
346#[cfg_attr(feature = "datasize", derive(DataSize))]
347#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
348#[serde(deny_unknown_fields)]
349pub struct ExecutionEffect {
350 pub operations: Vec<Operation>,
352 pub transforms: Vec<TransformEntry>,
354}
355
356impl ExecutionEffect {
357 pub fn new(transforms: Vec<TransformEntry>) -> Self {
359 Self {
360 transforms,
361 operations: Default::default(),
362 }
363 }
364}
365
366impl ToBytes for ExecutionEffect {
368 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
369 let mut buffer = bytesrepr::allocate_buffer(self)?;
370 buffer.extend(self.operations.to_bytes()?);
371 buffer.extend(self.transforms.to_bytes()?);
372 Ok(buffer)
373 }
374
375 fn serialized_length(&self) -> usize {
376 self.operations.serialized_length() + self.transforms.serialized_length()
377 }
378}
379
380impl FromBytes for ExecutionEffect {
381 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
382 let (operations, remainder) = Vec::<Operation>::from_bytes(bytes)?;
383 let (transforms, remainder) = Vec::<TransformEntry>::from_bytes(remainder)?;
384 let json_execution_journal = ExecutionEffect {
385 operations,
386 transforms,
387 };
388 Ok((json_execution_journal, remainder))
389 }
390}
391
392#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Debug)]
394#[cfg_attr(feature = "datasize", derive(DataSize))]
395#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
396#[serde(deny_unknown_fields)]
397pub struct Operation {
398 pub key: String,
400 pub kind: OpKind,
402}
403
404impl ToBytes for Operation {
406 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
407 let mut buffer = bytesrepr::allocate_buffer(self)?;
408 buffer.extend(self.key.to_bytes()?);
409 buffer.extend(self.kind.to_bytes()?);
410 Ok(buffer)
411 }
412
413 fn serialized_length(&self) -> usize {
414 self.key.serialized_length() + self.kind.serialized_length()
415 }
416}
417
418impl FromBytes for Operation {
419 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
420 let (key, remainder) = String::from_bytes(bytes)?;
421 let (kind, remainder) = OpKind::from_bytes(remainder)?;
422 let operation = Operation { key, kind };
423 Ok((operation, remainder))
424 }
425}
426
427#[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)]
429#[cfg_attr(feature = "datasize", derive(DataSize))]
430#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
431#[serde(deny_unknown_fields)]
432pub enum OpKind {
433 Read,
435 Write,
437 Add,
439 NoOp,
441}
442
443impl OpKind {
444 fn tag(&self) -> OpTag {
445 match self {
446 OpKind::Read => OpTag::Read,
447 OpKind::Write => OpTag::Write,
448 OpKind::Add => OpTag::Add,
449 OpKind::NoOp => OpTag::NoOp,
450 }
451 }
452}
453
454impl ToBytes for OpKind {
456 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
457 let tag_bytes = self.tag().to_u8().ok_or(bytesrepr::Error::Formatting)?;
458 tag_bytes.to_bytes()
459 }
460
461 fn serialized_length(&self) -> usize {
462 U8_SERIALIZED_LENGTH
463 }
464}
465
466impl FromBytes for OpKind {
467 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
468 let (tag, remainder) = u8::from_bytes(bytes)?;
469 match TryFrom::try_from(tag)? {
470 OpTag::Read => Ok((OpKind::Read, remainder)),
471 OpTag::Write => Ok((OpKind::Write, remainder)),
472 OpTag::Add => Ok((OpKind::Add, remainder)),
473 OpTag::NoOp => Ok((OpKind::NoOp, remainder)),
474 }
475 }
476}
477
478#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Debug)]
480#[cfg_attr(feature = "datasize", derive(DataSize))]
481#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
482#[serde(deny_unknown_fields)]
483pub struct TransformEntry {
484 pub key: String,
486 pub transform: Transform,
488}
489
490impl ToBytes for TransformEntry {
492 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
493 let mut buffer = bytesrepr::allocate_buffer(self)?;
494 buffer.extend(self.key.to_bytes()?);
495 buffer.extend(self.transform.to_bytes()?);
496 Ok(buffer)
497 }
498
499 fn serialized_length(&self) -> usize {
500 self.key.serialized_length() + self.transform.serialized_length()
501 }
502}
503
504impl FromBytes for TransformEntry {
505 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
506 let (key, remainder) = String::from_bytes(bytes)?;
507 let (transform, remainder) = Transform::from_bytes(remainder)?;
508 let transform_entry = TransformEntry { key, transform };
509 Ok((transform_entry, remainder))
510 }
511}
512
513#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, Debug)]
515#[cfg_attr(feature = "datasize", derive(DataSize))]
516#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
517#[serde(deny_unknown_fields)]
518pub enum Transform {
519 Identity,
521 WriteCLValue(CLValue),
523 WriteAccount(AccountHash),
525 WriteContractWasm,
527 WriteContract,
529 WriteContractPackage,
531 WriteDeployInfo(DeployInfo),
533 WriteEraInfo(EraInfo),
535 WriteTransfer(Transfer),
537 WriteBid(Box<Bid>),
539 WriteWithdraw(Vec<WithdrawPurse>),
541 AddInt32(i32),
543 AddUInt64(u64),
545 AddUInt128(U128),
547 AddUInt256(U256),
549 AddUInt512(U512),
551 AddKeys(Vec<NamedKey>),
553 Failure(String),
555 WriteUnbonding(Vec<UnbondingPurse>),
557}
558
559impl Transform {
560 fn tag(&self) -> TransformTag {
561 match self {
562 Transform::Identity => TransformTag::Identity,
563 Transform::WriteCLValue(_) => TransformTag::WriteCLValue,
564 Transform::WriteAccount(_) => TransformTag::WriteAccount,
565 Transform::WriteContractWasm => TransformTag::WriteContractWasm,
566 Transform::WriteContract => TransformTag::WriteContract,
567 Transform::WriteContractPackage => TransformTag::WriteContractPackage,
568 Transform::WriteDeployInfo(_) => TransformTag::WriteDeployInfo,
569 Transform::WriteEraInfo(_) => TransformTag::WriteEraInfo,
570 Transform::WriteTransfer(_) => TransformTag::WriteTransfer,
571 Transform::WriteBid(_) => TransformTag::WriteBid,
572 Transform::WriteWithdraw(_) => TransformTag::WriteWithdraw,
573 Transform::AddInt32(_) => TransformTag::AddInt32,
574 Transform::AddUInt64(_) => TransformTag::AddUInt64,
575 Transform::AddUInt128(_) => TransformTag::AddUInt128,
576 Transform::AddUInt256(_) => TransformTag::AddUInt256,
577 Transform::AddUInt512(_) => TransformTag::AddUInt512,
578 Transform::AddKeys(_) => TransformTag::AddKeys,
579 Transform::Failure(_) => TransformTag::Failure,
580 Transform::WriteUnbonding(_) => TransformTag::WriteUnbonding,
581 }
582 }
583}
584
585impl ToBytes for Transform {
587 fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
588 let mut buffer = bytesrepr::allocate_buffer(self)?;
589 let tag_bytes = self.tag().to_u8().ok_or(bytesrepr::Error::Formatting)?;
590 buffer.insert(0, tag_bytes);
591 match self {
592 Transform::Identity => {}
593 Transform::WriteCLValue(value) => {
594 buffer.extend(value.to_bytes()?);
595 }
596 Transform::WriteAccount(account_hash) => {
597 buffer.extend(account_hash.to_bytes()?);
598 }
599 Transform::WriteContractWasm => {}
600 Transform::WriteContract => {}
601 Transform::WriteContractPackage => {}
602 Transform::WriteDeployInfo(deploy_info) => {
603 buffer.extend(deploy_info.to_bytes()?);
604 }
605 Transform::WriteEraInfo(era_info) => {
606 buffer.extend(era_info.to_bytes()?);
607 }
608 Transform::WriteTransfer(transfer) => {
609 buffer.extend(transfer.to_bytes()?);
610 }
611 Transform::WriteBid(bid) => {
612 buffer.extend(bid.to_bytes()?);
613 }
614 Transform::WriteWithdraw(unbonding_purses) => {
615 buffer.extend(unbonding_purses.to_bytes()?);
616 }
617 Transform::AddInt32(value) => {
618 buffer.extend(value.to_bytes()?);
619 }
620 Transform::AddUInt64(value) => {
621 buffer.extend(value.to_bytes()?);
622 }
623 Transform::AddUInt128(value) => {
624 buffer.extend(value.to_bytes()?);
625 }
626 Transform::AddUInt256(value) => {
627 buffer.extend(value.to_bytes()?);
628 }
629 Transform::AddUInt512(value) => {
630 buffer.extend(value.to_bytes()?);
631 }
632 Transform::AddKeys(value) => {
633 buffer.extend(value.to_bytes()?);
634 }
635 Transform::Failure(value) => {
636 buffer.extend(value.to_bytes()?);
637 }
638 Transform::WriteUnbonding(value) => {
639 buffer.extend(value.to_bytes()?);
640 }
641 }
642 Ok(buffer)
643 }
644
645 fn serialized_length(&self) -> usize {
646 let body_len = match self {
647 Transform::WriteCLValue(value) => value.serialized_length(),
648 Transform::WriteAccount(value) => value.serialized_length(),
649 Transform::WriteDeployInfo(value) => value.serialized_length(),
650 Transform::WriteEraInfo(value) => value.serialized_length(),
651 Transform::WriteTransfer(value) => value.serialized_length(),
652 Transform::AddInt32(value) => value.serialized_length(),
653 Transform::AddUInt64(value) => value.serialized_length(),
654 Transform::AddUInt128(value) => value.serialized_length(),
655 Transform::AddUInt256(value) => value.serialized_length(),
656 Transform::AddUInt512(value) => value.serialized_length(),
657 Transform::AddKeys(value) => value.serialized_length(),
658 Transform::Failure(value) => value.serialized_length(),
659 Transform::Identity
660 | Transform::WriteContractWasm
661 | Transform::WriteContract
662 | Transform::WriteContractPackage => 0,
663 Transform::WriteBid(value) => value.serialized_length(),
664 Transform::WriteWithdraw(value) => value.serialized_length(),
665 Transform::WriteUnbonding(value) => value.serialized_length(),
666 };
667 U8_SERIALIZED_LENGTH + body_len
668 }
669}
670
671impl FromBytes for Transform {
672 fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
673 let (tag, remainder) = u8::from_bytes(bytes)?;
674 match TryFrom::try_from(tag)? {
675 TransformTag::Identity => Ok((Transform::Identity, remainder)),
676 TransformTag::WriteCLValue => {
677 let (cl_value, remainder) = CLValue::from_bytes(remainder)?;
678 Ok((Transform::WriteCLValue(cl_value), remainder))
679 }
680 TransformTag::WriteAccount => {
681 let (account_hash, remainder) = AccountHash::from_bytes(remainder)?;
682 Ok((Transform::WriteAccount(account_hash), remainder))
683 }
684 TransformTag::WriteContractWasm => Ok((Transform::WriteContractWasm, remainder)),
685 TransformTag::WriteContract => Ok((Transform::WriteContract, remainder)),
686 TransformTag::WriteContractPackage => Ok((Transform::WriteContractPackage, remainder)),
687 TransformTag::WriteDeployInfo => {
688 let (deploy_info, remainder) = DeployInfo::from_bytes(remainder)?;
689 Ok((Transform::WriteDeployInfo(deploy_info), remainder))
690 }
691 TransformTag::WriteEraInfo => {
692 let (era_info, remainder) = EraInfo::from_bytes(remainder)?;
693 Ok((Transform::WriteEraInfo(era_info), remainder))
694 }
695 TransformTag::WriteTransfer => {
696 let (transfer, remainder) = Transfer::from_bytes(remainder)?;
697 Ok((Transform::WriteTransfer(transfer), remainder))
698 }
699 TransformTag::AddInt32 => {
700 let (value_i32, remainder) = i32::from_bytes(remainder)?;
701 Ok((Transform::AddInt32(value_i32), remainder))
702 }
703 TransformTag::AddUInt64 => {
704 let (value_u64, remainder) = u64::from_bytes(remainder)?;
705 Ok((Transform::AddUInt64(value_u64), remainder))
706 }
707 TransformTag::AddUInt128 => {
708 let (value_u128, remainder) = U128::from_bytes(remainder)?;
709 Ok((Transform::AddUInt128(value_u128), remainder))
710 }
711 TransformTag::AddUInt256 => {
712 let (value_u256, remainder) = U256::from_bytes(remainder)?;
713 Ok((Transform::AddUInt256(value_u256), remainder))
714 }
715 TransformTag::AddUInt512 => {
716 let (value_u512, remainder) = U512::from_bytes(remainder)?;
717 Ok((Transform::AddUInt512(value_u512), remainder))
718 }
719 TransformTag::AddKeys => {
720 let (value, remainder) = Vec::<NamedKey>::from_bytes(remainder)?;
721 Ok((Transform::AddKeys(value), remainder))
722 }
723 TransformTag::Failure => {
724 let (value, remainder) = String::from_bytes(remainder)?;
725 Ok((Transform::Failure(value), remainder))
726 }
727 TransformTag::WriteBid => {
728 let (bid, remainder) = Bid::from_bytes(remainder)?;
729 Ok((Transform::WriteBid(Box::new(bid)), remainder))
730 }
731 TransformTag::WriteWithdraw => {
732 let (withdraw_purses, remainder) =
733 <Vec<WithdrawPurse> as FromBytes>::from_bytes(remainder)?;
734 Ok((Transform::WriteWithdraw(withdraw_purses), remainder))
735 }
736 TransformTag::WriteUnbonding => {
737 let (unbonding_purses, remainder) =
738 <Vec<UnbondingPurse> as FromBytes>::from_bytes(remainder)?;
739 Ok((Transform::WriteUnbonding(unbonding_purses), remainder))
740 }
741 }
742 }
743}
744
745impl Distribution<Transform> for Standard {
746 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Transform {
747 match rng.gen_range(0..13) {
749 0 => Transform::Identity,
750 1 => Transform::WriteCLValue(CLValue::from_t(true).unwrap()),
751 2 => Transform::WriteAccount(AccountHash::new(rng.gen())),
752 3 => Transform::WriteContractWasm,
753 4 => Transform::WriteContract,
754 5 => Transform::WriteContractPackage,
755 6 => Transform::AddInt32(rng.gen()),
756 7 => Transform::AddUInt64(rng.gen()),
757 8 => Transform::AddUInt128(rng.gen::<u64>().into()),
758 9 => Transform::AddUInt256(rng.gen::<u64>().into()),
759 10 => Transform::AddUInt512(rng.gen::<u64>().into()),
760 11 => {
761 let mut named_keys = Vec::new();
762 for _ in 0..rng.gen_range(1..6) {
763 named_keys.push(NamedKey {
764 name: rng.gen::<u64>().to_string(),
765 key: rng.gen::<u64>().to_string(),
766 });
767 }
768 Transform::AddKeys(named_keys)
769 }
770 12 => Transform::Failure(rng.gen::<u64>().to_string()),
771 _ => unreachable!(),
772 }
773 }
774}
775
776#[cfg(test)]
777mod tests {
778 use rand::{rngs::SmallRng, Rng, SeedableRng};
779
780 use super::*;
781
782 fn get_rng() -> SmallRng {
783 let mut seed = [0u8; 32];
784 getrandom::getrandom(seed.as_mut()).unwrap();
785 SmallRng::from_seed(seed)
786 }
787
788 #[test]
789 fn bytesrepr_test_transform() {
790 let mut rng = get_rng();
791 let transform: Transform = rng.gen();
792 bytesrepr::test_serialization_roundtrip(&transform);
793 }
794
795 #[test]
796 fn bytesrepr_test_execution_result() {
797 let mut rng = get_rng();
798 let execution_result: ExecutionResult = rng.gen();
799 bytesrepr::test_serialization_roundtrip(&execution_result);
800 }
801}