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-06-04 06:00:50 +00:00
eth / [ common ] ,
2023-04-12 12:39:11 +00:00
eth / trie / [ hexary , db , trie_defs ] ,
storage_types ,
. / values_from_bytes ,
. / distinct_tries
# 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 )
proc populateDbWithNodes * ( db : TrieDatabaseRef , 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 )
db . put ( nodeHash . data , nodeBytes )
2023-04-24 20:59:38 +00:00
# AARDVARK: just make the callers call populateDbWithNodes directly?
2023-04-12 12:39:11 +00:00
proc populateDbWithBranch * ( db : TrieDatabaseRef , branch : seq [ seq [ byte ] ] ) =
for nodeBytes in branch :
let nodeHash = keccakHash ( nodeBytes )
db . 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 )
proc maybeGetCode * ( db : TrieDatabaseRef , codeHash : Hash256 ) : Option [ seq [ byte ] ] =
when defined ( geth ) :
return db . maybeGet ( codeHash . data )
else :
return db . maybeGet ( contractHashKey ( codeHash ) . toOpenArray )
proc maybeGetCode * ( trie : AccountsTrie , address : EthAddress ) : Option [ seq [ byte ] ] =
let maybeAcc = trie . ifNodesExistGetAccount ( address )
if maybeAcc . isNone :
none [ seq [ byte ] ] ( )
else :
maybeGetCode ( SecureHexaryTrie ( trie ) . db , maybeAcc . get . codeHash )
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 ) )