chainwayxyz / citrea

Citrea, Bitcoin's First ZK Rollup 🍊🍋
https://citrea.xyz
GNU General Public License v3.0
95 stars 22 forks source link

R&D: sov_modules_api::StateMap<Address, DbAccount> #1084

Closed kpp closed 2 weeks ago

kpp commented 2 weeks ago

Evm::accounts: StateMap<Address, DbAccount> is roughly equal to:

module_prefix
  key: Address
  value: DbAccount
      AccountInfo {balance, code_hash, nonce}
      storage:  // StateMap<U256, U256>
          prefix // module_prefix/address
      keys: // StateVec<U256>
          prefix // module_prefix/address
          len_value: // StateValue<usize>
              prefix: // module_prefix/address/l
          elems: StateMap<usize, U256>
              prefix: // module_prefix/address/e

Each time we serde DbAccount (we do it in EvmDB.accounts set(&address, &db_account, self.working_set)) we also serde its children prefixes which is not needed at all, because we already have address and we can reconstruct prefixes if that's needed:

  1. when serializing DbAccount serialize only AccountInfo. Drop storage and keys because they don't store any info except for prefixes.
  2. when deserializing DbAccount deserialize only AccountInfo. Reconstruct storage: StateMap and keys: StateVec<U256> with the given prefix module_prefix/address.

Also because DbAccount storage: StateMap<U256, U256> and keys: StateVec<U256, BcsCodec> are unique by keys across all EVM we don't need to store module_prefix.address/ prefix at all, because we may create one unique storage prefix which all storage and keys can use. Let's name it EVMS and save a lot of bytes.

eyusufatik commented 2 weeks ago

storage and keys are not unique accross evm, it's unique for an address

kpp commented 2 weeks ago

DbAccount before:

[crates/evm/src/evm/db_commit.rs:70:13] s = "{\"info\":{\"balance\":\"0xa36bf0\",\"code_hash\":\"0x335b63591435d5cda20c42302c2a9df48f668c519642e35f07098fcd655b5b82\",\"nonce\":1},\"storage\":{\"_phantom\":[null,null],\"codec\":null,\"prefix\":{\"prefix\":{\"inner\":[99,105,116,114,101,97,95,101,118,109,47,69,118,109,47,97,99,99,111,117,110,116,115,47,49,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5]}}},\"keys\":{\"_phantom\":null,\"prefix\":{\"prefix\":{\"inner\":[99,105,116,114,101,97,95,101,118,109,47,69,118,109,47,97,99,99,111,117,110,116,115,47,49,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5]}},\"len_value\":{\"_phantom\":null,\"codec\":null,\"prefix\":{\"prefix\":{\"inner\":[99,105,116,114,101,97,95,101,118,109,47,69,118,109,47,97,99,99,111,117,110,116,115,47,49,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,108]}}},\"elems\":{\"_phantom\":[null,null],\"codec\":null,\"prefix\":{\"prefix\":{\"inner\":[99,105,116,114,101,97,95,101,118,109,47,69,118,109,47,97,99,99,111,117,110,116,115,47,49,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,101]}}}}}"

After:

thread 'tests::call_tests::call_multiple_test' panicked at crates/evm/src/tests/call_tests.rs:108:5:
assertion `left == right` failed
  left: 74
 right: 256