2023-11-01 10:32:09 +07:00
# Nimbus
2024-01-12 22:06:19 +01:00
# Copyright (c) 2023-2024 Status Research & Development GmbH
2023-11-01 10:32:09 +07:00
# 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-03-10 17:16:42 -05:00
import
2023-08-04 12:10:09 +01:00
std / [ sequtils , typetraits , options , times ] ,
2023-03-10 17:16:42 -05:00
chronicles ,
chronos ,
nimcrypto ,
stint ,
stew / byteutils ,
json_rpc / rpcclient ,
eth / common ,
eth / rlp ,
2023-08-04 12:10:09 +01:00
eth / trie / hexary_proof_verification ,
2023-03-10 17:16:42 -05:00
eth / p2p ,
eth / p2p / rlpx ,
eth / p2p / private / p2p_types ,
2024-02-16 16:08:07 +07:00
#../../../sync/protocol,
2023-08-04 12:10:09 +01:00
.. / .. / .. / db / [ core_db , distinct_tries , incomplete_db , storage_types ] ,
2023-12-08 16:35:50 +07:00
.. / data_sources ,
2024-01-13 08:41:57 +07:00
.. / .. / .. / beacon / web3_eth_conv ,
web3 / conversions ,
web3
2023-04-12 08:39:11 -04:00
2023-03-10 17:16:42 -05:00
export AsyncOperationFactory , AsyncDataSource
2024-01-13 08:41:57 +07:00
type
BlockHeader = eth_types . BlockHeader
2023-04-12 08:39:11 -04:00
var durationSpentDoingFetches * : times . Duration
var fetchCounter * : int
proc makeAnRpcClient * ( web3Url : string ) : Future [ RpcClient ] {. async . } =
let myWeb3 : Web3 = waitFor ( newWeb3 ( web3Url ) )
return myWeb3 . provider
func blockHeaderFromBlockObject ( o : BlockObject ) : BlockHeader =
let nonce : BlockNonce = if o . nonce . isSome : distinctBase ( o . nonce . get ) else : default ( BlockNonce )
BlockHeader (
2023-12-08 16:35:50 +07:00
parentHash : o . parentHash . ethHash ,
ommersHash : o . sha3Uncles . ethHash ,
coinbase : o . miner . ethAddr ,
stateRoot : o . stateRoot . ethHash ,
txRoot : o . transactionsRoot . ethHash ,
receiptRoot : o . receiptsRoot . ethHash ,
2023-04-12 08:39:11 -04:00
bloom : distinctBase ( o . logsBloom ) ,
difficulty : o . difficulty ,
2023-12-08 16:35:50 +07:00
blockNumber : o . number . u256 ,
gasLimit : GasInt ( distinctBase ( o . gasLimit ) ) ,
gasUsed : GasInt ( distinctBase ( o . gasUsed ) ) ,
2023-10-18 09:16:11 +07:00
timestamp : EthTime ( distinctBase ( o . timestamp ) ) ,
2023-04-12 08:39:11 -04:00
extraData : distinctBase ( o . extraData ) ,
2023-12-08 16:35:50 +07:00
#mixDigest: o.mixHash.ethHash, # AARDVARK what's this?
2023-04-12 08:39:11 -04:00
nonce : nonce ,
fee : o . baseFeePerGas ,
2023-12-08 16:35:50 +07:00
withdrawalsRoot : ethHash o . withdrawalsRoot ,
blobGasUsed : u64 o . blobGasUsed ,
excessBlobGas : u64 o . excessBlobGas
2023-04-12 08:39:11 -04:00
)
2023-12-08 16:35:50 +07:00
proc fetchBlockHeaderWithHash * ( rpcClient : RpcClient , h : common . Hash256 ) : Future [ common . BlockHeader ] {. async . } =
2023-04-12 08:39:11 -04:00
let t0 = now ( )
2023-12-08 16:35:50 +07:00
let blockObject : BlockObject = await rpcClient . eth_getBlockByHash ( h . w3Hash , false )
2023-04-12 08:39:11 -04:00
durationSpentDoingFetches + = now ( ) - t0
fetchCounter + = 1
return blockHeaderFromBlockObject ( blockObject )
2023-12-08 16:35:50 +07:00
proc fetchBlockHeaderWithNumber * ( rpcClient : RpcClient , n : common . BlockNumber ) : Future [ common . BlockHeader ] {. async . } =
2023-04-12 08:39:11 -04:00
let t0 = now ( )
2024-03-21 08:05:22 +07:00
let bid = blockId ( w3BlockNumber n )
2023-04-12 08:39:11 -04:00
let blockObject : BlockObject = await rpcClient . eth_getBlockByNumber ( bid , false )
durationSpentDoingFetches + = now ( ) - t0
fetchCounter + = 1
return blockHeaderFromBlockObject ( blockObject )
2024-04-12 11:21:17 +00:00
# Cruft moved to `json_rpc_data_source/currently_unused.nim`
2023-04-12 08:39:11 -04:00
2023-12-08 16:35:50 +07:00
proc fetchBlockHeaderAndBodyWithHash * ( rpcClient : RpcClient , h : common . Hash256 ) : Future [ ( common . BlockHeader , BlockBody ) ] {. async . } =
2023-04-12 08:39:11 -04:00
doAssert ( false , " AARDVARK not implemented " )
2023-12-08 16:35:50 +07:00
proc fetchBlockHeaderAndBodyWithNumber * ( rpcClient : RpcClient , n : common . BlockNumber ) : Future [ ( common . BlockHeader , BlockBody ) ] {. async . } =
2023-04-12 08:39:11 -04:00
doAssert ( false , " AARDVARK not implemented " )
func mdigestFromFixedBytes * ( arg : FixedBytes [ 32 ] ) : MDigest [ 256 ] =
MDigest [ 256 ] ( data : distinctBase ( arg ) )
func mdigestFromString * ( s : string ) : MDigest [ 256 ] =
mdigestFromFixedBytes ( FixedBytes [ 32 ] . fromHex ( s ) )
type
AccountProof * = seq [ seq [ byte ] ]
2023-12-08 16:35:50 +07:00
proc fetchAccountAndSlots * ( rpcClient : RpcClient , address : EthAddress , slots : seq [ UInt256 ] , blockNumber : common . BlockNumber ) : Future [ ( Account , AccountProof , seq [ StorageProof ] ) ] {. async . } =
2023-04-12 08:39:11 -04:00
let t0 = now ( )
debug " Got to fetchAccountAndSlots " , address = address , slots = slots , blockNumber = blockNumber
2024-02-16 16:08:07 +07:00
#let blockNumberUint64 = blockNumber.truncate(uint64)
2023-04-12 08:39:11 -04:00
let a = web3 . Address ( address )
2024-03-21 08:05:22 +07:00
let bid = blockId ( w3BlockNumber blockNumber )
2023-04-12 08:39:11 -04:00
debug " About to call eth_getProof " , address = address , slots = slots , blockNumber = blockNumber
let proofResponse : ProofResponse = await rpcClient . eth_getProof ( a , slots , bid )
debug " Received response to eth_getProof " , proofResponse = proofResponse
2023-05-10 18:04:35 +02:00
2023-04-12 08:39:11 -04:00
let acc = Account (
nonce : distinctBase ( proofResponse . nonce ) ,
balance : proofResponse . balance ,
storageRoot : mdigestFromFixedBytes ( proofResponse . storageHash ) ,
codeHash : mdigestFromFixedBytes ( proofResponse . codeHash )
)
debug " Parsed response to eth_getProof " , acc = acc
let mptNodesBytes : seq [ seq [ byte ] ] = proofResponse . accountProof . mapIt ( distinctBase ( it ) )
durationSpentDoingFetches + = now ( ) - t0
fetchCounter + = 1
return ( acc , mptNodesBytes , proofResponse . storageProof )
2023-12-08 16:35:50 +07:00
proc fetchCode * ( client : RpcClient , blockNumber : common . BlockNumber , address : EthAddress ) : Future [ seq [ byte ] ] {. async . } =
2023-04-12 08:39:11 -04:00
let t0 = now ( )
let a = web3 . Address ( address )
2024-03-21 08:05:22 +07:00
let bid = blockId ( w3BlockNumber blockNumber )
2023-04-12 08:39:11 -04:00
let fetchedCode : seq [ byte ] = await client . eth_getCode ( a , bid )
durationSpentDoingFetches + = now ( ) - t0
fetchCounter + = 1
return fetchedCode
2024-04-12 11:21:17 +00:00
# Cruft moved to json_rpc_data_source/currently_unused.nim
2023-04-12 08:39:11 -04:00
2023-12-08 16:35:50 +07:00
proc verifyFetchedAccount ( stateRoot : common . Hash256 , address : EthAddress , acc : Account , accProof : seq [ seq [ byte ] ] ) : Result [ void , string ] =
2023-03-10 17:16:42 -05:00
let accKey = toSeq ( keccakHash ( address ) . data )
let accEncoded = rlp . encode ( acc )
let accProofResult = verifyMptProof ( accProof , stateRoot , accKey , accEncoded )
case accProofResult . kind
of ValidProof :
return ok ( )
of MissingKey :
# For an account that doesn't exist yet, which is fine.
return ok ( )
of InvalidProof :
return err ( accProofResult . errorMsg )
type
2023-12-08 16:35:50 +07:00
CodeFetchingInfo = tuple [ blockNumber : common . BlockNumber , address : EthAddress ]
2023-03-10 17:16:42 -05:00
proc fetchCode ( client : RpcClient , p : CodeFetchingInfo ) : Future [ seq [ byte ] ] {. async . } =
let ( blockNumber , address ) = p
let fetchedCode = await fetchCode ( client , blockNumber , address )
return fetchedCode
2023-12-08 16:35:50 +07:00
proc verifyFetchedCode ( fetchedCode : seq [ byte ] , desiredCodeHash : common . Hash256 ) : Result [ void , common . Hash256 ] =
2023-03-10 17:16:42 -05:00
let fetchedCodeHash = keccakHash ( fetchedCode )
2023-06-04 13:00:50 +07:00
if desiredCodeHash = = fetchedCodeHash :
ok ( )
2023-03-10 17:16:42 -05:00
else :
err ( fetchedCodeHash )
2023-12-08 16:35:50 +07:00
proc fetchAndVerifyCode ( client : RpcClient , p : CodeFetchingInfo , desiredCodeHash : common . Hash256 ) : Future [ seq [ byte ] ] {. async . } =
2023-03-10 17:16:42 -05:00
let fetchedCode : seq [ byte ] = await fetchCode ( client , p )
let verificationRes = verifyFetchedCode ( fetchedCode , desiredCodeHash )
if verificationRes . isOk ( ) :
return fetchedCode
else :
let fetchedCodeHash = verificationRes . error
error ( " code hash values do not match " , p = p , desiredCodeHash = desiredCodeHash , fetchedCodeHash = fetchedCodeHash )
raise newException ( CatchableError , " async code received code for " & $ ( p . address ) & " whose hash ( " & $ ( fetchedCodeHash ) & " ) does not match the desired hash ( " & $ ( desiredCodeHash ) & " ) " )
2023-12-08 16:35:50 +07:00
proc putCode * ( db : CoreDbRef , codeHash : common . Hash256 , code : seq [ byte ] ) =
2023-04-12 08:39:11 -04:00
when defined ( geth ) :
2023-08-04 12:10:09 +01:00
db . kvt . put ( codeHash . data , code )
2023-04-12 08:39:11 -04:00
else :
2023-08-04 12:10:09 +01:00
db . kvt . put ( contractHashKey ( codeHash ) . toOpenArray , code )
2023-04-12 08:39:11 -04:00
2023-12-08 16:35:50 +07:00
proc putCode * ( trie : AccountsTrie , codeHash : common . Hash256 , code : seq [ byte ] ) =
2023-08-04 12:10:09 +01:00
putCode ( trie . db , codeHash , code )
2023-04-12 08:39:11 -04:00
2023-12-08 16:35:50 +07:00
proc storeCode ( trie : AccountsTrie , p : CodeFetchingInfo , desiredCodeHash : common . Hash256 , fetchedCode : seq [ byte ] ) =
2023-03-10 17:16:42 -05:00
trie . putCode ( desiredCodeHash , fetchedCode )
2023-12-08 16:35:50 +07:00
proc assertThatWeHaveStoredCode ( trie : AccountsTrie , p : CodeFetchingInfo , codeHash : common . Hash256 ) =
2023-03-10 17:16:42 -05:00
# FIXME-Adam: this is a bit wrong because we're not checking it against the blockNumber, only the address. (That is,
# if the code for this address has *changed* (which is unlikely), this check isn't the right thing to do.)
let maybeFoundCode = trie . maybeGetCode ( p . address )
if maybeFoundCode . isNone :
error ( " code didn ' t get put into the db " , p = p , codeHash = codeHash )
doAssert false , " code didn ' t get put into the db "
else :
let foundCode = maybeFoundCode . get
let foundCodeHash = keccakHash ( foundCode )
if foundCodeHash ! = codeHash :
error ( " code does not have the right hash " , p = p , codeHash = codeHash , foundCode = foundCode )
doAssert false , " code does not have the right hash "
proc assertThatWeHaveStoredAccount ( trie : AccountsTrie , address : EthAddress , fetchedAcc : Account , isForTheNewTrie : bool = false ) =
let foundAcc = ifNodesExistGetAccount ( trie , address ) . get
if fetchedAcc ! = foundAcc :
error " account didn ' t come out the same " , address = address , fetchedAcc = fetchedAcc , foundAcc = foundAcc , isForTheNewTrie = isForTheNewTrie
doAssert false , " account didn ' t come out the same "
doAssert ( trie . hasAllNodesForAccount ( address ) , " Can I check the account this way, too? " )
2023-05-10 18:04:35 +02:00
2023-12-08 16:35:50 +07:00
proc verifyFetchedSlot ( accountStorageRoot : common . Hash256 , slot : UInt256 , fetchedVal : UInt256 , storageMptNodes : seq [ seq [ byte ] ] ) : Result [ void , string ] =
2023-03-10 17:16:42 -05:00
if storageMptNodes . len = = 0 :
# I think an empty storage proof is okay; I see lots of these
# where the account is empty and the value is zero.
return ok ( )
else :
let storageKey = toSeq ( keccakHash ( toBytesBE ( slot ) ) . data )
let storageValueEncoded = rlp . encode ( fetchedVal )
let storageProofResult = verifyMptProof ( storageMptNodes , accountStorageRoot , storageKey , storageValueEncoded )
case storageProofResult . kind
of ValidProof :
return ok ( )
of MissingKey :
# This is for a slot that doesn't have anything stored at it, but that's fine.
return ok ( )
of InvalidProof :
return err ( storageProofResult . errorMsg )
2023-12-08 16:35:50 +07:00
proc assertThatWeHaveStoredSlot ( trie : AccountsTrie , address : EthAddress , acc : Account , slot : common . UInt256 , fetchedVal : UInt256 , isForTheNewTrie : bool = false ) =
2023-03-10 17:16:42 -05:00
if acc . storageRoot = = EMPTY_ROOT_HASH and fetchedVal . isZero :
# I believe this is okay.
discard
else :
let foundVal = ifNodesExistGetStorage ( trie , address , slot ) . get
if ( fetchedVal ! = foundVal ) :
error ( " slot didn ' t come out the same " , address = address , slot = slot , fetchedVal = fetchedVal , foundVal = foundVal , isForTheNewTrie = isForTheNewTrie )
doAssert false , " slot didn ' t come out the same "
2023-12-08 16:35:50 +07:00
proc verifyFetchedBlockHeader ( fetchedHeader : common . BlockHeader , desiredBlockNumber : common . BlockNumber ) : Result [ void , common . BlockNumber ] =
2023-03-10 17:16:42 -05:00
# *Can* we do anything to verify this header, given that all we know
# is the desiredBlockNumber and we want to run statelessly so we don't
# know what block hash we want?
2023-06-04 13:00:50 +07:00
ok ( )
2023-03-10 17:16:42 -05:00
2023-12-08 16:35:50 +07:00
proc storeBlockHeader ( chainDB : CoreDbRef , header : common . BlockHeader ) =
2023-03-10 17:16:42 -05:00
chainDB . persistHeaderToDbWithoutSetHeadOrScore ( header )
2023-12-08 16:35:50 +07:00
proc assertThatWeHaveStoredBlockHeader ( chainDB : CoreDbRef , blockNumber : common . BlockNumber , header : common . BlockHeader ) =
2023-03-10 17:16:42 -05:00
let h = chainDB . getBlockHash ( blockNumber )
doAssert ( h = = header . blockHash , " stored the block header for block " & $ ( blockNumber ) )
2023-04-12 08:39:11 -04:00
proc raiseExceptionIfError [ V , E ] ( whatAreWeVerifying : V , r : Result [ void , E ] ) =
2023-03-10 17:16:42 -05:00
if r . isErr :
error ( " async code failed to verify " , whatAreWeVerifying = whatAreWeVerifying , err = r . error )
raise newException ( CatchableError , " async code failed to verify: " & $ ( whatAreWeVerifying ) & " , error is: " & $ ( r . error ) )
const shouldDoUnnecessarySanityChecks = true
# This proc fetches both the account and also optionally some of its slots, because that's what eth_getProof can do.
2023-12-08 16:35:50 +07:00
proc ifNecessaryGetAccountAndSlots * ( client : RpcClient , db : CoreDbRef , blockNumber : common . BlockNumber , stateRoot : common . Hash256 , address : EthAddress , slots : seq [ UInt256 ] , justCheckingAccount : bool , justCheckingSlots : bool , newStateRootForSanityChecking : common . Hash256 ) : Future [ void ] {. async . } =
2023-03-10 17:16:42 -05:00
let trie = initAccountsTrie ( db , stateRoot , false ) # important for sanity checks
let trie2 = initAccountsTrie ( db , newStateRootForSanityChecking , false ) # important for sanity checks
let doesAccountActuallyNeedToBeFetched = not trie . hasAllNodesForAccount ( address )
let slotsToActuallyFetch = slots . filter ( proc ( slot : UInt256 ) : bool = not ( trie . hasAllNodesForStorageSlot ( address , slot ) ) )
if ( not doesAccountActuallyNeedToBeFetched ) and ( slotsToActuallyFetch . len = = 0 ) :
# Already have them, no need to fetch either the account or the slots
discard
else :
let ( acc , accProof , storageProofs ) = await fetchAccountAndSlots ( client , address , slotsToActuallyFetch , blockNumber )
# We need to verify the proof even if we already had this account,
# to make sure the data is valid.
let accountVerificationRes = verifyFetchedAccount ( stateRoot , address , acc , accProof )
let whatAreWeVerifying = ( " account proof " , address , acc )
raiseExceptionIfError ( whatAreWeVerifying , accountVerificationRes )
if not doesAccountActuallyNeedToBeFetched :
# We already had the account, no need to populate the DB with it again.
discard
else :
if not justCheckingAccount :
populateDbWithBranch ( db , accProof )
if shouldDoUnnecessarySanityChecks :
assertThatWeHaveStoredAccount ( trie , address , acc , false )
if doesAccountActuallyNeedToBeFetched : # this second check makes no sense if it's not the first time
assertThatWeHaveStoredAccount ( trie2 , address , acc , true )
doAssert ( slotsToActuallyFetch . len = = storageProofs . len , " We should get back the same number of storage proofs as slots that we asked for. I think. " )
for storageProof in storageProofs :
2023-04-12 08:39:11 -04:00
let slot : UInt256 = storageProof . key
let fetchedVal : UInt256 = storageProof . value
let storageMptNodes : seq [ seq [ byte ] ] = storageProof . proof . mapIt ( distinctBase ( it ) )
2023-03-10 17:16:42 -05:00
let storageVerificationRes = verifyFetchedSlot ( acc . storageRoot , slot , fetchedVal , storageMptNodes )
let whatAreWeVerifying = ( " storage proof " , address , acc , slot , fetchedVal )
raiseExceptionIfError ( whatAreWeVerifying , storageVerificationRes )
if not justCheckingSlots :
populateDbWithBranch ( db , storageMptNodes )
# I believe this is done so that we can iterate over the slots. See
2023-12-12 19:12:56 +00:00
# persistStorage in `db/ledger`.
2023-03-10 17:16:42 -05:00
let slotAsKey = createTrieKeyFromSlot ( slot )
let slotHash = keccakHash ( slotAsKey )
let slotEncoded = rlp . encode ( slot )
2023-08-04 12:10:09 +01:00
db . kvt . put ( slotHashToSlotKey ( slotHash . data ) . toOpenArray , slotEncoded )
2023-03-10 17:16:42 -05:00
if shouldDoUnnecessarySanityChecks :
assertThatWeHaveStoredSlot ( trie , address , acc , slot , fetchedVal , false )
assertThatWeHaveStoredSlot ( trie2 , address , acc , slot , fetchedVal , true )
2023-12-08 16:35:50 +07:00
proc ifNecessaryGetCode * ( client : RpcClient , db : CoreDbRef , blockNumber : common . BlockNumber , stateRoot : common . Hash256 , address : EthAddress , justChecking : bool , newStateRootForSanityChecking : common . Hash256 ) : Future [ void ] {. async . } =
2023-03-10 17:16:42 -05:00
await ifNecessaryGetAccountAndSlots ( client , db , blockNumber , stateRoot , address , @ [ ] , false , false , newStateRootForSanityChecking ) # to make sure we've got the codeHash
let trie = initAccountsTrie ( db , stateRoot , false ) # important for sanity checks
2023-05-10 18:04:35 +02:00
2023-03-10 17:16:42 -05:00
let acc = ifNodesExistGetAccount ( trie , address ) . get
let desiredCodeHash = acc . codeHash
let p = ( blockNumber , address )
if not ( trie . hasAllNodesForCode ( address ) ) :
let fetchedCode = await fetchAndVerifyCode ( client , p , desiredCodeHash )
if not justChecking :
storeCode ( trie , p , desiredCodeHash , fetchedCode )
if shouldDoUnnecessarySanityChecks :
assertThatWeHaveStoredCode ( trie , p , desiredCodeHash )
2023-12-08 16:35:50 +07:00
proc ifNecessaryGetBlockHeaderByNumber * ( client : RpcClient , chainDB : CoreDbRef , blockNumber : common . BlockNumber , justChecking : bool ) : Future [ void ] {. async . } =
2023-03-10 17:16:42 -05:00
let maybeHeaderAndHash = chainDB . getBlockHeaderWithHash ( blockNumber )
if maybeHeaderAndHash . isNone :
let fetchedHeader = await fetchBlockHeaderWithNumber ( client , blockNumber )
let headerVerificationRes = verifyFetchedBlockHeader ( fetchedHeader , blockNumber )
let whatAreWeVerifying = ( " block header by number " , blockNumber , fetchedHeader )
raiseExceptionIfError ( whatAreWeVerifying , headerVerificationRes )
if not justChecking :
storeBlockHeader ( chainDB , fetchedHeader )
if shouldDoUnnecessarySanityChecks :
assertThatWeHaveStoredBlockHeader ( chainDB , blockNumber , fetchedHeader )
# Used in asynchronous on-demand-data-fetching mode.
proc realAsyncDataSource * ( peerPool : PeerPool , client : RpcClient , justChecking : bool ) : AsyncDataSource =
AsyncDataSource (
2023-12-08 16:35:50 +07:00
ifNecessaryGetAccount : ( proc ( db : CoreDbRef , blockNumber : common . BlockNumber , stateRoot : common . Hash256 , address : EthAddress , newStateRootForSanityChecking : common . Hash256 ) : Future [ void ] {. async . } =
2023-03-10 17:16:42 -05:00
await ifNecessaryGetAccountAndSlots ( client , db , blockNumber , stateRoot , address , @ [ ] , false , false , newStateRootForSanityChecking )
) ,
2023-12-08 16:35:50 +07:00
ifNecessaryGetSlots : ( proc ( db : CoreDbRef , blockNumber : common . BlockNumber , stateRoot : common . Hash256 , address : EthAddress , slots : seq [ UInt256 ] , newStateRootForSanityChecking : common . Hash256 ) : Future [ void ] {. async . } =
2023-03-10 17:16:42 -05:00
await ifNecessaryGetAccountAndSlots ( client , db , blockNumber , stateRoot , address , slots , false , false , newStateRootForSanityChecking )
) ,
2023-12-08 16:35:50 +07:00
ifNecessaryGetCode : ( proc ( db : CoreDbRef , blockNumber : common . BlockNumber , stateRoot : common . Hash256 , address : EthAddress , newStateRootForSanityChecking : common . Hash256 ) : Future [ void ] {. async . } =
2023-03-10 17:16:42 -05:00
await ifNecessaryGetCode ( client , db , blockNumber , stateRoot , address , justChecking , newStateRootForSanityChecking )
) ,
2023-12-08 16:35:50 +07:00
ifNecessaryGetBlockHeaderByNumber : ( proc ( chainDB : CoreDbRef , blockNumber : common . BlockNumber ) : Future [ void ] {. async . } =
2023-03-10 17:16:42 -05:00
await ifNecessaryGetBlockHeaderByNumber ( client , chainDB , blockNumber , justChecking )
) ,
2023-04-24 16:59:38 -04:00
# FIXME-Adam: This will be needed later, but for now let's just get the basic methods in place.
#fetchNodes: (proc(stateRoot: Hash256, paths: seq[seq[seq[byte]]], nodeHashes: seq[Hash256]): Future[seq[seq[byte]]] {.async.} =
# return await fetchNodes(peerPool, stateRoot, paths, nodeHashes)
#),
2023-05-10 18:04:35 +02:00
2023-12-08 16:35:50 +07:00
fetchBlockHeaderWithHash : ( proc ( h : common . Hash256 ) : Future [ common . BlockHeader ] {. async . } =
2023-03-10 17:16:42 -05:00
return await fetchBlockHeaderWithHash ( client , h )
) ,
2023-12-08 16:35:50 +07:00
fetchBlockHeaderWithNumber : ( proc ( n : common . BlockNumber ) : Future [ common . BlockHeader ] {. async . } =
2023-03-10 17:16:42 -05:00
return await fetchBlockHeaderWithNumber ( client , n )
) ,
2023-12-08 16:35:50 +07:00
fetchBlockHeaderAndBodyWithHash : ( proc ( h : common . Hash256 ) : Future [ ( common . BlockHeader , BlockBody ) ] {. async . } =
2023-03-10 17:16:42 -05:00
return await fetchBlockHeaderAndBodyWithHash ( client , h )
) ,
2023-12-08 16:35:50 +07:00
fetchBlockHeaderAndBodyWithNumber : ( proc ( n : common . BlockNumber ) : Future [ ( common . BlockHeader , BlockBody ) ] {. async . } =
2023-03-10 17:16:42 -05:00
return await fetchBlockHeaderAndBodyWithNumber ( client , n )
)
)