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 { matches!(self, MptValue::Some(_)) }
81
82 pub fn is_tombstone(&self) -> bool { matches!(self, MptValue::TombStone) }
83
84 pub fn into_option(self) -> Option<ValueType> {
85 match self {
86 MptValue::None => None,
87 MptValue::TombStone => Some(ValueType::default()),
88 MptValue::Some(x) => Some(x),
89 }
90 }
91
92 pub fn take(&mut self) -> Self { std::mem::replace(self, MptValue::None) }
93
94 pub fn unwrap(self) -> ValueType {
95 match self {
96 MptValue::None => panic!("Unwrapping MptValue::None"),
97 MptValue::TombStone => ValueType::default(),
98 MptValue::Some(x) => x,
99 }
100 }
101}
102
103impl<ValueType> From<Option<ValueType>> for MptValue<ValueType> {
104 fn from(opt: Option<ValueType>) -> MptValue<ValueType> {
105 match opt {
106 None => MptValue::None,
107 Some(v) => MptValue::Some(v),
108 }
109 }
110}
111
112impl Encodable for MptValue<H256> {
113 fn rlp_append(&self, s: &mut RlpStream) {
114 match self {
115 MptValue::None => {
116 s.begin_list(1).append(&0u8);
117 }
118 MptValue::TombStone => {
119 s.begin_list(1).append(&1u8);
120 }
121 MptValue::Some(h) => {
122 s.begin_list(2).append(&2u8).append(h);
123 }
124 }
125 }
126}
127
128impl Decodable for MptValue<H256> {
129 fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
130 match rlp.val_at(0)? {
131 0u8 => Ok(MptValue::None),
132 1u8 => Ok(MptValue::TombStone),
133 2u8 => Ok(MptValue::Some(rlp.val_at(1)?)),
134 _ => Err(DecoderError::Custom("Unexpected MptValue type in RLP")),
135 }
136 }
137}
138
139#[derive(Clone, Debug, RlpEncodable, RlpDecodable, Serialize)]
140pub struct NodeMerkleTriplet {
141 pub delta: MptValue<H256>,
142 pub intermediate: MptValue<H256>,
143 pub snapshot: Option<H256>,
144}
145
146pub type StorageRoot = NodeMerkleTriplet;
147
148#[derive(Clone, Debug, PartialEq)]
149pub enum StorageLayout {
150 Regular(u8), }
152
153pub const STORAGE_LAYOUT_REGULAR_V0: StorageLayout = StorageLayout::Regular(0);
154
155impl StorageLayout {
156 pub fn to_bytes(&self) -> Vec<u8> {
157 match self {
158 StorageLayout::Regular(version) => vec![0, *version],
159 }
160 }
161
162 pub fn from_bytes(raw: &[u8]) -> Result<StorageLayout, String> {
163 match raw {
164 &[0, version] => Ok(StorageLayout::Regular(version)),
165 _ => Err(format!("Unknown storage layout: {:?}", raw)),
166 }
167 }
168}
169
170#[derive(Default, Clone, Copy, Debug)]
171pub struct StorageValue {
172 pub value: U256,
173 pub owner: Option<Address>,
174}
175
176#[derive(Clone, Copy, Debug)]
177pub enum WriteCacheItem {
178 Read,
179 Write(StorageValue),
180}
181
182impl Decodable for StorageValue {
183 fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
184 if rlp.is_list() {
185 if rlp.item_count()? != 2 {
186 return Err(DecoderError::RlpIncorrectListLen);
187 }
188 Ok(StorageValue {
189 value: rlp.val_at(0)?,
190 owner: Some(rlp.val_at(1)?),
191 })
192 } else {
193 Ok(StorageValue {
194 value: rlp.as_val()?,
195 owner: None,
196 })
197 }
198 }
199}
200
201impl Encodable for StorageValue {
202 fn rlp_append(&self, s: &mut RlpStream) {
203 match &self.owner {
204 Some(owner) => {
205 s.begin_list(2).append(&self.value).append(owner);
206 }
207 None => {
208 s.append_internal(&self.value);
209 }
210 }
211 }
212}
213
214#[cfg(test)]
215mod tests {
216 use super::MptValue;
217 use crate::{MerkleHash, MERKLE_NULL_NODE};
218 use serde_json;
219
220 #[test]
221 fn test_mpt_value_rlp() {
222 let val = MptValue::None;
223
224 assert_eq!(rlp::encode(&val), vec![0xc0 + 1, 0x80]);
226 assert_eq!(val, rlp::decode(&rlp::encode(&val)).unwrap());
227
228 let val = MptValue::TombStone;
229
230 assert_eq!(rlp::encode(&val), vec![0xc0 + 1, 0x01]);
232 assert_eq!(val, rlp::decode(&rlp::encode(&val)).unwrap());
233
234 let val = MptValue::Some(MERKLE_NULL_NODE);
235
236 assert_eq!(
238 rlp::encode(&val),
239 [&[0xc0 + 34, 0x02][..], &rlp::encode(&MERKLE_NULL_NODE)[..]]
240 .concat()
241 );
242 assert_eq!(val, rlp::decode(&rlp::encode(&val)).unwrap());
243 }
244
245 #[test]
246 fn test_mpt_value_rlp_invalid_tag() {
247 let invalid = rlp::encode_list::<u8, _>(&[3]);
248 assert_eq!(
249 rlp::decode::<MptValue<MerkleHash>>(&invalid),
250 Err(rlp::DecoderError::Custom("Unexpected MptValue type in RLP"))
251 );
252 }
253
254 #[test]
255 fn test_mpt_value_json() {
256 let val = MptValue::<MerkleHash>::None;
257 let serialized = serde_json::to_string(&val).unwrap();
258 assert_eq!(&serialized, "null");
259
260 let val = MptValue::<MerkleHash>::TombStone;
261 let serialized = serde_json::to_string(&val).unwrap();
262 assert_eq!(&serialized, "\"TOMBSTONE\"");
263
264 let val = MptValue::<MerkleHash>::Some(MERKLE_NULL_NODE);
265 let serialized = serde_json::to_string(&val).unwrap();
266 assert_eq!(serialized, format!("\"{:?}\"", MERKLE_NULL_NODE));
267 }
268}