primitives/
storage.rs

1// Copyright 2019 Conflux Foundation. All rights reserved.
2// Conflux is free software and distributed under GNU General Public License.
3// See http://www.gnu.org/licenses/
4
5use std::{convert::TryFrom, fmt, marker::PhantomData};
6
7use cfx_types::{Address, H256, U256};
8use rlp::*;
9use rlp_derive::{RlpDecodable, RlpEncodable};
10use serde::{
11    de::{self, Visitor},
12    Deserialize, Deserializer, Serialize, Serializer,
13};
14
15#[derive(Clone, Debug, PartialEq)]
16pub enum MptValue<ValueType> {
17    None,
18    TombStone,
19    Some(ValueType),
20}
21
22impl<ValueType: Serialize> Serialize for MptValue<ValueType> {
23    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
24    where S: Serializer {
25        match self {
26            MptValue::None => serializer.serialize_none(),
27            MptValue::Some(h) => serializer.serialize_some(h),
28            MptValue::TombStone => serializer.serialize_str("TOMBSTONE"),
29        }
30    }
31}
32
33impl<'a, ValueType: Deserialize<'a> + From<String>> Deserialize<'a>
34    for MptValue<ValueType>
35{
36    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
37    where D: Deserializer<'a> {
38        deserializer.deserialize_any(MptValueVisitor {
39            marker: PhantomData,
40        })
41    }
42}
43
44struct MptValueVisitor<ValueType> {
45    marker: PhantomData<ValueType>,
46}
47
48impl<'a, ValueType> Visitor<'a> for MptValueVisitor<ValueType>
49where ValueType: Deserialize<'a> + TryFrom<String>
50{
51    type Value = MptValue<ValueType>;
52
53    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
54        write!(formatter, "`MptValue`")
55    }
56
57    fn visit_unit<E>(self) -> Result<Self::Value, E>
58    where E: de::Error {
59        Ok(MptValue::None)
60    }
61
62    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
63    where E: de::Error {
64        match value {
65            "TOMBSTONE" => Ok(MptValue::TombStone),
66            s => match ValueType::try_from(String::from(s)) {
67                Ok(v) => Ok(MptValue::Some(v)),
68                _ => Err(de::Error::custom("unknown value")),
69            },
70        }
71    }
72
73    fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
74    where E: de::Error {
75        self.visit_str(value.as_ref())
76    }
77}
78
79impl<ValueType: Default> MptValue<ValueType> {
80    pub fn is_some(&self) -> bool {
81        match self {
82            MptValue::Some(_) => true,
83            _ => false,
84        }
85    }
86
87    pub fn is_tombstone(&self) -> bool {
88        match self {
89            MptValue::TombStone => true,
90            _ => false,
91        }
92    }
93
94    pub fn into_option(self) -> Option<ValueType> {
95        match self {
96            MptValue::None => None,
97            MptValue::TombStone => Some(ValueType::default()),
98            MptValue::Some(x) => Some(x),
99        }
100    }
101
102    pub fn take(&mut self) -> Self { std::mem::replace(self, MptValue::None) }
103
104    pub fn unwrap(self) -> ValueType {
105        match self {
106            MptValue::None => panic!("Unwrapping MptValue::None"),
107            MptValue::TombStone => ValueType::default(),
108            MptValue::Some(x) => x,
109        }
110    }
111}
112
113impl<ValueType> From<Option<ValueType>> for MptValue<ValueType> {
114    fn from(opt: Option<ValueType>) -> MptValue<ValueType> {
115        match opt {
116            None => MptValue::None,
117            Some(v) => MptValue::Some(v),
118        }
119    }
120}
121
122impl Encodable for MptValue<H256> {
123    fn rlp_append(&self, s: &mut RlpStream) {
124        match self {
125            MptValue::None => {
126                s.begin_list(1).append(&0u8);
127            }
128            MptValue::TombStone => {
129                s.begin_list(1).append(&1u8);
130            }
131            MptValue::Some(h) => {
132                s.begin_list(2).append(&2u8).append(h);
133            }
134        }
135    }
136}
137
138impl Decodable for MptValue<H256> {
139    fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
140        match rlp.val_at(0)? {
141            0u8 => Ok(MptValue::None),
142            1u8 => Ok(MptValue::TombStone),
143            2u8 => Ok(MptValue::Some(rlp.val_at(1)?)),
144            n => panic!("Unexpected MptValue type in RLP: {}", n),
145        }
146    }
147}
148
149#[derive(Clone, Debug, RlpEncodable, RlpDecodable, Serialize)]
150pub struct NodeMerkleTriplet {
151    pub delta: MptValue<H256>,
152    pub intermediate: MptValue<H256>,
153    pub snapshot: Option<H256>,
154}
155
156pub type StorageRoot = NodeMerkleTriplet;
157
158#[derive(Clone, Debug, PartialEq)]
159pub enum StorageLayout {
160    Regular(u8), // type: 0, fields: version
161}
162
163pub const STORAGE_LAYOUT_REGULAR_V0: StorageLayout = StorageLayout::Regular(0);
164
165impl StorageLayout {
166    pub fn to_bytes(&self) -> Vec<u8> {
167        match self {
168            StorageLayout::Regular(version) => vec![0, *version],
169        }
170    }
171
172    pub fn from_bytes(raw: &[u8]) -> Result<StorageLayout, String> {
173        match raw {
174            &[0, version] => Ok(StorageLayout::Regular(version)),
175            _ => Err(format!("Unknown storage layout: {:?}", raw)),
176        }
177    }
178}
179
180#[derive(Default, Clone, Copy, Debug)]
181pub struct StorageValue {
182    pub value: U256,
183    pub owner: Option<Address>,
184}
185
186#[derive(Clone, Copy, Debug)]
187pub enum WriteCacheItem {
188    Read,
189    Write(StorageValue),
190}
191
192impl Decodable for StorageValue {
193    fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
194        if rlp.is_list() {
195            if rlp.item_count()? != 2 {
196                return Err(DecoderError::RlpIncorrectListLen);
197            }
198            Ok(StorageValue {
199                value: rlp.val_at(0)?,
200                owner: Some(rlp.val_at(1)?),
201            })
202        } else {
203            Ok(StorageValue {
204                value: rlp.as_val()?,
205                owner: None,
206            })
207        }
208    }
209}
210
211impl Encodable for StorageValue {
212    fn rlp_append(&self, s: &mut RlpStream) {
213        match &self.owner {
214            Some(owner) => {
215                s.begin_list(2).append(&self.value).append(owner);
216            }
217            None => {
218                s.append_internal(&self.value);
219            }
220        }
221    }
222}
223
224#[cfg(test)]
225mod tests {
226    use super::MptValue;
227    use crate::{MerkleHash, MERKLE_NULL_NODE};
228    use serde_json;
229
230    #[test]
231    fn test_mpt_value_rlp() {
232        let val = MptValue::None;
233
234        // list of length 1: rlp(0)
235        assert_eq!(rlp::encode(&val), vec![0xc0 + 1, 0x80]);
236        assert_eq!(val, rlp::decode(&rlp::encode(&val)).unwrap());
237
238        let val = MptValue::TombStone;
239
240        // list of length 1: rlp(1)
241        assert_eq!(rlp::encode(&val), vec![0xc0 + 1, 0x01]);
242        assert_eq!(val, rlp::decode(&rlp::encode(&val)).unwrap());
243
244        let val = MptValue::Some(MERKLE_NULL_NODE);
245
246        // list of length 34 (type + 33 for serialized hash): rlp(2) + rlp(hash)
247        assert_eq!(
248            rlp::encode(&val),
249            [&[0xc0 + 34, 0x02][..], &rlp::encode(&MERKLE_NULL_NODE)[..]]
250                .concat()
251        );
252        assert_eq!(val, rlp::decode(&rlp::encode(&val)).unwrap());
253    }
254
255    #[test]
256    fn test_mpt_value_json() {
257        let val = MptValue::<MerkleHash>::None;
258        let serialized = serde_json::to_string(&val).unwrap();
259        assert_eq!(&serialized, "null");
260
261        let val = MptValue::<MerkleHash>::TombStone;
262        let serialized = serde_json::to_string(&val).unwrap();
263        assert_eq!(&serialized, "\"TOMBSTONE\"");
264
265        let val = MptValue::<MerkleHash>::Some(MERKLE_NULL_NODE);
266        let serialized = serde_json::to_string(&val).unwrap();
267        assert_eq!(serialized, format!("\"{:?}\"", MERKLE_NULL_NODE));
268    }
269}