Skip to content

Commit 9b4afec

Browse files
authored
EIP-7928: Persist and get block access list from database (#3799)
1 parent 61c577c commit 9b4afec

File tree

10 files changed

+92
-13
lines changed

10 files changed

+92
-13
lines changed

execution_chain/common/genesis.nim

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ proc toGenesisHeader*(
8383
const EmptyRequestsHash = calcRequestsHash()
8484
result.requestsHash = Opt.some(EmptyRequestsHash)
8585

86+
if fork >= Amsterdam:
87+
result.blockAccessListHash = Opt.some(EMPTY_BLOCK_ACCESS_LIST_HASH)
88+
8689
proc toGenesisHeader*(
8790
genesis: Genesis;
8891
fork: HardFork;

execution_chain/core/chain/forked_chain.nim

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ proc validateBlock(c: ForkedChainRef,
505505
excessBlobGas: blk.header.excessBlobGas,
506506
parentBeaconBlockRoot: blk.header.parentBeaconBlockRoot,
507507
requestsHash: blk.header.requestsHash,
508+
blockAccessListHash: blk.header.blockAccessListHash
508509
),
509510
parentTxFrame=cast[uint](parentFrame),
510511
txFrame=cast[uint](txFrame)
@@ -947,6 +948,7 @@ proc blockBodyByHash*(c: ForkedChainRef, blockHash: Hash32): Result[BlockBody, s
947948
transactions: blk.transactions,
948949
uncles: blk.uncles,
949950
withdrawals: blk.withdrawals,
951+
blockAccessList: blk.blockAccessList,
950952
))
951953
c.baseTxFrame.getBlockBody(blockHash)
952954

execution_chain/core/chain/forked_chain/chain_private.nim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ proc writeBaggage*(c: ForkedChainRef,
3434
txFrame.persistWithdrawals(
3535
header.withdrawalsRoot.expect("WithdrawalsRoot should be verified before"),
3636
blk.withdrawals.get)
37+
if blk.blockAccessList.isSome:
38+
txFrame.persistBlockAccessList(
39+
header.blockAccessListHash.expect("blockAccessListHash should be verified before"),
40+
blk.blockAccessList.get)
3741

3842
proc processBlock*(c: ForkedChainRef,
3943
parentBlk: BlockRef,

execution_chain/core/executor/process_block.nim

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import
1818
../../transaction,
1919
../../evm/state,
2020
../../evm/types,
21+
../../block_access_list/block_access_list_validation,
2122
../dao,
2223
../eip6110,
2324
./calculate_reward,
@@ -140,6 +141,20 @@ proc procBlkPreamble(
140141
if header.parentBeaconBlockRoot.isSome:
141142
return err("Pre-Cancun block header must not have parentBeaconBlockRoot")
142143

144+
if com.isAmsterdamOrLater(header.timestamp):
145+
if header.blockAccessListHash.isNone:
146+
return err("Post-Amsterdam block header must have blockAccessListHash")
147+
elif blk.blockAccessList.isNone:
148+
return err("Post-Amsterdam block body must have blockAccessList")
149+
elif not skipValidation:
150+
if blk.blockAccessList.get.validate(header.blockAccessListHash.get).isErr():
151+
return err("Mismatched blockAccessListHash")
152+
else:
153+
if header.blockAccessListHash.isSome:
154+
return err("Pre-Amsterdam block header must not have blockAccessListHash")
155+
elif blk.blockAccessList.isSome:
156+
return err("Pre-Amsterdam block body must not have blockAccessList")
157+
143158
if header.txRoot != EMPTY_ROOT_HASH:
144159
if blk.transactions.len == 0:
145160
return err("Transactions missing from body")

execution_chain/core/validate.nim

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import
1818
../transaction/call_types,
1919
../[transaction, constants],
2020
../utils/utils,
21-
"."/[dao, eip4844, eip7702, eip7691, gaslimit, withdrawals],
21+
../block_access_list/block_access_list_validation,
22+
./[dao, eip4844, eip7702, eip7691, gaslimit, withdrawals],
2223
./pow/difficulty,
2324
stew/objects,
2425
results
@@ -37,6 +38,28 @@ const
3738
# Private validator functions
3839
# ------------------------------------------------------------------------------
3940

41+
# https://eips.ethereum.org/EIPS/eip-7928
42+
func validateBlockAccessList*(
43+
com: CommonRef,
44+
header: Header,
45+
blockAccessList: Opt[BlockAccessList]
46+
): Result[void, string] =
47+
if com.isAmsterdamOrLater(header.timestamp):
48+
if header.blockAccessListHash.isNone:
49+
return err("Post-Amsterdam block header must have blockAccessListHash")
50+
elif blockAccessList.isNone:
51+
return err("Post-Amsterdam block body must have blockAccessList")
52+
else:
53+
if blockAccessList.get.validate(header.blockAccessListHash.get).isErr():
54+
return err("Mismatched blockAccessListHash blockNumber = " & $header.number)
55+
else:
56+
if header.blockAccessListHash.isSome:
57+
return err("Pre-Amsterdam block header must not have blockAccessListHash")
58+
elif blockAccessList.isSome:
59+
return err("Pre-Amsterdam block body must not have blockAccessList")
60+
61+
return ok()
62+
4063
proc validateHeader(
4164
com: CommonRef;
4265
blk: Block;
@@ -98,6 +121,7 @@ proc validateHeader(
98121
? com.validateWithdrawals(header, blk.withdrawals)
99122
? com.validateEip4844Header(header, parentHeader, blk.transactions)
100123
? com.validateGasLimitOrBaseFee(header, parentHeader)
124+
? com.validateBlockAccessList(header, blk.blockAccessList)
101125

102126
ok()
103127

execution_chain/core/withdrawals.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Nimbus
2-
# Copyright (c) 2022-2024 Status Research & Development GmbH
2+
# Copyright (c) 2022-2025 Status Research & Development GmbH
33
# Licensed under either of
44
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
55
# http://www.apache.org/licenses/LICENSE-2.0)
@@ -23,7 +23,7 @@ proc validateWithdrawals*(
2323
return err("Post-Shanghai block body must have withdrawals")
2424
else:
2525
if withdrawals.get.calcWithdrawalsRoot != header.withdrawalsRoot.get:
26-
return err("Mismatched withdrawalsRoot blockNumber =" & $header.number)
26+
return err("Mismatched withdrawalsRoot blockNumber = " & $header.number)
2727
else:
2828
if header.withdrawalsRoot.isSome:
2929
return err("Pre-Shanghai block header must not have withdrawalsRoot")

execution_chain/db/core_db/core_apps.nim

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,28 @@ proc getTransactions*(
409409

410410
return ok(move(res))
411411

412+
proc persistBlockAccessList*(
413+
db: CoreDbTxRef, blockAccessListHash: Hash32, bal: BlockAccessList) =
414+
db.put(blockAccessListHashKey(blockAccessListHash).toOpenArray, bal.encode())
415+
.expect("persistBlockAccessList should succeed")
416+
417+
proc getBlockAccessList*(
418+
db: CoreDbTxRef,
419+
blockAccessListHash: Hash32): Result[Opt[BlockAccessList], string] =
420+
if blockAccessListHash == EMPTY_BLOCK_ACCESS_LIST_HASH:
421+
return ok(Opt.some(default(BlockAccessList)))
422+
423+
let balBytes = db.getOrEmpty(blockAccessListHashKey(blockAccessListHash).toOpenArray).valueOr:
424+
return err("getBlockAccessList: " & $$error)
425+
426+
if balBytes == EmptyBlob:
427+
return ok(Opt.none(BlockAccessList))
428+
429+
let bal = BlockAccessList.decode(balBytes).valueOr:
430+
return err("getBlockAccessList: " & $error)
431+
432+
ok(Opt.some(bal))
433+
412434
proc getBlockBody*(
413435
db: CoreDbTxRef;
414436
header: Header;
@@ -421,6 +443,10 @@ proc getBlockBody*(
421443
if header.withdrawalsRoot.isSome:
422444
let wds = ?db.getWithdrawals(header.withdrawalsRoot.get)
423445
body.withdrawals = Opt.some(wds)
446+
447+
if header.blockAccessListHash.isSome:
448+
body.blockAccessList = ?db.getBlockAccessList(header.blockAccessListHash.get)
449+
424450
return ok(move(body))
425451

426452
proc getBlockBody*(
@@ -448,7 +474,6 @@ proc getEthBlock*(
448474
blockBody = ?db.getBlockBody(header)
449475
ok(EthBlock.init(move(header), move(blockBody)))
450476

451-
452477
proc getUncleHashes*(
453478
db: CoreDbTxRef;
454479
blockHashes: openArray[Hash32];
@@ -641,18 +666,18 @@ proc getWitness*(db: CoreDbTxRef, blockHash: Hash32): Result[Witness, string] =
641666

642667
Witness.decode(witnessBytes)
643668

669+
proc persistCodeByHash*(db: CoreDbTxRef, codeHash: Hash32, code: openArray[byte]): Result[void, string] =
670+
db.put(contractHashKey(codeHash).toOpenArray, code).isOkOr:
671+
return err("persistCodeByHash: " & $$error)
672+
673+
ok()
674+
644675
proc getCodeByHash*(db: CoreDbTxRef, codeHash: Hash32): Result[seq[byte], string] =
645676
let code = db.get(contractHashKey(codeHash).toOpenArray).valueOr:
646677
return err("getCodeByHash: " & $$error)
647678

648679
ok(code)
649680

650-
proc setCodeByHash*(db: CoreDbTxRef, codeHash: Hash32, code: openArray[byte]): Result[void, string] =
651-
db.put(contractHashKey(codeHash).toOpenArray, code).isOkOr:
652-
return err("setCodeByHash: " & $$error)
653-
654-
ok()
655-
656681
# ------------------------------------------------------------------------------
657682
# End
658683
# ------------------------------------------------------------------------------

execution_chain/db/storage_types.nim

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type
2929
beaconHeader = 10
3030
wdKey = 11
3131
witness = 12
32+
blockAccessList = 13
3233

3334
DbKey* = object
3435
# The first byte stores the key type. The rest are key-specific values
@@ -110,6 +111,11 @@ func blockHashToWitnessKey*(h: Hash32): DbKey {.inline.} =
110111
result.data[1 .. 32] = h.data
111112
result.dataEndPos = uint8 32
112113

114+
func blockAccessListHashKey*(h: Hash32): DbKey {.inline.} =
115+
result.data[0] = byte ord(blockAccessList)
116+
result.data[1 .. 32] = h.data
117+
result.dataEndPos = uint8 32
118+
113119
template toOpenArray*(k: DbKey): openArray[byte] =
114120
k.data.toOpenArray(0, int(k.dataEndPos))
115121

execution_chain/stateless/stateless_execution.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ proc statelessProcessBlock*(
5353

5454
# Load the contract code into the database indexed by code hash.
5555
for c in witness.codes:
56-
doAssert memoryTxFrame.setCodeByHash(keccak256(c), c).isOk()
56+
doAssert memoryTxFrame.persistCodeByHash(keccak256(c), c).isOk()
5757

5858
# Load the block hashes into the database indexed by block number.
5959
for h in verifiedHeaders:

execution_chain/sync/beacon/worker/blocks/blocks_blocks.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ template blocksFetchCheckImpl(
120120
# erroneously empty `transactions[]`.)
121121
#
122122
blocks[n].transactions = bodies[n].transactions
123-
blocks[n].uncles = bodies[n].uncles
124-
blocks[n].withdrawals = bodies[n].withdrawals
123+
blocks[n].uncles = bodies[n].uncles
124+
blocks[n].withdrawals = bodies[n].withdrawals
125125

126126
if 0 < blocks.len.uint64:
127127
bodyRc = Opt[seq[EthBlock]].ok(blocks) # return ok()

0 commit comments

Comments
 (0)