primitives/
storage_key.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 crate::static_bool::{self, StaticBool};
6use lazy_static::lazy_static;
7
8pub type CheckInput = static_bool::Yes;
9pub type SkipInputCheck = static_bool::No;
10
11pub trait ConditionalReturnValue<'a> {
12    type Output;
13
14    fn from_key(k: StorageKeyWithSpace<'a>) -> Self::Output;
15    fn from_result(r: Result<StorageKeyWithSpace<'a>, String>) -> Self::Output;
16}
17
18pub struct FromKeyBytesResult<ShouldCheckInput: StaticBool> {
19    phantom: std::marker::PhantomData<ShouldCheckInput>,
20}
21
22impl<'a> ConditionalReturnValue<'a> for FromKeyBytesResult<SkipInputCheck> {
23    type Output = StorageKeyWithSpace<'a>;
24
25    fn from_key(k: StorageKeyWithSpace<'a>) -> Self::Output { k }
26
27    fn from_result(
28        _r: Result<StorageKeyWithSpace<'a>, String>,
29    ) -> Self::Output {
30        unreachable!()
31    }
32}
33
34impl<'a> ConditionalReturnValue<'a> for FromKeyBytesResult<CheckInput> {
35    type Output = Result<StorageKeyWithSpace<'a>, String>;
36
37    fn from_key(k: StorageKeyWithSpace<'a>) -> Self::Output { Ok(k) }
38
39    fn from_result(r: Result<StorageKeyWithSpace<'a>, String>) -> Self::Output {
40        r
41    }
42}
43
44// The original StorageKeys unprocessed, in contrary to StorageKey which is
45// processed to use in DeltaMpt.
46#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
47pub enum StorageKey<'a> {
48    AccountKey(&'a [u8]),
49    StorageRootKey(&'a [u8]),
50    StorageKey {
51        address_bytes: &'a [u8],
52        storage_key: &'a [u8],
53    },
54    CodeRootKey(&'a [u8]),
55    CodeKey {
56        address_bytes: &'a [u8],
57        code_hash_bytes: &'a [u8],
58    },
59    DepositListKey(&'a [u8]),
60    VoteListKey(&'a [u8]),
61    // Empty key is used to traverse all key and value pairs.
62    EmptyKey,
63    // Address prefix key is used to search all keys with the same address
64    // prefix, eg [1, 2](0x0102) will search all keys with prefix 0x0102
65    AddressPrefixKey(&'a [u8]),
66}
67
68#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
69pub struct StorageKeyWithSpace<'a> {
70    pub key: StorageKey<'a>,
71    pub space: Space,
72}
73
74impl<'a> StorageKey<'a> {
75    pub const fn with_space(self, space: Space) -> StorageKeyWithSpace<'a> {
76        StorageKeyWithSpace { key: self, space }
77    }
78
79    pub const fn with_native_space(self) -> StorageKeyWithSpace<'a> {
80        self.with_space(Space::Native)
81    }
82
83    pub const fn with_evm_space(self) -> StorageKeyWithSpace<'a> {
84        self.with_space(Space::Ethereum)
85    }
86
87    pub const fn new_account_key(address: &'a Address) -> Self {
88        StorageKey::AccountKey(&address.0)
89    }
90
91    pub const fn new_storage_root_key(address: &'a Address) -> Self {
92        StorageKey::StorageRootKey(&address.0)
93    }
94
95    pub const fn new_storage_key(
96        address: &'a Address, storage_key: &'a [u8],
97    ) -> Self {
98        StorageKey::StorageKey {
99            address_bytes: &address.0,
100            storage_key,
101        }
102    }
103
104    pub fn new_code_root_key(address: &'a Address) -> Self {
105        StorageKey::CodeRootKey(&address.0)
106    }
107
108    pub fn new_code_key(address: &'a Address, code_hash: &'a H256) -> Self {
109        StorageKey::CodeKey {
110            address_bytes: &address.0,
111            code_hash_bytes: &code_hash.0,
112        }
113    }
114
115    pub fn new_deposit_list_key(address: &'a Address) -> Self {
116        StorageKey::DepositListKey(&address.0)
117    }
118
119    pub fn new_vote_list_key(address: &'a Address) -> Self {
120        StorageKey::VoteListKey(&address.0)
121    }
122}
123
124impl<'a> StorageKey<'a> {
125    // Compatible interface with rpc
126    pub fn to_key_bytes(&self) -> Vec<u8> {
127        (*self).with_native_space().to_key_bytes()
128    }
129}
130
131// Conversion methods.
132impl<'a> StorageKeyWithSpace<'a> {
133    pub const ACCOUNT_BYTES: usize = 20;
134    const CODE_HASH_BYTES: usize = 32;
135    const CODE_HASH_PREFIX: &'static [u8] = b"code";
136    const CODE_HASH_PREFIX_LEN: usize = 4;
137    const DEPOSIT_LIST_LEN: usize = 7;
138    const DEPOSIT_LIST_PREFIX: &'static [u8] = b"deposit";
139    pub const EVM_SPACE_TYPE: &'static [u8] = b"\x81";
140    const STORAGE_PREFIX: &'static [u8] = b"data";
141    const STORAGE_PREFIX_LEN: usize = 4;
142    const VOTE_LIST_LEN: usize = 4;
143    const VOTE_LIST_PREFIX: &'static [u8] = b"vote";
144
145    pub fn to_delta_mpt_key_bytes(
146        &self, padding: &DeltaMptKeyPadding,
147    ) -> Vec<u8> {
148        let key_bytes = match self.key {
149            StorageKey::AccountKey(address_bytes) => {
150                if address_bytes.len() == Self::ACCOUNT_BYTES {
151                    delta_mpt_storage_key::new_account_key(
152                        address_bytes,
153                        padding,
154                    )
155                } else if cfg!(feature = "test_no_account_length_check") {
156                    // The branch is test only. When an address with incomplete
157                    // length, it's passed to DeltaMPT directly.
158                    let mut x = Vec::with_capacity(address_bytes.len());
159                    x.extend_from_slice(address_bytes);
160
161                    return x;
162                } else {
163                    unreachable!(
164                        "Invalid account key. Unrecognized: {:?}",
165                        address_bytes
166                    );
167                }
168            }
169            StorageKey::StorageRootKey(address_bytes) => {
170                delta_mpt_storage_key::new_storage_root_key(
171                    address_bytes,
172                    padding,
173                )
174            }
175            StorageKey::StorageKey {
176                address_bytes,
177                storage_key,
178            } => delta_mpt_storage_key::new_storage_key(
179                address_bytes,
180                storage_key,
181                padding,
182            ),
183            StorageKey::CodeRootKey(address_bytes) => {
184                delta_mpt_storage_key::new_code_root_key(address_bytes, padding)
185            }
186            StorageKey::CodeKey {
187                address_bytes,
188                code_hash_bytes,
189            } => delta_mpt_storage_key::new_code_key(
190                address_bytes,
191                code_hash_bytes,
192                padding,
193            ),
194            StorageKey::DepositListKey(address_bytes) => {
195                delta_mpt_storage_key::new_deposit_list_key(
196                    address_bytes,
197                    padding,
198                )
199            }
200            StorageKey::VoteListKey(address_bytes) => {
201                delta_mpt_storage_key::new_vote_list_key(address_bytes, padding)
202            }
203            StorageKey::EmptyKey => {
204                return vec![];
205            }
206            StorageKey::AddressPrefixKey(_address_bytes) => {
207                // delta mpt trie does not support address prefix key search
208                // so we search all keys and filter them by address prefix
209                // due to delta mpt trie won't be very big, so the performance
210                // impact is not very big
211                return vec![];
212            }
213        };
214
215        if self.space == Space::Native {
216            key_bytes
217        } else {
218            // Insert "0x81" at the position 32.
219            [
220                &key_bytes[..ACCOUNT_KEYPART_BYTES],
221                Self::EVM_SPACE_TYPE,
222                &key_bytes[ACCOUNT_KEYPART_BYTES..],
223            ]
224            .concat()
225        }
226    }
227
228    pub fn to_key_bytes(&self) -> Vec<u8> {
229        let key_bytes = match self.key {
230            StorageKey::AccountKey(address_bytes) => {
231                let mut key = Vec::with_capacity(Self::ACCOUNT_BYTES);
232                key.extend_from_slice(address_bytes);
233
234                key
235            }
236            StorageKey::StorageRootKey(address_bytes) => {
237                let mut key = Vec::with_capacity(
238                    Self::ACCOUNT_BYTES + Self::STORAGE_PREFIX_LEN,
239                );
240                key.extend_from_slice(address_bytes);
241                key.extend_from_slice(Self::STORAGE_PREFIX);
242
243                key
244            }
245            StorageKey::StorageKey {
246                address_bytes,
247                storage_key,
248            } => {
249                let mut key = Vec::with_capacity(
250                    Self::ACCOUNT_BYTES
251                        + Self::STORAGE_PREFIX_LEN
252                        + storage_key.len(),
253                );
254                key.extend_from_slice(address_bytes);
255                key.extend_from_slice(Self::STORAGE_PREFIX);
256                key.extend_from_slice(storage_key);
257
258                key
259            }
260            StorageKey::CodeRootKey(address_bytes) => {
261                let mut key = Vec::with_capacity(
262                    Self::ACCOUNT_BYTES + Self::CODE_HASH_PREFIX_LEN,
263                );
264                key.extend_from_slice(address_bytes);
265                key.extend_from_slice(Self::CODE_HASH_PREFIX);
266
267                key
268            }
269            StorageKey::CodeKey {
270                address_bytes,
271                code_hash_bytes,
272            } => {
273                let mut key = Vec::with_capacity(
274                    Self::ACCOUNT_BYTES
275                        + Self::CODE_HASH_PREFIX_LEN
276                        + Self::CODE_HASH_BYTES,
277                );
278                key.extend_from_slice(address_bytes);
279                key.extend_from_slice(Self::CODE_HASH_PREFIX);
280                key.extend_from_slice(code_hash_bytes);
281
282                key
283            }
284            StorageKey::DepositListKey(address_bytes) => {
285                let mut key = Vec::with_capacity(
286                    Self::ACCOUNT_BYTES + Self::DEPOSIT_LIST_LEN,
287                );
288                key.extend_from_slice(address_bytes);
289                key.extend_from_slice(Self::DEPOSIT_LIST_PREFIX);
290
291                key
292            }
293            StorageKey::VoteListKey(address_bytes) => {
294                let mut key = Vec::with_capacity(
295                    Self::ACCOUNT_BYTES + Self::VOTE_LIST_LEN,
296                );
297                key.extend_from_slice(address_bytes);
298                key.extend_from_slice(Self::VOTE_LIST_PREFIX);
299
300                key
301            }
302            StorageKey::EmptyKey => {
303                return vec![];
304            }
305            StorageKey::AddressPrefixKey(address_bytes) => {
306                let mut key = Vec::with_capacity(address_bytes.len());
307                key.extend_from_slice(address_bytes);
308                return key;
309            }
310        };
311
312        if self.space == Space::Native {
313            key_bytes
314        } else {
315            // Insert "0x81" at the position 20.
316            [
317                &key_bytes[..Self::ACCOUNT_BYTES],
318                Self::EVM_SPACE_TYPE,
319                &key_bytes[Self::ACCOUNT_BYTES..],
320            ]
321            .concat()
322        }
323    }
324
325    // from_key_bytes::<CheckInput>(...) returns Result<StorageKey, String>
326    // from_key_bytes::<SkipInputCheck>(...) returns StorageKey, crashes on
327    // error
328    pub fn from_key_bytes<ShouldCheckInput: StaticBool>(
329        bytes: &'a [u8],
330    ) -> <FromKeyBytesResult<ShouldCheckInput> as ConditionalReturnValue<'a>>::Output
331    where FromKeyBytesResult<ShouldCheckInput>: ConditionalReturnValue<'a>{
332        let key = if bytes.len() <= Self::ACCOUNT_BYTES {
333            StorageKey::AccountKey(bytes).with_native_space()
334        } else if bytes.len() == Self::ACCOUNT_BYTES + 1 {
335            StorageKey::AccountKey(&bytes[..Self::ACCOUNT_BYTES])
336                .with_evm_space()
337        } else {
338            let address_bytes = &bytes[0..Self::ACCOUNT_BYTES];
339
340            let extension_bit: bool = bytes[Self::ACCOUNT_BYTES] & 0x80 != 0;
341            let bytes = if extension_bit {
342                // check for incorrect extension byte
343                if ShouldCheckInput::value() == CheckInput::value()
344                    && bytes[Self::ACCOUNT_BYTES] != Self::EVM_SPACE_TYPE[0]
345                {
346                    return <FromKeyBytesResult<ShouldCheckInput> as ConditionalReturnValue<'a>>::from_result(
347                        Err(format!("Unexpected extension byte: {:?}", bytes[Self::ACCOUNT_BYTES]))
348                    );
349                }
350
351                // with `SkipInputCheck`, crash on incorrect extension byte
352                assert_eq!(bytes[Self::ACCOUNT_BYTES], Self::EVM_SPACE_TYPE[0]);
353                &bytes[(Self::ACCOUNT_BYTES + 1)..]
354            } else {
355                &bytes[Self::ACCOUNT_BYTES..]
356            };
357
358            let storage_key_no_space = if bytes
359                .starts_with(Self::STORAGE_PREFIX)
360            {
361                let bytes = &bytes[Self::STORAGE_PREFIX_LEN..];
362                if !bytes.is_empty() {
363                    StorageKey::StorageKey {
364                        address_bytes,
365                        storage_key: bytes,
366                    }
367                } else {
368                    StorageKey::StorageRootKey(address_bytes)
369                }
370            } else if bytes.starts_with(Self::CODE_HASH_PREFIX) {
371                let bytes = &bytes[Self::CODE_HASH_PREFIX_LEN..];
372                if !bytes.is_empty() {
373                    StorageKey::CodeKey {
374                        address_bytes,
375                        code_hash_bytes: bytes,
376                    }
377                } else {
378                    StorageKey::CodeRootKey(address_bytes)
379                }
380            } else if bytes.starts_with(Self::DEPOSIT_LIST_PREFIX) {
381                StorageKey::DepositListKey(address_bytes)
382            } else if bytes.starts_with(Self::VOTE_LIST_PREFIX) {
383                StorageKey::VoteListKey(address_bytes)
384            }
385            // unknown key format => we report an error or crash
386            // depending on the generic parameter
387            else if ShouldCheckInput::value() == CheckInput::value() {
388                return <FromKeyBytesResult<ShouldCheckInput> as ConditionalReturnValue<'a>>::from_result(
389                    Err(format!("Unable to parse storage key: {:?} - {:?}", address_bytes, bytes))
390                );
391            } else {
392                unreachable!(
393                    "Invalid key format. Unrecognized: {:?}, account: {:?}",
394                    bytes, address_bytes
395                );
396            };
397
398            let space = if extension_bit {
399                Space::Ethereum
400            } else {
401                Space::Native
402            };
403
404            storage_key_no_space.with_space(space)
405        };
406
407        <FromKeyBytesResult<ShouldCheckInput> as ConditionalReturnValue<'a>>::from_key(key)
408    }
409}
410
411/// The padding is uniquely generated for DeltaMPT at each intermediate epoch,
412/// and it's used to compute padding bytes for address and storage_key. The
413/// padding setup is against an attack where adversary artificially build deep
414/// paths in MPT.
415#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
416pub struct DeltaMptKeyPadding([u8; delta_mpt_storage_key::KEY_PADDING_BYTES]);
417
418pub use delta_mpt_storage_key::KEY_PADDING_BYTES as DELTA_MPT_KEY_PADDING_BYTES;
419lazy_static! {
420    pub static ref GENESIS_DELTA_MPT_KEY_PADDING: DeltaMptKeyPadding =
421        StorageKeyWithSpace::delta_mpt_padding(
422            &MERKLE_NULL_NODE,
423            &MERKLE_NULL_NODE
424        );
425}
426
427impl Deref for DeltaMptKeyPadding {
428    type Target = [u8; delta_mpt_storage_key::KEY_PADDING_BYTES];
429
430    fn deref(&self) -> &Self::Target { &self.0 }
431}
432
433impl DerefMut for DeltaMptKeyPadding {
434    fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
435}
436
437impl Encodable for DeltaMptKeyPadding {
438    fn rlp_append(&self, s: &mut RlpStream) { s.append_internal(&&self[..]); }
439}
440
441impl Decodable for DeltaMptKeyPadding {
442    fn decode(rlp: &Rlp) -> std::result::Result<Self, DecoderError> {
443        let v = rlp.as_val::<Vec<u8>>()?;
444        let mut array = DeltaMptKeyPadding::default();
445        if v.len() != delta_mpt_storage_key::KEY_PADDING_BYTES {
446            Err(DecoderError::RlpInconsistentLengthAndData)
447        } else {
448            array[..].copy_from_slice(&v);
449            Ok(array)
450        }
451    }
452}
453
454mod delta_mpt_storage_key {
455    use super::*;
456
457    pub const ACCOUNT_KEYPART_BYTES: usize = 32;
458    const ACCOUNT_PADDING_BYTES: usize = 12;
459    pub const KEY_PADDING_BYTES: usize = 32;
460
461    fn new_buffer(uninitialized_size: usize) -> Vec<u8> {
462        vec![0; uninitialized_size]
463
464        // The previous implementation make this function unsafe.
465        // However, the performance gain (avoid initializing a buffer of 32
466        // bytes) is negligible since calling this function is followed by a
467        // hash computation.
468        //
469        // let mut buffer = Vec::with_capacity(uninitialized_size);
470        // unsafe { buffer.set_len(uninitialized_size) }
471        //
472        // buffer
473    }
474
475    fn compute_address_keypart(
476        address: &[u8], padding: &DeltaMptKeyPadding,
477    ) -> [u8; ACCOUNT_KEYPART_BYTES] {
478        // Manually asserting the size by using new_buffer instead of
479        // Vec#extend_from_slice.
480        let mut padded = new_buffer(ACCOUNT_KEYPART_BYTES);
481        padded[..ACCOUNT_PADDING_BYTES]
482            .copy_from_slice(&padding[..ACCOUNT_PADDING_BYTES]);
483        padded[ACCOUNT_PADDING_BYTES..].copy_from_slice(address);
484
485        let mut address_hash = [0u8; ACCOUNT_KEYPART_BYTES];
486        address_hash[..ACCOUNT_PADDING_BYTES]
487            .copy_from_slice(&keccak(padded)[..ACCOUNT_PADDING_BYTES]);
488        address_hash[ACCOUNT_PADDING_BYTES..].copy_from_slice(address);
489
490        address_hash
491    }
492
493    fn compute_storage_key_padding(
494        storage_key: &[u8], padding: &DeltaMptKeyPadding,
495    ) -> DeltaMptKeyPadding {
496        let mut padded =
497            Vec::with_capacity(KEY_PADDING_BYTES + storage_key.len());
498        padded.extend_from_slice(&padding.0);
499        padded.extend_from_slice(storage_key);
500
501        DeltaMptKeyPadding(keccak(padded).0)
502    }
503
504    fn extend_address(
505        key: &mut Vec<u8>, address: &[u8], padding: &DeltaMptKeyPadding,
506    ) {
507        let padded_address = compute_address_keypart(address, padding);
508
509        key.extend_from_slice(padded_address.as_ref());
510    }
511
512    fn extend_key_with_prefix(
513        key: &mut Vec<u8>, address: &[u8], padding: &DeltaMptKeyPadding,
514        prefix: &[u8],
515    ) {
516        extend_address(key, address, padding);
517        key.extend_from_slice(prefix);
518    }
519
520    pub fn new_account_key(
521        address: &[u8], padding: &DeltaMptKeyPadding,
522    ) -> Vec<u8> {
523        let mut key = Vec::with_capacity(ACCOUNT_KEYPART_BYTES);
524        extend_address(&mut key, address, padding);
525
526        key
527    }
528
529    fn extend_storage_key(
530        key: &mut Vec<u8>, storage_key: &[u8], padding: &DeltaMptKeyPadding,
531    ) {
532        key.extend_from_slice(
533            &compute_storage_key_padding(storage_key, padding)
534                [StorageKeyWithSpace::STORAGE_PREFIX_LEN..],
535        );
536        key.extend_from_slice(storage_key);
537    }
538
539    pub fn new_storage_root_key(
540        address: &[u8], padding: &DeltaMptKeyPadding,
541    ) -> Vec<u8> {
542        let mut key = Vec::with_capacity(
543            ACCOUNT_KEYPART_BYTES + StorageKeyWithSpace::STORAGE_PREFIX_LEN,
544        );
545        extend_key_with_prefix(
546            &mut key,
547            address,
548            padding,
549            StorageKeyWithSpace::STORAGE_PREFIX,
550        );
551
552        key
553    }
554
555    pub fn new_storage_key(
556        address: &[u8], storage_key: &[u8], padding: &DeltaMptKeyPadding,
557    ) -> Vec<u8> {
558        let mut key = Vec::with_capacity(
559            ACCOUNT_KEYPART_BYTES + KEY_PADDING_BYTES + storage_key.len(),
560        );
561        extend_key_with_prefix(
562            &mut key,
563            address,
564            padding,
565            StorageKeyWithSpace::STORAGE_PREFIX,
566        );
567        extend_storage_key(&mut key, storage_key, padding);
568
569        key
570    }
571
572    pub fn new_code_root_key(
573        address: &[u8], padding: &DeltaMptKeyPadding,
574    ) -> Vec<u8> {
575        let mut key = Vec::with_capacity(
576            ACCOUNT_KEYPART_BYTES + StorageKeyWithSpace::STORAGE_PREFIX_LEN,
577        );
578        extend_key_with_prefix(
579            &mut key,
580            address,
581            padding,
582            StorageKeyWithSpace::CODE_HASH_PREFIX,
583        );
584
585        key
586    }
587
588    pub fn new_code_key(
589        address: &[u8], code_hash: &[u8], padding: &DeltaMptKeyPadding,
590    ) -> Vec<u8> {
591        let mut key = Vec::with_capacity(
592            ACCOUNT_KEYPART_BYTES
593                + StorageKeyWithSpace::CODE_HASH_PREFIX_LEN
594                + StorageKeyWithSpace::CODE_HASH_BYTES,
595        );
596        extend_key_with_prefix(
597            &mut key,
598            address,
599            padding,
600            StorageKeyWithSpace::CODE_HASH_PREFIX,
601        );
602        key.extend_from_slice(code_hash);
603
604        key
605    }
606
607    pub fn new_deposit_list_key(
608        address: &[u8], padding: &DeltaMptKeyPadding,
609    ) -> Vec<u8> {
610        let mut key = Vec::with_capacity(
611            ACCOUNT_KEYPART_BYTES + StorageKeyWithSpace::DEPOSIT_LIST_LEN,
612        );
613        extend_key_with_prefix(
614            &mut key,
615            address,
616            padding,
617            StorageKeyWithSpace::DEPOSIT_LIST_PREFIX,
618        );
619        key
620    }
621
622    pub fn new_vote_list_key(
623        address: &[u8], padding: &DeltaMptKeyPadding,
624    ) -> Vec<u8> {
625        let mut key = Vec::with_capacity(
626            ACCOUNT_KEYPART_BYTES + StorageKeyWithSpace::VOTE_LIST_LEN,
627        );
628        extend_key_with_prefix(
629            &mut key,
630            address,
631            padding,
632            StorageKeyWithSpace::VOTE_LIST_PREFIX,
633        );
634        key
635    }
636
637    impl<'a> StorageKeyWithSpace<'a> {
638        pub fn delta_mpt_padding(
639            snapshot_root: &MerkleHash, intermediate_delta_root: &MerkleHash,
640        ) -> DeltaMptKeyPadding {
641            let mut buffer = Vec::with_capacity(
642                snapshot_root.0.len() + intermediate_delta_root.0.len(),
643            );
644            buffer.extend_from_slice(&snapshot_root.0);
645            buffer.extend_from_slice(&intermediate_delta_root.0);
646            DeltaMptKeyPadding(keccak(&buffer).0)
647        }
648
649        pub fn from_delta_mpt_key(
650            delta_mpt_key: &'a [u8],
651        ) -> StorageKeyWithSpace<'a> {
652            let remaining_bytes = delta_mpt_key;
653            let bytes_len = remaining_bytes.len();
654            if bytes_len < ACCOUNT_KEYPART_BYTES {
655                if cfg!(feature = "test_no_account_length_check") {
656                    // The branch is test only. When an address with incomplete
657                    // length, it's passed to DeltaMPT directly.
658                    StorageKey::AccountKey(remaining_bytes).with_native_space()
659                } else {
660                    unreachable!(
661                        "Invalid delta mpt key format. Unrecognized: {:?}",
662                        remaining_bytes
663                    );
664                }
665            } else {
666                let address_bytes = &remaining_bytes
667                    [ACCOUNT_PADDING_BYTES..ACCOUNT_KEYPART_BYTES];
668                if bytes_len == ACCOUNT_KEYPART_BYTES {
669                    return StorageKey::AccountKey(address_bytes)
670                        .with_native_space();
671                }
672                if bytes_len == ACCOUNT_KEYPART_BYTES + 1 {
673                    return StorageKey::AccountKey(address_bytes)
674                        .with_evm_space();
675                }
676                let extension_bit =
677                    remaining_bytes[ACCOUNT_KEYPART_BYTES] & 0x80 != 0;
678
679                let remaining_bytes = if extension_bit {
680                    assert_eq!(
681                        remaining_bytes[ACCOUNT_KEYPART_BYTES],
682                        StorageKeyWithSpace::EVM_SPACE_TYPE[0]
683                    );
684                    &remaining_bytes[(ACCOUNT_KEYPART_BYTES + 1)..]
685                } else {
686                    &remaining_bytes[ACCOUNT_KEYPART_BYTES..]
687                };
688
689                let storage_key_no_space = if remaining_bytes
690                    .starts_with(StorageKeyWithSpace::STORAGE_PREFIX)
691                {
692                    if remaining_bytes.len()
693                        == StorageKeyWithSpace::STORAGE_PREFIX_LEN
694                    {
695                        StorageKey::StorageRootKey(address_bytes)
696                    } else {
697                        StorageKey::StorageKey {
698                            address_bytes,
699                            storage_key: &remaining_bytes[KEY_PADDING_BYTES..],
700                        }
701                    }
702                } else if remaining_bytes
703                    .starts_with(StorageKeyWithSpace::CODE_HASH_PREFIX)
704                {
705                    let bytes = &remaining_bytes
706                        [StorageKeyWithSpace::CODE_HASH_PREFIX_LEN..];
707                    if !bytes.is_empty() {
708                        StorageKey::CodeKey {
709                            address_bytes,
710                            code_hash_bytes: bytes,
711                        }
712                    } else {
713                        StorageKey::CodeRootKey(address_bytes)
714                    }
715                } else if remaining_bytes
716                    .starts_with(StorageKeyWithSpace::DEPOSIT_LIST_PREFIX)
717                {
718                    StorageKey::DepositListKey(address_bytes)
719                } else if remaining_bytes
720                    .starts_with(StorageKeyWithSpace::VOTE_LIST_PREFIX)
721                {
722                    StorageKey::VoteListKey(address_bytes)
723                } else {
724                    unreachable!(
725                            "Invalid delta mpt key format. Address {:?}, Unrecognized: {:?}",
726                            address_bytes, remaining_bytes
727                        );
728                };
729
730                let space = if extension_bit {
731                    Space::Ethereum
732                } else {
733                    Space::Native
734                };
735                storage_key_no_space.with_space(space)
736            }
737        }
738    }
739}
740
741// This enum is used to filter only the wanted contract storage key when
742// traversal the trie for example, when traverse eth space key/value, we can
743// only filter the eSpace storage key/value to accelerate the traversal
744// speed
745// Native means filter(keep) the native space storage key/value
746// Ethereum means filter(keep) the ethereum space storage key/value
747#[derive(Debug, Clone, Copy, PartialEq, Eq)]
748pub struct SpaceStorageFilter(pub Space);
749
750impl From<Space> for SpaceStorageFilter {
751    fn from(space: Space) -> Self { SpaceStorageFilter(space) }
752}
753
754impl From<SpaceStorageFilter> for Space {
755    fn from(filter: SpaceStorageFilter) -> Self { filter.0 }
756}
757
758impl SpaceStorageFilter {
759    pub fn is_native(&self) -> bool { matches!(self.0, Space::Native) }
760
761    pub fn is_ethereum(&self) -> bool { matches!(self.0, Space::Ethereum) }
762
763    // return the flag index according the trie type
764    // if is_delta_mpt is true, then the space flag is at the 32th index
765    // otherwise, the space flag is at the 20th index
766    pub fn space_flag_index(is_delta_mpt: bool) -> usize {
767        if is_delta_mpt {
768            delta_mpt_storage_key::KEY_PADDING_BYTES
769        } else {
770            StorageKeyWithSpace::ACCOUNT_BYTES
771        }
772    }
773
774    // return true if the key is filtered out
775    pub fn is_filtered(&self, is_delta_mpt: bool, key: &[u8]) -> bool {
776        let flag_index = Self::space_flag_index(is_delta_mpt);
777        if key.len() > flag_index {
778            match self.0 {
779                Space::Native => {
780                    if key[flag_index] == StorageKeyWithSpace::EVM_SPACE_TYPE[0]
781                    {
782                        return true;
783                    }
784                }
785                Space::Ethereum => {
786                    if key[flag_index] != StorageKeyWithSpace::EVM_SPACE_TYPE[0]
787                    {
788                        return true;
789                    }
790                }
791            }
792        }
793        false
794    }
795}
796
797use super::{MerkleHash, MERKLE_NULL_NODE};
798use crate::{
799    hash::keccak, storage_key::delta_mpt_storage_key::ACCOUNT_KEYPART_BYTES,
800};
801use cfx_types::{Address, Space, H256};
802use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream};
803use serde::{Deserialize, Serialize};
804use std::{
805    convert::AsRef,
806    ops::{Deref, DerefMut},
807    vec::Vec,
808};
809
810#[cfg(test)]
811mod tests {
812    use super::{delta_mpt_storage_key::*, DeltaMptKeyPadding, StorageKey};
813    use crate::StorageKeyWithSpace;
814    use cfx_types::{Address, H256};
815
816    #[test]
817    fn test_delta_mpt_account_key() {
818        let padding = DeltaMptKeyPadding([0; KEY_PADDING_BYTES]);
819
820        let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
821            .parse::<Address>()
822            .unwrap();
823
824        let key = StorageKey::new_account_key(&address).with_native_space();
825        let bytes = key.to_delta_mpt_key_bytes(&padding);
826        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
827        assert_eq!(key, key2);
828
829        let key = StorageKey::new_account_key(&address).with_evm_space();
830        let bytes = key.to_delta_mpt_key_bytes(&padding);
831        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
832        assert_eq!(key, key2);
833    }
834
835    #[test]
836    fn test_delta_mpt_storage_root_key() {
837        let padding = DeltaMptKeyPadding([0; KEY_PADDING_BYTES]);
838
839        let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
840            .parse::<Address>()
841            .unwrap();
842
843        let key =
844            StorageKey::new_storage_root_key(&address).with_native_space();
845        let bytes = key.to_delta_mpt_key_bytes(&padding);
846        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
847        assert_eq!(key, key2);
848
849        let key = StorageKey::new_storage_root_key(&address).with_evm_space();
850        let bytes = key.to_delta_mpt_key_bytes(&padding);
851        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
852        assert_eq!(key, key2);
853    }
854
855    #[test]
856    fn test_delta_mpt_storage_key() {
857        let padding = DeltaMptKeyPadding([0; KEY_PADDING_BYTES]);
858
859        let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
860            .parse::<Address>()
861            .unwrap();
862
863        let storage_key = &[99; 32];
864
865        let key = StorageKey::new_storage_key(&address, storage_key)
866            .with_native_space();
867        let bytes = key.to_delta_mpt_key_bytes(&padding);
868        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
869        assert_eq!(key, key2);
870
871        let key =
872            StorageKey::new_storage_key(&address, storage_key).with_evm_space();
873        let bytes = key.to_delta_mpt_key_bytes(&padding);
874        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
875        assert_eq!(key, key2);
876    }
877
878    #[test]
879    fn test_delta_mpt_code_root_key() {
880        let padding = DeltaMptKeyPadding([0; KEY_PADDING_BYTES]);
881
882        let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
883            .parse::<Address>()
884            .unwrap();
885
886        let key = StorageKey::new_code_root_key(&address).with_native_space();
887        let bytes = key.to_delta_mpt_key_bytes(&padding);
888        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
889        assert_eq!(key, key2);
890
891        let key = StorageKey::new_code_root_key(&address).with_evm_space();
892        let bytes = key.to_delta_mpt_key_bytes(&padding);
893        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
894        assert_eq!(key, key2);
895    }
896
897    #[test]
898    fn test_delta_mpt_code_key() {
899        let padding = DeltaMptKeyPadding([0; KEY_PADDING_BYTES]);
900
901        let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
902            .parse::<Address>()
903            .unwrap();
904
905        let code_hash =
906            "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec66d2d6c7b5ec66d2d6c7b5ec6"
907                .parse::<H256>()
908                .unwrap();
909
910        let key =
911            StorageKey::new_code_key(&address, &code_hash).with_native_space();
912        let bytes = key.to_delta_mpt_key_bytes(&padding);
913        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
914        assert_eq!(key, key2);
915
916        let key =
917            StorageKey::new_code_key(&address, &code_hash).with_evm_space();
918        let bytes = key.to_delta_mpt_key_bytes(&padding);
919        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
920        assert_eq!(key, key2);
921    }
922
923    #[test]
924    fn test_delta_mpt_deposit_list_key() {
925        let padding = DeltaMptKeyPadding([0; KEY_PADDING_BYTES]);
926
927        let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
928            .parse::<Address>()
929            .unwrap();
930
931        let key =
932            StorageKey::new_deposit_list_key(&address).with_native_space();
933        let bytes = key.to_delta_mpt_key_bytes(&padding);
934        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
935        assert_eq!(key, key2);
936
937        let key = StorageKey::new_deposit_list_key(&address).with_evm_space();
938        let bytes = key.to_delta_mpt_key_bytes(&padding);
939        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
940        assert_eq!(key, key2);
941    }
942
943    #[test]
944    fn test_delta_mpt_vote_list_key() {
945        let padding = DeltaMptKeyPadding([0; KEY_PADDING_BYTES]);
946
947        let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
948            .parse::<Address>()
949            .unwrap();
950
951        let key = StorageKey::new_vote_list_key(&address).with_native_space();
952        let bytes = key.to_delta_mpt_key_bytes(&padding);
953        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
954        assert_eq!(key, key2);
955
956        let key = StorageKey::new_vote_list_key(&address).with_evm_space();
957        let bytes = key.to_delta_mpt_key_bytes(&padding);
958        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
959        assert_eq!(key, key2);
960    }
961}