2023-11-01 03:32:09 +00:00
# Nimbus
# Copyright (c) 2023 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
# http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except
# according to those terms.
2023-04-12 12:39:11 +00:00
#[
FIXME - Adam : I feel like this and distinct_tries should either be combined or more clearly separated .
The points of these two files are :
- Have distinct types for the two kinds of tries , because we really don ' t w a n t t o m i x t h e m u p .
- Have an interface with functions like getAccountBytes rather than just get . ( But still just a super - thin wrapper . )
- Have maybeGetWhatever instead of just getWhatever . ( Also assertions . )
- Notice that this makes sense at both the bytes level and the Account / UInt256 level .
] #
import
chronicles ,
2023-09-26 09:21:13 +00:00
eth / [ common , trie / db ] ,
2023-08-04 11:10:09 +00:00
" . " / [ core_db , distinct_tries , storage_types , values_from_bytes ]
2023-04-12 12:39:11 +00:00
# Useful for debugging.
const shouldDoAssertionsForMissingNodes * = false
proc ifNodesExistGetAccountBytes * ( trie : AccountsTrie , address : EthAddress ) : Option [ seq [ byte ] ] =
trie . maybeGetAccountBytes ( address )
proc ifNodesExistGetStorageBytesWithinAccount * ( storageTrie : StorageTrie , slotAsKey : openArray [ byte ] ) : Option [ seq [ byte ] ] =
storageTrie . maybeGetSlotBytes ( slotAsKey )
2023-08-04 11:10:09 +00:00
proc populateDbWithNodes * ( db : CoreDbRef , nodes : seq [ seq [ byte ] ] ) =
2023-04-24 20:59:38 +00:00
error ( " GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG AARDVARK: populateDbWithNodes received nodes, about to populate " , nodes ) # AARDVARK not an error, I just want it to stand out
2023-04-12 12:39:11 +00:00
for nodeBytes in nodes :
let nodeHash = keccakHash ( nodeBytes )
info ( " AARDVARK: populateDbWithNodes about to add node " , nodeHash , nodeBytes )
2023-08-04 11:10:09 +00:00
db . kvt . put ( nodeHash . data , nodeBytes )
2023-04-12 12:39:11 +00:00
2023-04-24 20:59:38 +00:00
# AARDVARK: just make the callers call populateDbWithNodes directly?
2023-08-04 11:10:09 +00:00
proc populateDbWithBranch * ( db : CoreDbRef , branch : seq [ seq [ byte ] ] ) =
2023-04-12 12:39:11 +00:00
for nodeBytes in branch :
let nodeHash = keccakHash ( nodeBytes )
2023-08-04 11:10:09 +00:00
db . kvt . put ( nodeHash . data , nodeBytes )
2023-06-04 06:00:50 +00:00
2023-04-12 12:39:11 +00:00
# Returns a none if there are missing nodes; if the account itself simply
# doesn't exist yet, that's fine and it returns some(newAccount()).
proc ifNodesExistGetAccount * ( trie : AccountsTrie , address : EthAddress ) : Option [ Account ] =
ifNodesExistGetAccountBytes ( trie , address ) . map ( accountFromBytes )
2023-08-04 11:10:09 +00:00
proc maybeGetCode * ( db : CoreDbRef , codeHash : Hash256 ) : Option [ seq [ byte ] ] =
2023-04-12 12:39:11 +00:00
when defined ( geth ) :
2023-09-26 09:21:13 +00:00
if db . isLegacy :
db . kvt . backend . toLegacy . maybeGet ( codeHash . data )
else :
db . kvt . get ( codeHash . data )
2023-04-12 12:39:11 +00:00
else :
2023-09-26 09:21:13 +00:00
if db . isLegacy :
db . kvt . backend . toLegacy . maybeGet ( contractHashKey ( codeHash ) . toOpenArray )
else :
some ( db . kvt . get ( contractHashKey ( codeHash ) . toOpenArray ) )
2023-04-12 12:39:11 +00:00
proc maybeGetCode * ( trie : AccountsTrie , address : EthAddress ) : Option [ seq [ byte ] ] =
let maybeAcc = trie . ifNodesExistGetAccount ( address )
if maybeAcc . isNone :
none [ seq [ byte ] ] ( )
else :
2023-08-04 11:10:09 +00:00
maybeGetCode ( trie . db , maybeAcc . get . codeHash )
2023-04-12 12:39:11 +00:00
proc checkingForMissingNodes_getCode * ( trie : AccountsTrie , address : EthAddress ) : seq [ byte ] =
let m = maybeGetCode ( trie , address )
doAssert ( m . isSome , " missing code for account at " & $ ( address ) )
m . get
proc assertFetchedCode * ( trie : AccountsTrie , address : EthAddress ) =
if shouldDoAssertionsForMissingNodes :
let m = maybeGetCode ( trie , address )
doAssert ( m . isSome , " missing code for account at " & $ ( address ) )
proc ifNodesExistGetStorageWithinAccount * ( storageTrie : StorageTrie , slot : UInt256 ) : Option [ UInt256 ] =
ifNodesExistGetStorageBytesWithinAccount ( storageTrie , createTrieKeyFromSlot ( slot ) ) . map ( slotValueFromBytes )
proc ifNodesExistGetStorage * ( trie : AccountsTrie , address : EthAddress , slot : UInt256 ) : Option [ UInt256 ] =
let maybeAcc = ifNodesExistGetAccount ( trie , address )
if maybeAcc . isNone :
none [ UInt256 ] ( )
else :
ifNodesExistGetStorageWithinAccount ( storageTrieForAccount ( trie , maybeAcc . get ) , slot )
proc hasAllNodesForAccount * ( trie : AccountsTrie , address : EthAddress ) : bool =
ifNodesExistGetAccountBytes ( trie , address ) . isSome
proc hasAllNodesForCode * ( trie : AccountsTrie , address : EthAddress ) : bool =
maybeGetCode ( trie , address ) . isSome
proc hasAllNodesForStorageSlot * ( trie : AccountsTrie , address : EthAddress , slot : UInt256 ) : bool =
ifNodesExistGetStorage ( trie , address , slot ) . isSome
proc assertFetchedStorage * ( trie : AccountsTrie , address : EthAddress , slot : UInt256 ) =
doAssert ( hasAllNodesForStorageSlot ( trie , address , slot ) )