casper_types/
deploy_info.rs

1// TODO - remove once schemars stops causing warning.
2#![allow(clippy::field_reassign_with_default)]
3
4use alloc::vec::Vec;
5
6#[cfg(feature = "datasize")]
7use datasize::DataSize;
8#[cfg(feature = "json-schema")]
9use schemars::JsonSchema;
10use serde::{Deserialize, Serialize};
11
12use crate::{
13    account::AccountHash,
14    bytesrepr::{self, FromBytes, ToBytes},
15    DeployHash, TransferAddr, URef, U512,
16};
17
18/// Information relating to the given Deploy.
19#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
20#[cfg_attr(feature = "datasize", derive(DataSize))]
21#[cfg_attr(feature = "json-schema", derive(JsonSchema))]
22#[serde(deny_unknown_fields)]
23pub struct DeployInfo {
24    /// The relevant Deploy.
25    pub deploy_hash: DeployHash,
26    /// Transfers performed by the Deploy.
27    pub transfers: Vec<TransferAddr>,
28    /// Account identifier of the creator of the Deploy.
29    pub from: AccountHash,
30    /// Source purse used for payment of the Deploy.
31    pub source: URef,
32    /// Gas cost of executing the Deploy.
33    pub gas: U512,
34}
35
36impl DeployInfo {
37    /// Creates a [`DeployInfo`].
38    pub fn new(
39        deploy_hash: DeployHash,
40        transfers: &[TransferAddr],
41        from: AccountHash,
42        source: URef,
43        gas: U512,
44    ) -> Self {
45        let transfers = transfers.to_vec();
46        DeployInfo {
47            deploy_hash,
48            transfers,
49            from,
50            source,
51            gas,
52        }
53    }
54}
55
56impl FromBytes for DeployInfo {
57    fn from_bytes(bytes: &[u8]) -> Result<(Self, &[u8]), bytesrepr::Error> {
58        let (deploy_hash, rem) = DeployHash::from_bytes(bytes)?;
59        let (transfers, rem) = Vec::<TransferAddr>::from_bytes(rem)?;
60        let (from, rem) = AccountHash::from_bytes(rem)?;
61        let (source, rem) = URef::from_bytes(rem)?;
62        let (gas, rem) = U512::from_bytes(rem)?;
63        Ok((
64            DeployInfo {
65                deploy_hash,
66                transfers,
67                from,
68                source,
69                gas,
70            },
71            rem,
72        ))
73    }
74}
75
76impl ToBytes for DeployInfo {
77    fn to_bytes(&self) -> Result<Vec<u8>, bytesrepr::Error> {
78        let mut result = bytesrepr::allocate_buffer(self)?;
79        self.deploy_hash.write_bytes(&mut result)?;
80        self.transfers.write_bytes(&mut result)?;
81        self.from.write_bytes(&mut result)?;
82        self.source.write_bytes(&mut result)?;
83        self.gas.write_bytes(&mut result)?;
84        Ok(result)
85    }
86
87    fn serialized_length(&self) -> usize {
88        self.deploy_hash.serialized_length()
89            + self.transfers.serialized_length()
90            + self.from.serialized_length()
91            + self.source.serialized_length()
92            + self.gas.serialized_length()
93    }
94
95    fn write_bytes(&self, writer: &mut Vec<u8>) -> Result<(), bytesrepr::Error> {
96        self.deploy_hash.write_bytes(writer)?;
97        self.transfers.write_bytes(writer)?;
98        self.from.write_bytes(writer)?;
99        self.source.write_bytes(writer)?;
100        self.gas.write_bytes(writer)?;
101        Ok(())
102    }
103}
104
105/// Generators for a `Deploy`
106#[cfg(any(feature = "testing", feature = "gens", test))]
107pub(crate) mod gens {
108    use alloc::vec::Vec;
109
110    use proptest::{
111        array,
112        collection::{self, SizeRange},
113        prelude::{Arbitrary, Strategy},
114    };
115
116    use crate::{
117        account::AccountHash,
118        gens::{u512_arb, uref_arb},
119        DeployHash, DeployInfo, TransferAddr,
120    };
121
122    pub fn deploy_hash_arb() -> impl Strategy<Value = DeployHash> {
123        array::uniform32(<u8>::arbitrary()).prop_map(DeployHash::new)
124    }
125
126    pub fn transfer_addr_arb() -> impl Strategy<Value = TransferAddr> {
127        array::uniform32(<u8>::arbitrary()).prop_map(TransferAddr::new)
128    }
129
130    pub fn transfers_arb(size: impl Into<SizeRange>) -> impl Strategy<Value = Vec<TransferAddr>> {
131        collection::vec(transfer_addr_arb(), size)
132    }
133
134    pub fn account_hash_arb() -> impl Strategy<Value = AccountHash> {
135        array::uniform32(<u8>::arbitrary()).prop_map(AccountHash::new)
136    }
137
138    /// Creates an arbitrary `Deploy`
139    pub fn deploy_info_arb() -> impl Strategy<Value = DeployInfo> {
140        let transfers_length_range = 0..5;
141        (
142            deploy_hash_arb(),
143            transfers_arb(transfers_length_range),
144            account_hash_arb(),
145            uref_arb(),
146            u512_arb(),
147        )
148            .prop_map(|(deploy_hash, transfers, from, source, gas)| DeployInfo {
149                deploy_hash,
150                transfers,
151                from,
152                source,
153                gas,
154            })
155    }
156}
157
158#[cfg(test)]
159mod tests {
160    use proptest::prelude::*;
161
162    use crate::bytesrepr;
163
164    use super::gens;
165
166    proptest! {
167        #[test]
168        fn test_serialization_roundtrip(deploy_info in gens::deploy_info_arb()) {
169            bytesrepr::test_serialization_roundtrip(&deploy_info)
170        }
171    }
172}