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.clone().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        return 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        return 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.len() > 0 {
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.len() > 0 {
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                    return StorageKey::AccountKey(remaining_bytes)
659                        .with_native_space();
660                } else {
661                    unreachable!(
662                        "Invalid delta mpt key format. Unrecognized: {:?}",
663                        remaining_bytes
664                    );
665                }
666            } else {
667                let address_bytes = &remaining_bytes
668                    [ACCOUNT_PADDING_BYTES..ACCOUNT_KEYPART_BYTES];
669                if bytes_len == ACCOUNT_KEYPART_BYTES {
670                    return StorageKey::AccountKey(address_bytes)
671                        .with_native_space();
672                }
673                if bytes_len == ACCOUNT_KEYPART_BYTES + 1 {
674                    return StorageKey::AccountKey(address_bytes)
675                        .with_evm_space();
676                }
677                let extension_bit =
678                    remaining_bytes[ACCOUNT_KEYPART_BYTES] & 0x80 != 0;
679
680                let remaining_bytes = if extension_bit {
681                    assert_eq!(
682                        remaining_bytes[ACCOUNT_KEYPART_BYTES],
683                        StorageKeyWithSpace::EVM_SPACE_TYPE[0]
684                    );
685                    &remaining_bytes[(ACCOUNT_KEYPART_BYTES + 1)..]
686                } else {
687                    &remaining_bytes[ACCOUNT_KEYPART_BYTES..]
688                };
689
690                let storage_key_no_space = if remaining_bytes
691                    .starts_with(StorageKeyWithSpace::STORAGE_PREFIX)
692                {
693                    if remaining_bytes.len()
694                        == StorageKeyWithSpace::STORAGE_PREFIX_LEN
695                    {
696                        StorageKey::StorageRootKey(address_bytes)
697                    } else {
698                        StorageKey::StorageKey {
699                            address_bytes,
700                            storage_key: &remaining_bytes[KEY_PADDING_BYTES..],
701                        }
702                    }
703                } else if remaining_bytes
704                    .starts_with(StorageKeyWithSpace::CODE_HASH_PREFIX)
705                {
706                    let bytes = &remaining_bytes
707                        [StorageKeyWithSpace::CODE_HASH_PREFIX_LEN..];
708                    if bytes.len() > 0 {
709                        StorageKey::CodeKey {
710                            address_bytes,
711                            code_hash_bytes: bytes,
712                        }
713                    } else {
714                        StorageKey::CodeRootKey(address_bytes)
715                    }
716                } else if remaining_bytes
717                    .starts_with(StorageKeyWithSpace::DEPOSIT_LIST_PREFIX)
718                {
719                    StorageKey::DepositListKey(address_bytes)
720                } else if remaining_bytes
721                    .starts_with(StorageKeyWithSpace::VOTE_LIST_PREFIX)
722                {
723                    StorageKey::VoteListKey(address_bytes)
724                } else {
725                    unreachable!(
726                            "Invalid delta mpt key format. Address {:?}, Unrecognized: {:?}",
727                            address_bytes, remaining_bytes
728                        );
729                };
730
731                let space = if extension_bit {
732                    Space::Ethereum
733                } else {
734                    Space::Native
735                };
736                storage_key_no_space.with_space(space)
737            }
738        }
739    }
740}
741
742// This enum is used to filter only the wanted contract storage key when
743// traversal the trie for example, when traverse eth space key/value, we can
744// only filter the eSpace storage key/value to accelerate the traversal
745// speed
746// Native means filter(keep) the native space storage key/value
747// Ethereum means filter(keep) the ethereum space storage key/value
748#[derive(Debug, Clone, Copy, PartialEq, Eq)]
749pub struct SpaceStorageFilter(pub Space);
750
751impl From<Space> for SpaceStorageFilter {
752    fn from(space: Space) -> Self { SpaceStorageFilter(space) }
753}
754
755impl From<SpaceStorageFilter> for Space {
756    fn from(filter: SpaceStorageFilter) -> Self { filter.0 }
757}
758
759impl SpaceStorageFilter {
760    pub fn is_native(&self) -> bool { matches!(self.0, Space::Native) }
761
762    pub fn is_ethereum(&self) -> bool { matches!(self.0, Space::Ethereum) }
763
764    // return the flag index according the trie type
765    // if is_delta_mpt is true, then the space flag is at the 32th index
766    // otherwise, the space flag is at the 20th index
767    pub fn space_flag_index(is_delta_mpt: bool) -> usize {
768        if is_delta_mpt {
769            delta_mpt_storage_key::KEY_PADDING_BYTES
770        } else {
771            StorageKeyWithSpace::ACCOUNT_BYTES
772        }
773    }
774
775    // return true if the key is filtered out
776    pub fn is_filtered(&self, is_delta_mpt: bool, key: &[u8]) -> bool {
777        let flag_index = Self::space_flag_index(is_delta_mpt);
778        if key.len() > flag_index {
779            match self.0 {
780                Space::Native => {
781                    if key[flag_index] == StorageKeyWithSpace::EVM_SPACE_TYPE[0]
782                    {
783                        return true;
784                    }
785                }
786                Space::Ethereum => {
787                    if key[flag_index] != StorageKeyWithSpace::EVM_SPACE_TYPE[0]
788                    {
789                        return true;
790                    }
791                }
792            }
793        }
794        false
795    }
796}
797
798use super::{MerkleHash, MERKLE_NULL_NODE};
799use crate::{
800    hash::keccak, storage_key::delta_mpt_storage_key::ACCOUNT_KEYPART_BYTES,
801};
802use cfx_types::{Address, Space, H256};
803use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream};
804use serde::{Deserialize, Serialize};
805use std::{
806    convert::AsRef,
807    ops::{Deref, DerefMut},
808    vec::Vec,
809};
810
811#[cfg(test)]
812mod tests {
813    use super::{delta_mpt_storage_key::*, DeltaMptKeyPadding, StorageKey};
814    use crate::StorageKeyWithSpace;
815    use cfx_types::{Address, H256};
816
817    #[test]
818    fn test_delta_mpt_account_key() {
819        let padding = DeltaMptKeyPadding([0; KEY_PADDING_BYTES]);
820
821        let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
822            .parse::<Address>()
823            .unwrap();
824
825        let key = StorageKey::new_account_key(&address).with_native_space();
826        let bytes = key.to_delta_mpt_key_bytes(&padding);
827        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
828        assert_eq!(key, key2);
829
830        let key = StorageKey::new_account_key(&address).with_evm_space();
831        let bytes = key.to_delta_mpt_key_bytes(&padding);
832        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
833        assert_eq!(key, key2);
834    }
835
836    #[test]
837    fn test_delta_mpt_storage_root_key() {
838        let padding = DeltaMptKeyPadding([0; KEY_PADDING_BYTES]);
839
840        let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
841            .parse::<Address>()
842            .unwrap();
843
844        let key =
845            StorageKey::new_storage_root_key(&address).with_native_space();
846        let bytes = key.to_delta_mpt_key_bytes(&padding);
847        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
848        assert_eq!(key, key2);
849
850        let key = StorageKey::new_storage_root_key(&address).with_evm_space();
851        let bytes = key.to_delta_mpt_key_bytes(&padding);
852        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
853        assert_eq!(key, key2);
854    }
855
856    #[test]
857    fn test_delta_mpt_storage_key() {
858        let padding = DeltaMptKeyPadding([0; KEY_PADDING_BYTES]);
859
860        let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
861            .parse::<Address>()
862            .unwrap();
863
864        let storage_key = &[99; 32];
865
866        let key = StorageKey::new_storage_key(&address, storage_key)
867            .with_native_space();
868        let bytes = key.to_delta_mpt_key_bytes(&padding);
869        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
870        assert_eq!(key, key2);
871
872        let key =
873            StorageKey::new_storage_key(&address, storage_key).with_evm_space();
874        let bytes = key.to_delta_mpt_key_bytes(&padding);
875        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
876        assert_eq!(key, key2);
877    }
878
879    #[test]
880    fn test_delta_mpt_code_root_key() {
881        let padding = DeltaMptKeyPadding([0; KEY_PADDING_BYTES]);
882
883        let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
884            .parse::<Address>()
885            .unwrap();
886
887        let key = StorageKey::new_code_root_key(&address).with_native_space();
888        let bytes = key.to_delta_mpt_key_bytes(&padding);
889        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
890        assert_eq!(key, key2);
891
892        let key = StorageKey::new_code_root_key(&address).with_evm_space();
893        let bytes = key.to_delta_mpt_key_bytes(&padding);
894        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
895        assert_eq!(key, key2);
896    }
897
898    #[test]
899    fn test_delta_mpt_code_key() {
900        let padding = DeltaMptKeyPadding([0; KEY_PADDING_BYTES]);
901
902        let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
903            .parse::<Address>()
904            .unwrap();
905
906        let code_hash =
907            "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec66d2d6c7b5ec66d2d6c7b5ec6"
908                .parse::<H256>()
909                .unwrap();
910
911        let key =
912            StorageKey::new_code_key(&address, &code_hash).with_native_space();
913        let bytes = key.to_delta_mpt_key_bytes(&padding);
914        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
915        assert_eq!(key, key2);
916
917        let key =
918            StorageKey::new_code_key(&address, &code_hash).with_evm_space();
919        let bytes = key.to_delta_mpt_key_bytes(&padding);
920        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
921        assert_eq!(key, key2);
922    }
923
924    #[test]
925    fn test_delta_mpt_deposit_list_key() {
926        let padding = DeltaMptKeyPadding([0; KEY_PADDING_BYTES]);
927
928        let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
929            .parse::<Address>()
930            .unwrap();
931
932        let key =
933            StorageKey::new_deposit_list_key(&address).with_native_space();
934        let bytes = key.to_delta_mpt_key_bytes(&padding);
935        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
936        assert_eq!(key, key2);
937
938        let key = StorageKey::new_deposit_list_key(&address).with_evm_space();
939        let bytes = key.to_delta_mpt_key_bytes(&padding);
940        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
941        assert_eq!(key, key2);
942    }
943
944    #[test]
945    fn test_delta_mpt_vote_list_key() {
946        let padding = DeltaMptKeyPadding([0; KEY_PADDING_BYTES]);
947
948        let address = "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6"
949            .parse::<Address>()
950            .unwrap();
951
952        let key = StorageKey::new_vote_list_key(&address).with_native_space();
953        let bytes = key.to_delta_mpt_key_bytes(&padding);
954        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
955        assert_eq!(key, key2);
956
957        let key = StorageKey::new_vote_list_key(&address).with_evm_space();
958        let bytes = key.to_delta_mpt_key_bytes(&padding);
959        let key2 = StorageKeyWithSpace::from_delta_mpt_key(&bytes[..]);
960        assert_eq!(key, key2);
961    }
962}