1use 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), }
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 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 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 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}