casper_types/execution/
execution_result_v1.rs

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