diem_types/
account_state_blob.rs1use diem_crypto::{
9 hash::{CryptoHash, CryptoHasher},
10 HashValue,
11};
12use diem_crypto_derive::CryptoHasher;
13#[cfg(any(test, feature = "fuzzing"))]
14use proptest::{arbitrary::Arbitrary, prelude::*};
15use serde::{Deserialize, Serialize};
16use std::fmt;
17
18#[derive(Clone, Eq, PartialEq, Serialize, Deserialize, CryptoHasher)]
19pub struct AccountStateBlob {
20 blob: Vec<u8>,
21}
22
23impl fmt::Debug for AccountStateBlob {
24 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25 write!(
26 f,
27 "AccountStateBlob {{ \n \
28 Raw: 0x{} \n \
29 }}",
30 hex::encode(&self.blob),
31 )
32 }
33}
34
35impl AsRef<[u8]> for AccountStateBlob {
36 fn as_ref(&self) -> &[u8] { &self.blob }
37}
38
39impl From<&AccountStateBlob> for Vec<u8> {
40 fn from(account_state_blob: &AccountStateBlob) -> Vec<u8> {
41 account_state_blob.blob.clone()
42 }
43}
44
45impl From<AccountStateBlob> for Vec<u8> {
46 fn from(account_state_blob: AccountStateBlob) -> Vec<u8> {
47 Self::from(&account_state_blob)
48 }
49}
50
51impl From<Vec<u8>> for AccountStateBlob {
52 fn from(blob: Vec<u8>) -> AccountStateBlob { AccountStateBlob { blob } }
53}
54
55impl CryptoHash for AccountStateBlob {
56 type Hasher = AccountStateBlobHasher;
57
58 fn hash(&self) -> HashValue {
59 let mut hasher = Self::Hasher::default();
60 hasher.update(&self.blob);
61 hasher.finish()
62 }
63}
64
65#[cfg(any(test, feature = "fuzzing"))]
66prop_compose! {
67 fn account_state_blob_strategy()(
68 entries in proptest::collection::btree_map(
69 proptest::collection::vec(any::<u8>(), 1..32),
70 proptest::collection::vec(any::<u8>(), 1..64),
71 0..5,
72 )
73 ) -> AccountStateBlob {
74 AccountStateBlob::from(bcs::to_bytes(&entries).unwrap())
75 }
76}
77
78#[cfg(any(test, feature = "fuzzing"))]
79impl Arbitrary for AccountStateBlob {
80 type Parameters = ();
81 type Strategy = BoxedStrategy<Self>;
82
83 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
84 account_state_blob_strategy().boxed()
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91 use bcs::test_helpers::assert_canonical_encode_decode;
92 use proptest::collection::vec;
93
94 fn hash_blob(blob: &[u8]) -> HashValue {
95 let mut hasher = AccountStateBlobHasher::default();
96 hasher.update(blob);
97 hasher.finish()
98 }
99
100 proptest! {
101 #[test]
102 fn account_state_blob_hash(blob in vec(any::<u8>(), 1..100)) {
103 prop_assert_eq!(hash_blob(&blob), AccountStateBlob::from(blob).hash());
104 }
105
106 #[test]
107 fn account_state_blob_bcs_roundtrip(account_state_blob in any::<AccountStateBlob>()) {
108 assert_canonical_encode_decode(account_state_blob);
109 }
110 }
111
112 #[test]
113 fn test_debug_does_not_panic() {
114 let _ = format!("{:#?}", AccountStateBlob::from(vec![1u8, 2u8, 3u8]));
115 }
116}