Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions execution_chain/common/genesis.nim
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ proc toGenesisHeader*(
const EmptyRequestsHash = calcRequestsHash()
result.requestsHash = Opt.some(EmptyRequestsHash)

if fork >= Amsterdam:
result.blockAccessListHash = Opt.some(EMPTY_BLOCK_ACCESS_LIST_HASH)

proc toGenesisHeader*(
genesis: Genesis;
fork: HardFork;
Expand Down
2 changes: 2 additions & 0 deletions execution_chain/core/chain/forked_chain.nim
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ proc validateBlock(c: ForkedChainRef,
excessBlobGas: blk.header.excessBlobGas,
parentBeaconBlockRoot: blk.header.parentBeaconBlockRoot,
requestsHash: blk.header.requestsHash,
blockAccessListHash: blk.header.blockAccessListHash
),
parentTxFrame=cast[uint](parentFrame),
txFrame=cast[uint](txFrame)
Expand Down Expand Up @@ -947,6 +948,7 @@ proc blockBodyByHash*(c: ForkedChainRef, blockHash: Hash32): Result[BlockBody, s
transactions: blk.transactions,
uncles: blk.uncles,
withdrawals: blk.withdrawals,
blockAccessList: blk.blockAccessList,
))
c.baseTxFrame.getBlockBody(blockHash)

Expand Down
4 changes: 4 additions & 0 deletions execution_chain/core/chain/forked_chain/chain_private.nim
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ proc writeBaggage*(c: ForkedChainRef,
txFrame.persistWithdrawals(
header.withdrawalsRoot.expect("WithdrawalsRoot should be verified before"),
blk.withdrawals.get)
if blk.blockAccessList.isSome:
txFrame.persistBlockAccessList(
header.blockAccessListHash.expect("blockAccessListHash should be verified before"),
blk.blockAccessList.get)

proc processBlock*(c: ForkedChainRef,
parentBlk: BlockRef,
Expand Down
8 changes: 7 additions & 1 deletion execution_chain/core/chain/persist_blocks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type
NoPersistWithdrawals
NoPersistReceipts
NoPersistSlotHashes
NoPersistBlockAccessList

PersistBlockFlags* = set[PersistBlockFlag]

Expand All @@ -51,7 +52,7 @@ type

PersistStats* = tuple[blocks: int, txs: int, gas: GasInt]

const NoPersistBodies* = {NoPersistTransactions, NoPersistUncles, NoPersistWithdrawals}
const NoPersistBodies* = {NoPersistTransactions, NoPersistUncles, NoPersistWithdrawals, NoPersistBlockAccessList}

# ------------------------------------------------------------------------------
# Private
Expand Down Expand Up @@ -208,6 +209,11 @@ proc persistBlock*(p: var Persister, blk: Block): Result[void, string] =
blk.withdrawals.get,
)

if NoPersistBlockAccessList notin p.flags and blk.blockAccessList.isSome:
txFrame.persistBlockAccessList(
header.blockAccessListHash.expect("blockAccessListHash should be verified before"),
blk.blockAccessList.get)

p.stats.blocks += 1
p.stats.txs += blk.transactions.len
p.stats.gas += blk.header.gasUsed
Expand Down
15 changes: 15 additions & 0 deletions execution_chain/core/executor/process_block.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import
../../transaction,
../../evm/state,
../../evm/types,
../../block_access_list/block_access_list_validation,
../dao,
../eip6110,
./calculate_reward,
Expand Down Expand Up @@ -140,6 +141,20 @@ proc procBlkPreamble(
if header.parentBeaconBlockRoot.isSome:
return err("Pre-Cancun block header must not have parentBeaconBlockRoot")

if com.isAmsterdamOrLater(header.timestamp):
if header.blockAccessListHash.isNone:
return err("Post-Amsterdam block header must have blockAccessListHash")
elif blk.blockAccessList.isNone:
return err("Post-Amsterdam block body must have blockAccessList")
elif not skipValidation:
if blk.blockAccessList.get.validate(header.blockAccessListHash.get).isErr():
return err("Mismatched blockAccessListHash")
else:
if header.blockAccessListHash.isSome:
return err("Pre-Amsterdam block header must not have blockAccessListHash")
elif blk.blockAccessList.isSome:
return err("Pre-Amsterdam block body must not have blockAccessList")

if header.txRoot != EMPTY_ROOT_HASH:
if blk.transactions.len == 0:
return err("Transactions missing from body")
Expand Down
26 changes: 25 additions & 1 deletion execution_chain/core/validate.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import
../transaction/call_types,
../[transaction, constants],
../utils/utils,
"."/[dao, eip4844, eip7702, eip7691, gaslimit, withdrawals],
../block_access_list/block_access_list_validation,
./[dao, eip4844, eip7702, eip7691, gaslimit, withdrawals],
./pow/difficulty,
stew/objects,
results
Expand All @@ -37,6 +38,28 @@ const
# Private validator functions
# ------------------------------------------------------------------------------

# https://eips.ethereum.org/EIPS/eip-7928
func validateBlockAccessList*(
com: CommonRef,
header: Header,
blockAccessList: Opt[BlockAccessList]
): Result[void, string] =
if com.isAmsterdamOrLater(header.timestamp):
if header.blockAccessListHash.isNone:
return err("Post-Amsterdam block header must have blockAccessListHash")
elif blockAccessList.isNone:
return err("Post-Amsterdam block body must have blockAccessList")
else:
if blockAccessList.get.validate(header.blockAccessListHash.get).isErr():
return err("Mismatched blockAccessListHash blockNumber =" & $header.number)
else:
if header.blockAccessListHash.isSome:
return err("Pre-Amsterdam block header must not have blockAccessListHash")
elif blockAccessList.isSome:
return err("Pre-Amsterdam block body must not have blockAccessList")

return ok()

proc validateHeader(
com: CommonRef;
blk: Block;
Expand Down Expand Up @@ -98,6 +121,7 @@ proc validateHeader(
? com.validateWithdrawals(header, blk.withdrawals)
? com.validateEip4844Header(header, parentHeader, blk.transactions)
? com.validateGasLimitOrBaseFee(header, parentHeader)
? com.validateBlockAccessList(header, blk.blockAccessList)

ok()

Expand Down
34 changes: 27 additions & 7 deletions execution_chain/db/core_db/core_apps.nim
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,22 @@ proc getTransactions*(

return ok(move(res))

proc persistBlockAccessList*(
db: CoreDbTxRef, blockAccessListHash: Hash32, bal: BlockAccessList) =
db.put(blockAccessListHashKey(blockAccessListHash).toOpenArray, bal.encode())
.expect("persistBlockAccessList should succeed")

proc getBlockAccessList*(
db: CoreDbTxRef,
blockAccessListHash: Hash32): Result[BlockAccessList, string] =
let balBytes = db.get(blockAccessListHashKey(blockAccessListHash).toOpenArray).valueOr:
return err("getBlockAccessList: " & $$error)

let bal = BlockAccessList.decode(balBytes).valueOr:
return err("getBlockAccessList: " & $error)

ok(bal)

proc getBlockBody*(
db: CoreDbTxRef;
header: Header;
Expand All @@ -421,6 +437,11 @@ proc getBlockBody*(
if header.withdrawalsRoot.isSome:
let wds = ?db.getWithdrawals(header.withdrawalsRoot.get)
body.withdrawals = Opt.some(wds)

if header.blockAccessListHash.isSome:
let bal = ?db.getBlockAccessList(header.blockAccessListHash.get)
body.blockAccessList = Opt.some(bal)

return ok(move(body))

proc getBlockBody*(
Expand Down Expand Up @@ -448,7 +469,6 @@ proc getEthBlock*(
blockBody = ?db.getBlockBody(header)
ok(EthBlock.init(move(header), move(blockBody)))


proc getUncleHashes*(
db: CoreDbTxRef;
blockHashes: openArray[Hash32];
Expand Down Expand Up @@ -641,18 +661,18 @@ proc getWitness*(db: CoreDbTxRef, blockHash: Hash32): Result[Witness, string] =

Witness.decode(witnessBytes)

proc persistCodeByHash*(db: CoreDbTxRef, codeHash: Hash32, code: openArray[byte]): Result[void, string] =
db.put(contractHashKey(codeHash).toOpenArray, code).isOkOr:
return err("persistCodeByHash: " & $$error)

ok()

proc getCodeByHash*(db: CoreDbTxRef, codeHash: Hash32): Result[seq[byte], string] =
let code = db.get(contractHashKey(codeHash).toOpenArray).valueOr:
return err("getCodeByHash: " & $$error)

ok(code)

proc setCodeByHash*(db: CoreDbTxRef, codeHash: Hash32, code: openArray[byte]): Result[void, string] =
db.put(contractHashKey(codeHash).toOpenArray, code).isOkOr:
return err("setCodeByHash: " & $$error)

ok()

# ------------------------------------------------------------------------------
# End
# ------------------------------------------------------------------------------
6 changes: 6 additions & 0 deletions execution_chain/db/storage_types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type
beaconHeader = 10
wdKey = 11
witness = 12
blockAccessList = 13

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

func blockAccessListHashKey*(h: Hash32): DbKey {.inline.} =
result.data[0] = byte ord(blockAccessList)
result.data[1 .. 32] = h.data
result.dataEndPos = uint8 32

template toOpenArray*(k: DbKey): openArray[byte] =
k.data.toOpenArray(0, int(k.dataEndPos))

Expand Down
2 changes: 1 addition & 1 deletion execution_chain/stateless/stateless_execution.nim
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ proc statelessProcessBlock*(

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

# Load the block hashes into the database indexed by block number.
for h in verifiedHeaders:
Expand Down
10 changes: 8 additions & 2 deletions execution_chain/sync/beacon/worker/blocks/blocks_blocks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ template blocksFetchCheckImpl(
else:
if bodies[n].transactions.len == 0:
break checkTxLenOk
if blocks[n].header.blockAccessListHash.isSome():
if bodies[n].blockAccessList.isSome():
break checkTxLenOk
elif bodies[n].blockAccessList.isNone():
break checkTxLenOk
# Oops, cut off the rest
blocks.setLen(n) # curb off junk
buddy.bdyFetchRegisterError()
Expand All @@ -112,8 +117,9 @@ template blocksFetchCheckImpl(
# erroneously empty `transactions[]`.)
#
blocks[n].transactions = bodies[n].transactions
blocks[n].uncles = bodies[n].uncles
blocks[n].withdrawals = bodies[n].withdrawals
blocks[n].uncles = bodies[n].uncles
blocks[n].withdrawals = bodies[n].withdrawals
blocks[n].blockAccessList = bodies[n].blockAccessList

if 0 < blocks.len.uint64:
bodyRc = Opt[seq[EthBlock]].ok(blocks) # return ok()
Expand Down
3 changes: 2 additions & 1 deletion execution_chain/sync/wire_protocol/handler.nim
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ proc getBlockBodies*(ctx: EthWireRef,
BlockBody(
transactions: blk.transactions,
uncles: blk.uncles,
withdrawals: blk.withdrawals
withdrawals: blk.withdrawals,
blockAccessList: blk.blockAccessList,
)

for blockHash in hashes:
Expand Down