Reduce getCanonicalHead usage, and delegate to ForkedChain (#2948)

The current getCanonicalHead of core db should not be confused with ForkedChain.latestHeader.
Therefore we need to use getCanonicalHead to restricted case only, e.g. initializing ForkedChain.
This commit is contained in:
andri lim 2024-12-18 11:04:23 +07:00 committed by GitHub
parent 806d9dd04a
commit 45bc6422a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 99 additions and 139 deletions

View File

@ -36,14 +36,13 @@ proc processChainData(cd: ChainData, taskPool: Taskpool): TestStatus =
# bad blocks
discard importRlpBlocks(bytes, c, finalize = true)
let head = com.db.getCanonicalHead().expect("canonical head exists")
let blockHash = "0x" & head.blockHash.data.toHex
let blockHash = $c.latestHash
if blockHash == cd.lastBlockHash:
TestStatus.OK
else:
trace "block hash not equal",
got=blockHash,
number=head.number,
number=c.latestHeader.number,
expected=cd.lastBlockHash
TestStatus.Failed

View File

@ -99,8 +99,7 @@ proc setBlock*(c: ChainRef; blk: Block): Result[void, string] =
_ = vmState.parent.stateRoot # Check point
? vmState.processBlock(blk)
? c.db.persistHeader(
header, c.com.proofOfStake(header), c.com.startOfHistory)
? c.db.persistHeaderAndSetHead(header, c.com.startOfHistory)
c.db.persistTransactions(header.number, header.txRoot, blk.transactions)
c.db.persistReceipts(header.receiptsRoot, vmState.receipts)

View File

@ -34,22 +34,27 @@ proc genesisHeader(node: JsonNode): Header =
let genesisRLP = hexToSeqByte(node["genesisRLP"].getStr)
rlp.decode(genesisRLP, Block).header
proc setupELClient*(conf: ChainConfig, taskPool: Taskpool, node: JsonNode): TestEnv =
proc initializeDb(memDB: CoreDbRef, node: JsonNode): Hash32 =
let
memDB = newCoreDbRef DefaultDbMemory
genesisHeader = node.genesisHeader
com = CommonRef.new(memDB, taskPool, conf)
stateDB = LedgerRef.init(memDB)
chain = newForkedChain(com, genesisHeader)
memDB.persistHeaderAndSetHead(genesisHeader).expect("persistHeader no error")
setupStateDB(node["pre"], stateDB)
stateDB.persist()
doAssert stateDB.getStateRoot == genesisHeader.stateRoot
com.db.persistHeader(genesisHeader,
com.proofOfStake(genesisHeader)).expect("persistHeader no error")
let head = com.db.getCanonicalHead().expect("canonical head exists")
doAssert(head.blockHash == genesisHeader.blockHash)
genesisHeader.blockHash
proc setupELClient*(conf: ChainConfig, taskPool: Taskpool, node: JsonNode): TestEnv =
let
memDB = newCoreDbRef DefaultDbMemory
genesisHash = initializeDb(memDB, node)
com = CommonRef.new(memDB, taskPool, conf)
chain = ForkedChainRef.init(com)
let headHash = chain.latestHash
doAssert(headHash == genesisHash)
let
txPool = TxPoolRef.new(chain)

View File

@ -144,8 +144,7 @@ proc initializeDb(com: CommonRef) =
nonce = com.genesisHeader.nonce
doAssert(com.genesisHeader.number == 0.BlockNumber,
"can't commit genesis block with number > 0")
com.db.persistHeader(com.genesisHeader,
com.proofOfStake(com.genesisHeader),
com.db.persistHeaderAndSetHead(com.genesisHeader,
startOfHistory=com.genesisHeader.parentHash).
expect("can persist genesis header")
doAssert(canonicalHeadHashKey().toOpenArray in kvt)

View File

@ -79,11 +79,7 @@ proc importRlpBlocks*(importFile: string,
importRlpBlocks(bytes, chain, finalize)
proc importRlpBlocks*(conf: NimbusConf, com: CommonRef) =
let head = com.db.getCanonicalHead().valueOr:
error "cannot get canonical head from db", msg=error
quit(QuitFailure)
let chain = newForkedChain(com, head, baseDistance = 0)
let chain = ForkedChainRef.init(com, baseDistance = 0)
# success or not, we quit after importing blocks
for i, blocksFile in conf.blocksFile:

View File

@ -31,7 +31,7 @@ type
# ------------------------------------------------------------------------------
func newChain*(com: CommonRef,
extraValidation: bool): ChainRef =
extraValidation: bool = true): ChainRef =
## Constructor for the `Chain` descriptor object.
## The argument `extraValidation` enables extra block
## chain validation if set `true`.
@ -40,16 +40,6 @@ func newChain*(com: CommonRef,
extraValidation: extraValidation
)
proc newChain*(com: CommonRef): ChainRef =
## Constructor for the `Chain` descriptor object. All sub-object descriptors
## are initialised with defaults. So is extra block chain validation
let header = com.db.getCanonicalHead().expect("canonical head exists")
let extraValidation = com.proofOfStake(header)
return ChainRef(
com: com,
extraValidation: extraValidation,
)
# ------------------------------------------------------------------------------
# Public `Chain` getters
# ------------------------------------------------------------------------------

View File

@ -151,9 +151,8 @@ proc persistBlocksImpl(
let blockHash = header.blockHash()
if NoPersistHeader notin flags:
?c.db.persistHeader(
blockHash, header,
c.com.proofOfStake(header), c.com.startOfHistory)
?c.db.persistHeaderAndSetHead(
blockHash, header, c.com.startOfHistory)
if NoPersistTransactions notin flags:
c.db.persistTransactions(header.number, header.txRoot, blk.transactions)

View File

@ -261,7 +261,7 @@
##
## In the most complex case, the newly mined block was added to some block
## chain branch which has become an uncle to the new canonical head retrieved
## by `getCanonicalHead()`. In order to update the pool to the very state
## by `latestHeader()`. In order to update the pool to the very state
## one would have arrived if worked on the retrieved canonical head branch
## in the first place, the directive `smartHead()` calculates the actions of
## what is needed to get just there from the locally cached head state of the
@ -303,7 +303,7 @@
## --------------------
## head
## Cached block chain insertion point, not necessarily the same header as
## retrieved by the `getCanonicalHead()`. This insertion point can be
## retrieved by the `latestHeader()`. This insertion point can be
## adjusted with the `smartHead()` function.

View File

@ -224,7 +224,7 @@ proc getNonce*(xp: TxPoolRef; account: Address): AccountNonce =
func head*(xp: TxPoolRef): Header =
## Getter, cached block chain insertion point. Typocally, this should be the
## the same header as retrieved by the `getCanonicalHead()` (unless in the
## the same header as retrieved by the `ForkedChainRef.latestHeader` (unless in the
## middle of a mining update.)
xp.vmState.parent

View File

@ -99,26 +99,10 @@ type
# ------- update/move block chain head -------------------------------------
txInfoErrAncestorMissing = ##\
## Cannot forward current head as it is detached from the block chain
"Lost header ancestor"
txInfoErrChainHeadMissing = ##\
## Must not back move current head as it is detached from the block chain
"Lost header position"
txInfoErrForwardHeadMissing = ##\
## Cannot move forward current head to non-existing target position
"Non-existing forward header"
txInfoErrUnrootedCurChain = ##\
## Some orphan block found in current branch of the block chain
"Orphan block in current branch"
txInfoErrUnrootedNewChain = ##\
## Some orphan block found in new branch of the block chain
"Orphan block in new branch"
txInfoChainHeadUpdate = ##\
## Tx becomes obsolete as it is in a mined block, already
"Tx obsoleted"

View File

@ -598,16 +598,15 @@ proc persistHeader*(
db.addBlockNumberToHashLookup(header.number, blockHash)
ok()
proc persistHeader*(
proc persistHeaderAndSetHead*(
db: CoreDbRef;
blockHash: Hash32;
header: Header;
forceCanonical: bool;
startOfHistory = GENESIS_PARENT_HASH;
): Result[void, string] =
?db.persistHeader(blockHash, header, startOfHistory)
if not forceCanonical and header.parentHash != startOfHistory:
if header.parentHash != startOfHistory:
let
canonicalHash = ?db.getCanonicalHeaderHash()
canonScore = db.getScore(canonicalHash).valueOr:
@ -621,15 +620,14 @@ proc persistHeader*(
db.setHead(blockHash)
proc persistHeader*(
proc persistHeaderAndSetHead*(
db: CoreDbRef;
header: Header;
forceCanonical: bool;
startOfHistory = GENESIS_PARENT_HASH;
): Result[void, string] =
let
blockHash = header.blockHash
db.persistHeader(blockHash, header, forceCanonical, startOfHistory)
db.persistHeaderAndSetHead(blockHash, header, startOfHistory)
proc persistUncles*(db: CoreDbRef, uncles: openArray[Header]): Hash32 =
## Persists the list of uncles to the database.

View File

@ -15,7 +15,8 @@ import
results,
../transaction,
../common/common,
../core/eip4844
../core/eip4844,
../core/chain/forked_chain
from ./rpc_types import
Quantity,
@ -59,16 +60,16 @@ type
blocks: uint64
Oracle* = ref object
com: CommonRef
chain: ForkedChainRef
maxHeaderHistory: uint64
maxBlockHistory : uint64
historyCache : KeyedQueue[CacheKey, ProcessedFees]
{.push gcsafe, raises: [].}
func new*(_: type Oracle, com: CommonRef): Oracle =
func new*(_: type Oracle, chain: ForkedChainRef): Oracle =
Oracle(
com: com,
chain: chain,
maxHeaderHistory: 1024,
maxBlockHistory: 1024,
historyCache: KeyedQueue[CacheKey, ProcessedFees].init(),
@ -159,10 +160,7 @@ proc processBlock(oracle: Oracle, bc: BlockContent, percentiles: openArray[float
proc resolveBlockRange(oracle: Oracle, blockId: BlockTag, numBlocks: uint64): Result[BlockRange, string] =
# Get the chain's current head.
let
headBlock = try:
oracle.com.db.getCanonicalHead()
except CatchableError as exc:
return err(exc.msg)
headBlock = oracle.chain.latestHeader
head = headBlock.number
var

View File

@ -301,7 +301,7 @@ method getStatus*(ctx: EthWireRef): Result[EthState, string]
let
db = ctx.db
com = ctx.chain.com
bestBlock = ?db.getCanonicalHead()
bestBlock = ctx.chain.latestHeader
forkId = com.forkId(bestBlock.number, bestBlock.timestamp)
return ok(EthState(

View File

@ -74,17 +74,15 @@ proc executeCase(node: JsonNode): bool =
setupStateDB(env.pre, stateDB)
stateDB.persist()
com.db.persistHeader(env.genesisHeader,
com.proofOfStake(env.genesisHeader)).isOkOr:
com.db.persistHeaderAndSetHead(env.genesisHeader).isOkOr:
debugEcho "Failed to put genesis header into database: ", error
return false
let chead = com.db.getCanonicalHead().expect("canonicalHead exists")
if chead.blockHash != env.genesisHeader.blockHash:
var c = ForkedChainRef.init(com)
if c.latestHash != env.genesisHeader.blockHash:
debugEcho "Genesis block hash in database is different with expected genesis block hash"
return false
var c = newForkedChain(com, env.genesisHeader)
var lastStateRoot = env.genesisHeader.stateRoot
for blk in env.blocks:
let res = c.importBlock(blk.blk)
@ -102,9 +100,8 @@ proc executeCase(node: JsonNode): bool =
c.forkChoice(env.lastBlockHash, env.lastBlockHash).isOkOr:
debugEcho error
return false
let head = com.db.getCanonicalHead().expect("canonicalHead exists")
let headHash = head.blockHash
let headHash = c.latestHash
if headHash != env.lastBlockHash:
debugEcho "lastestBlockHash mismatch, get: ", headHash,
" expect: ", env.lastBlockHash

View File

@ -146,7 +146,7 @@ proc test_chainSync*(
## Store persistent blocks from dump into chain DB
let
sayBlocks = 900'u64
chain = com.newChain
chain = com.newChain()
blockOnDb = com.db.getSavedStateBlockNumber()
lastBlock = max(1, numBlocks).BlockNumber

View File

@ -339,7 +339,7 @@ proc runLedgerTransactionTests(noisy = true) =
for tx in body.transactions:
env.txs.add tx
let head = env.xdb.getCanonicalHead().expect("canonicalHead exists")
let head = env.chain.latestHeader
test &"Collect unique recipient addresses from {env.txs.len} txs," &
&" head=#{head.number}":
# since we generate our own transactions instead of replaying

View File

@ -35,14 +35,10 @@ type
txHash: Hash32
blockHash: Hash32
func zeroHash(): Hash32 =
Hash32.fromHex("0x0000000000000000000000000000000000000000000000000000000000000000")
func emptyCodeHash(): Hash32 =
Hash32.fromHex("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
func emptyStorageHash(): Hash32 =
Hash32.fromHex("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
const
zeroHash = hash32"0x0000000000000000000000000000000000000000000000000000000000000000"
emptyCodeHash = hash32"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"
emptyStorageHash = hash32"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
proc verifyAccountProof(trustedStateRoot: Hash32, res: ProofResponse): MptProofVerificationResult =
let
@ -119,18 +115,18 @@ proc setupEnv(signer, ks2: Address, ctx: EthContext, com: CommonRef): TestEnv =
signer, 1.u256 * 1_000_000_000.u256 * 1_000_000_000.u256) # 1 ETH
# Test data created for eth_getProof tests
let regularAcc = Address.fromHex("0x0000000000000000000000000000000000000001")
let regularAcc = address"0x0000000000000000000000000000000000000001"
vmState.stateDB.addBalance(regularAcc, 2_000_000_000.u256)
vmState.stateDB.setNonce(regularAcc, 1.uint64)
let contractAccWithStorage = Address.fromHex("0x0000000000000000000000000000000000000002")
let contractAccWithStorage = address"0x0000000000000000000000000000000000000002"
vmState.stateDB.addBalance(contractAccWithStorage, 1_000_000_000.u256)
vmState.stateDB.setNonce(contractAccWithStorage, 2.uint64)
vmState.stateDB.setCode(contractAccWithStorage, code)
vmState.stateDB.setStorage(contractAccWithStorage, u256(0), u256(1234))
vmState.stateDB.setStorage(contractAccWithStorage, u256(1), u256(2345))
let contractAccNoStorage = Address.fromHex("0x0000000000000000000000000000000000000003")
let contractAccNoStorage = address"0x0000000000000000000000000000000000000003"
vmState.stateDB.setCode(contractAccNoStorage, code)
@ -181,26 +177,26 @@ proc setupEnv(signer, ks2: Address, ctx: EthContext, com: CommonRef): TestEnv =
vmState.stateDB.persist()
var header = Header(
parentHash : parentHash,
stateRoot : vmState.stateDB.getStateRoot,
transactionsRoot : txRoot,
receiptsRoot : calcReceiptsRoot(vmState.receipts),
parentHash : parentHash,
stateRoot : vmState.stateDB.getStateRoot,
transactionsRoot: txRoot,
receiptsRoot : calcReceiptsRoot(vmState.receipts),
logsBloom : createBloom(vmState.receipts),
difficulty : difficulty,
number : blockNumber,
gasLimit : vmState.cumulativeGasUsed + 1_000_000,
gasUsed : vmState.cumulativeGasUsed,
timestamp : timeStamp
difficulty : difficulty,
number : blockNumber,
gasLimit : vmState.cumulativeGasUsed + 1_000_000,
gasUsed : vmState.cumulativeGasUsed,
timestamp : timeStamp
)
com.db.persistHeader(header,
com.pos.isNil, com.startOfHistory).expect("persistHeader not error")
com.db.persistHeaderAndSetHead(header,
com.startOfHistory).expect("persistHeader not error")
let uncles = [header]
header.ommersHash = com.db.persistUncles(uncles)
com.db.persistHeader(header,
com.pos.isNil, com.startOfHistory).expect("persistHeader not error")
com.db.persistHeaderAndSetHead(header,
com.startOfHistory).expect("persistHeader not error")
com.db.persistFixtureBlock()
@ -226,9 +222,9 @@ proc rpcMain*() =
conf.networkId,
conf.networkParams
)
signer = Address.fromHex "0x0e69cde81b1aa07a45c32c6cd85d67229d36bb1b"
ks2 = Address.fromHex "0xa3b2222afa5c987da6ef773fde8d01b9f23d481f"
ks3 = Address.fromHex "0x597176e9a64aad0845d83afdaf698fbeff77703b"
signer = address"0x0e69cde81b1aa07a45c32c6cd85d67229d36bb1b"
ks2 = address"0xa3b2222afa5c987da6ef773fde8d01b9f23d481f"
ks3 = address"0x597176e9a64aad0845d83afdaf698fbeff77703b"
let keyStore = "tests" / "keystore"
let res = ctx.am.loadKeystores(keyStore)
@ -319,19 +315,19 @@ proc rpcMain*() =
check res == w3Qty(0x1'u64)
test "eth_getBalance":
let a = await client.eth_getBalance(Address.fromHex("0xfff33a3bd36abdbd412707b8e310d6011454a7ae"), blockId(1'u64))
let a = await client.eth_getBalance(address"0xfff33a3bd36abdbd412707b8e310d6011454a7ae", blockId(1'u64))
check a == UInt256.fromHex("0x1b1ae4d6e2ef5000000")
let b = await client.eth_getBalance(Address.fromHex("0xfff4bad596633479a2a29f9a8b3f78eefd07e6ee"), blockId(1'u64))
let b = await client.eth_getBalance(address"0xfff4bad596633479a2a29f9a8b3f78eefd07e6ee", blockId(1'u64))
check b == UInt256.fromHex("0x56bc75e2d63100000")
let c = await client.eth_getBalance(Address.fromHex("0xfff7ac99c8e4feb60c9750054bdc14ce1857f181"), blockId(1'u64))
let c = await client.eth_getBalance(address"0xfff7ac99c8e4feb60c9750054bdc14ce1857f181", blockId(1'u64))
check c == UInt256.fromHex("0x3635c9adc5dea00000")
test "eth_getStorageAt":
let res = await client.eth_getStorageAt(Address.fromHex("0xfff33a3bd36abdbd412707b8e310d6011454a7ae"), 0.u256, blockId(1'u64))
let res = await client.eth_getStorageAt(address"0xfff33a3bd36abdbd412707b8e310d6011454a7ae", 0.u256, blockId(1'u64))
check FixedBytes[32](zeroHash32.data) == res
test "eth_getTransactionCount":
let res = await client.eth_getTransactionCount(Address.fromHex("0xfff7ac99c8e4feb60c9750054bdc14ce1857f181"), blockId(1'u64))
let res = await client.eth_getTransactionCount(address"0xfff7ac99c8e4feb60c9750054bdc14ce1857f181", blockId(1'u64))
check res == w3Qty(0'u64)
test "eth_getBlockTransactionCountByHash":
@ -353,7 +349,7 @@ proc rpcMain*() =
check res == w3Qty(0'u64)
test "eth_getCode":
let res = await client.eth_getCode(Address.fromHex("0xfff7ac99c8e4feb60c9750054bdc14ce1857f181"), blockId(1'u64))
let res = await client.eth_getCode(address"0xfff7ac99c8e4feb60c9750054bdc14ce1857f181", blockId(1'u64))
check res.len == 0
test "eth_sign":
@ -518,8 +514,8 @@ proc rpcMain*() =
let testHeader = getBlockHeader4514995()
let testHash = testHeader.blockHash
let topic = Bytes32.fromHex("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef")
let topic1 = Bytes32.fromHex("0x000000000000000000000000fdc183d01a793613736cd40a5a578f49add1772b")
let topic = bytes32"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
let topic1 = bytes32"0x000000000000000000000000fdc183d01a793613736cd40a5a578f49add1772b"
let filterOptions = FilterOptions(
blockHash: Opt.some(testHash),
@ -540,11 +536,11 @@ proc rpcMain*() =
let testHeader = getBlockHeader4514995()
let testHash = testHeader.blockHash
let topic = Bytes32.fromHex("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef")
let topic1 = Bytes32.fromHex("0xa64da754fccf55aa65a1f0128a648633fade3884b236e879ee9f64c78df5d5d7")
let topic = bytes32"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
let topic1 = bytes32"0xa64da754fccf55aa65a1f0128a648633fade3884b236e879ee9f64c78df5d5d7"
let topic2 = Bytes32.fromHex("0x000000000000000000000000e16c02eac87920033ac72fc55ee1df3151c75786")
let topic3 = Bytes32.fromHex("0x000000000000000000000000b626a5facc4de1c813f5293ec3be31979f1d1c78")
let topic2 = bytes32"0x000000000000000000000000e16c02eac87920033ac72fc55ee1df3151c75786"
let topic3 = bytes32"0x000000000000000000000000b626a5facc4de1c813f5293ec3be31979f1d1c78"
@ -567,7 +563,7 @@ proc rpcMain*() =
block:
# account doesn't exist
let
address = Address.fromHex("0x0000000000000000000000000000000000000004")
address = address"0x0000000000000000000000000000000000000004"
proofResponse = await client.eth_getProof(address, @[], blockId(1'u64))
storageProof = proofResponse.storageProof
@ -575,15 +571,15 @@ proc rpcMain*() =
proofResponse.address == address
verifyAccountProof(blockData.stateRoot, proofResponse).isMissing()
proofResponse.balance == 0.u256
proofResponse.codeHash == zeroHash()
proofResponse.codeHash == zeroHash
proofResponse.nonce == w3Qty(0.uint64)
proofResponse.storageHash == zeroHash()
proofResponse.storageHash == zeroHash
storageProof.len() == 0
block:
# account exists but requested slots don't exist
let
address = Address.fromHex("0x0000000000000000000000000000000000000001")
address = address"0x0000000000000000000000000000000000000001"
slot1Key = 0.u256
slot2Key = 1.u256
proofResponse = await client.eth_getProof(address, @[slot1Key, slot2Key], blockId(1'u64))
@ -593,9 +589,9 @@ proc rpcMain*() =
proofResponse.address == address
verifyAccountProof(blockData.stateRoot, proofResponse).isValid()
proofResponse.balance == 2_000_000_000.u256
proofResponse.codeHash == emptyCodeHash()
proofResponse.codeHash == emptyCodeHash
proofResponse.nonce == w3Qty(1.uint64)
proofResponse.storageHash == emptyStorageHash()
proofResponse.storageHash == emptyStorageHash
storageProof.len() == 2
storageProof[0].key == slot1Key
storageProof[0].proof.len() == 0
@ -607,7 +603,7 @@ proc rpcMain*() =
block:
# contract account with no storage slots
let
address = Address.fromHex("0x0000000000000000000000000000000000000003")
address = address"0x0000000000000000000000000000000000000003"
slot1Key = 0.u256 # Doesn't exist
proofResponse = await client.eth_getProof(address, @[slot1Key], blockId(1'u64))
storageProof = proofResponse.storageProof
@ -616,9 +612,9 @@ proc rpcMain*() =
proofResponse.address == address
verifyAccountProof(blockData.stateRoot, proofResponse).isValid()
proofResponse.balance == 0.u256
proofResponse.codeHash == Hash32.fromHex("0x09044b55d7aba83cb8ac3d2c9c8d8bcadbfc33f06f1be65e8cc1e4ddab5f3074")
proofResponse.codeHash == hash32"0x09044b55d7aba83cb8ac3d2c9c8d8bcadbfc33f06f1be65e8cc1e4ddab5f3074"
proofResponse.nonce == w3Qty(0.uint64)
proofResponse.storageHash == emptyStorageHash()
proofResponse.storageHash == emptyStorageHash
storageProof.len() == 1
storageProof[0].key == slot1Key
storageProof[0].proof.len() == 0
@ -630,7 +626,7 @@ proc rpcMain*() =
block:
# contract account with storage slots
let
address = Address.fromHex("0x0000000000000000000000000000000000000002")
address = address"0x0000000000000000000000000000000000000002"
slot1Key = 0.u256
slot2Key = 1.u256
slot3Key = 2.u256 # Doesn't exist
@ -641,9 +637,9 @@ proc rpcMain*() =
proofResponse.address == address
verifyAccountProof(blockData.stateRoot, proofResponse).isValid()
proofResponse.balance == 1_000_000_000.u256
proofResponse.codeHash == Hash32.fromHex("0x09044b55d7aba83cb8ac3d2c9c8d8bcadbfc33f06f1be65e8cc1e4ddab5f3074")
proofResponse.codeHash == hash32"0x09044b55d7aba83cb8ac3d2c9c8d8bcadbfc33f06f1be65e8cc1e4ddab5f3074"
proofResponse.nonce == w3Qty(2.uint64)
proofResponse.storageHash == Hash32.fromHex("0x2ed06ec37dad4cd8c8fc1a1172d633a8973987fa6995b14a7c0a50c0e8d1a9c3")
proofResponse.storageHash == hash32"0x2ed06ec37dad4cd8c8fc1a1172d633a8973987fa6995b14a7c0a50c0e8d1a9c3"
storageProof.len() == 3
storageProof[0].key == slot1Key
storageProof[0].proof.len() > 0
@ -661,7 +657,7 @@ proc rpcMain*() =
block:
# externally owned account
let
address = Address.fromHex("0x0000000000000000000000000000000000000001")
address = address"0x0000000000000000000000000000000000000001"
proofResponse = await client.eth_getProof(address, @[], blockId(1'u64))
storageProof = proofResponse.storageProof
@ -669,9 +665,9 @@ proc rpcMain*() =
proofResponse.address == address
verifyAccountProof(blockData.stateRoot, proofResponse).isValid()
proofResponse.balance == 2_000_000_000.u256
proofResponse.codeHash == emptyCodeHash()
proofResponse.codeHash == emptyCodeHash
proofResponse.nonce == w3Qty(1.uint64)
proofResponse.storageHash == emptyStorageHash()
proofResponse.storageHash == emptyStorageHash
storageProof.len() == 0
test "eth_getProof - Multiple blocks":
@ -680,7 +676,7 @@ proc rpcMain*() =
block:
# block 1 - account has balance, code and storage
let
address = Address.fromHex("0x0000000000000000000000000000000000000002")
address = address"0x0000000000000000000000000000000000000002"
slot2Key = 1.u256
proofResponse = await client.eth_getProof(address, @[slot2Key], blockId(1'u64))
storageProof = proofResponse.storageProof
@ -689,9 +685,9 @@ proc rpcMain*() =
proofResponse.address == address
verifyAccountProof(blockData.stateRoot, proofResponse).isValid()
proofResponse.balance == 1_000_000_000.u256
proofResponse.codeHash == Hash32.fromHex("0x09044b55d7aba83cb8ac3d2c9c8d8bcadbfc33f06f1be65e8cc1e4ddab5f3074")
proofResponse.codeHash == hash32"0x09044b55d7aba83cb8ac3d2c9c8d8bcadbfc33f06f1be65e8cc1e4ddab5f3074"
proofResponse.nonce == w3Qty(2.uint64)
proofResponse.storageHash == Hash32.fromHex("0x2ed06ec37dad4cd8c8fc1a1172d633a8973987fa6995b14a7c0a50c0e8d1a9c3")
proofResponse.storageHash == hash32"0x2ed06ec37dad4cd8c8fc1a1172d633a8973987fa6995b14a7c0a50c0e8d1a9c3"
storageProof.len() == 1
verifySlotProof(proofResponse.storageHash, storageProof[0]).isValid()

View File

@ -277,7 +277,7 @@ proc runTxHeadDelta(noisy = true) =
xp = env.xp
com = env.com
chain = env.chain
head = com.db.getCanonicalHead().expect("canonical head exists")
head = chain.latestHeader
timestamp = head.timestamp
const
@ -327,7 +327,7 @@ proc runTxHeadDelta(noisy = true) =
setErrorLevel() # in case we set trace level
check com.syncCurrent == 10.BlockNumber
head = com.db.getBlockHeader(com.syncCurrent).expect("block header exists")
head = chain.headerByNumber(com.syncCurrent).expect("block header exists")
let
sdb = LedgerRef.init(com.db)
expected = u256(txPerblock * numBlocks) * amount