Skip to content

Commit e5ec3a5

Browse files
authored
EIP-7928: Add BAL tracking to evm (#3836)
1 parent 66e9119 commit e5ec3a5

32 files changed

+711
-203
lines changed

execution_chain/beacon/api_handler.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export
2525
getPayloadV3,
2626
getPayloadV4,
2727
getPayloadV5,
28+
getPayloadV6,
2829
getPayloadBodiesByHash,
2930
getPayloadBodiesByRange,
3031
newPayload,

execution_chain/beacon/api_handler/api_getpayload.nim

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ proc getPayload*(ben: BeaconEngineRef,
2626
let bundle = ben.getPayloadBundle(id).valueOr:
2727
raise unknownPayload("Unknown bundle")
2828

29-
let
29+
let
3030
version = bundle.payload.version
3131
com = ben.com
3232

@@ -112,7 +112,7 @@ proc getPayloadV5*(ben: BeaconEngineRef, id: Bytes8): GetPayloadV5Response =
112112

113113
let version = bundle.payload.version
114114
if version != Version.V3:
115-
raise unsupportedFork("getPayloadV5 expect payloadV3 but get payload" & $version)
115+
raise unsupportedFork("getPayloadV5 expect ExecutionPayloadV3 but got ExecutionPayload" & $version)
116116
if bundle.blobsBundle.isNil:
117117
raise unsupportedFork("getPayloadV5 is missing BlobsBundleV2")
118118
if bundle.executionRequests.isNone:
@@ -122,10 +122,40 @@ proc getPayloadV5*(ben: BeaconEngineRef, id: Bytes8): GetPayloadV5Response =
122122
if not com.isOsakaOrLater(ethTime bundle.payload.timestamp):
123123
raise unsupportedFork("bundle timestamp is less than Osaka activation")
124124

125+
if com.isAmsterdamOrLater(ethTime bundle.payload.timestamp):
126+
raise unsupportedFork("bundle timestamp greater than Amsterdam must use getPayloadV6")
127+
125128
GetPayloadV5Response(
126129
executionPayload: bundle.payload.V3,
127130
blockValue: bundle.blockValue,
128131
blobsBundle: bundle.blobsBundle.V2,
129132
shouldOverrideBuilder: false,
130133
executionRequests: bundle.executionRequests.get,
131-
)
134+
)
135+
136+
proc getPayloadV6*(ben: BeaconEngineRef, id: Bytes8): GetPayloadV6Response =
137+
trace "Engine API request received",
138+
meth = "GetPayload", id
139+
140+
let bundle = ben.getPayloadBundle(id).valueOr:
141+
raise unknownPayload("Unknown bundle")
142+
143+
let version = bundle.payload.version
144+
if version != Version.V4:
145+
raise unsupportedFork("getPayloadV6 expect ExecutionPayloadV4 but got ExecutionPayload" & $version)
146+
if bundle.blobsBundle.isNil:
147+
raise unsupportedFork("getPayloadV6 is missing BlobsBundleV2")
148+
if bundle.executionRequests.isNone:
149+
raise unsupportedFork("getPayloadV6 is missing executionRequests")
150+
151+
let com = ben.com
152+
if not com.isAmsterdamOrLater(ethTime bundle.payload.timestamp):
153+
raise unsupportedFork("bundle timestamp is less than Amsterdam activation")
154+
155+
GetPayloadV6Response(
156+
executionPayload: bundle.payload.V4,
157+
blockValue: bundle.blockValue,
158+
blobsBundle: bundle.blobsBundle.V2,
159+
shouldOverrideBuilder: false,
160+
executionRequests: bundle.executionRequests.get,
161+
)

execution_chain/beacon/api_handler/api_newpayload.nim

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,41 @@ func validateVersionedHashed(payload: ExecutionPayload,
4141
true
4242

4343
template validateVersion(com, timestamp, payloadVersion, apiVersion) =
44-
if apiVersion == Version.V4:
44+
if apiVersion == Version.V5:
45+
if not com.isAmsterdamOrLater(timestamp):
46+
raise unsupportedFork("newPayloadV5 expect payload timestamp fall within Amsterdam")
47+
if payloadVersion != Version.V4:
48+
raise invalidParams("newPayload" & $apiVersion &
49+
" expect ExecutionPayloadV4" &
50+
" but got ExecutionPayload" & $payloadVersion)
51+
52+
elif apiVersion == Version.V4:
4553
if not com.isPragueOrLater(timestamp):
4654
raise unsupportedFork("newPayloadV4 expect payload timestamp fall within Prague")
47-
48-
if com.isPragueOrLater(timestamp):
4955
if payloadVersion != Version.V3:
50-
raise invalidParams("if timestamp is Prague or later, " &
51-
"payload must be ExecutionPayloadV3, got ExecutionPayload" & $payloadVersion)
56+
raise invalidParams("newPayload" & $apiVersion &
57+
" expect ExecutionPayloadV3" &
58+
" but got ExecutionPayload" & $payloadVersion)
5259

53-
if apiVersion == Version.V3:
60+
elif apiVersion == Version.V3:
5461
if not com.isCancunOrLater(timestamp):
5562
raise unsupportedFork("newPayloadV3 expect payload timestamp fall within Cancun")
63+
if payloadVersion != Version.V3:
64+
raise invalidParams("newPayload" & $apiVersion &
65+
" expect ExecutionPayloadV3" &
66+
" but got ExecutionPayload" & $payloadVersion)
5667

57-
if com.isCancunOrLater(timestamp):
68+
if com.isAmsterdamOrLater(timestamp):
69+
if payloadVersion != Version.V4:
70+
raise invalidParams("if timestamp is Amsterdam or later, " &
71+
"payload must be ExecutionPayloadV4, got ExecutionPayload" & $payloadVersion)
72+
73+
elif com.isPragueOrLater(timestamp):
74+
if payloadVersion != Version.V3:
75+
raise invalidParams("if timestamp is Prague or later, " &
76+
"payload must be ExecutionPayloadV3, got ExecutionPayload" & $payloadVersion)
77+
78+
elif com.isCancunOrLater(timestamp):
5879
if payloadVersion != Version.V3:
5980
raise invalidParams("if timestamp is Cancun or later, " &
6081
"payload must be ExecutionPayloadV3, got ExecutionPayload" & $payloadVersion)
@@ -68,13 +89,6 @@ template validateVersion(com, timestamp, payloadVersion, apiVersion) =
6889
raise invalidParams("if timestamp is earlier than Shanghai, " &
6990
"payload must be ExecutionPayloadV1, got ExecutionPayload" & $payloadVersion)
7091

71-
if apiVersion == Version.V3 or apiVersion == Version.V4:
72-
# both newPayloadV3 and newPayloadV4 expect ExecutionPayloadV3
73-
if payloadVersion != Version.V3:
74-
raise invalidParams("newPayload" & $apiVersion &
75-
" expect ExecutionPayload3" &
76-
" but got ExecutionPayload" & $payloadVersion)
77-
7892
template validatePayload(apiVersion, payloadVersion, payload) =
7993
if payloadVersion >= Version.V2:
8094
if payload.withdrawals.isNone:
@@ -89,6 +103,11 @@ template validatePayload(apiVersion, payloadVersion, payload) =
89103
raise invalidParams("newPayload" & $apiVersion &
90104
"excessBlobGas is expected from execution payload")
91105

106+
if apiVersion >= Version.V5 or payloadVersion >= Version.V4:
107+
if payload.blockAccessList.isNone:
108+
raise invalidParams("newPayload" & $apiVersion &
109+
"blockAccessList is expected from execution payload")
110+
92111
# https://github.com/ethereum/execution-apis/blob/40088597b8b4f48c45184da002e27ffc3c37641f/src/engine/prague.md#request
93112
func validateExecutionRequest(blockHash: Hash32,
94113
requests: openArray[seq[byte]], apiVersion: Version):

execution_chain/beacon/payload_conv.nim

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ func wdRoot(x: Opt[seq[WithdrawalV1]]): Opt[Hash32] =
4040
func txRoot(list: openArray[Web3Tx]): Hash32 =
4141
orderedTrieRoot(list)
4242

43+
func balHash(bal: Opt[seq[byte]]): Opt[Hash32] =
44+
if bal.isNone():
45+
Opt.none(Hash32)
46+
else:
47+
Opt.some(keccak256(bal.get))
48+
4349
# ------------------------------------------------------------------------------
4450
# Public functions
4551
# ------------------------------------------------------------------------------
@@ -63,6 +69,7 @@ func executionPayload*(blk: Block): ExecutionPayload =
6369
withdrawals : w3Withdrawals blk.withdrawals,
6470
blobGasUsed : w3Qty blk.header.blobGasUsed,
6571
excessBlobGas: w3Qty blk.header.excessBlobGas,
72+
blockAccessList: w3BlockAccessList blk.blockAccessList
6673
)
6774

6875
func executionPayloadV1V2*(blk: Block): ExecutionPayloadV1OrV2 =
@@ -110,23 +117,26 @@ func blockHeader*(p: ExecutionPayload,
110117
excessBlobGas : u64(p.excessBlobGas),
111118
parentBeaconBlockRoot: parentBeaconBlockRoot,
112119
requestsHash : requestsHash,
120+
blockAccessListHash: balHash p.blockAccessList,
113121
)
114122

115123
func blockBody*(p: ExecutionPayload):
116-
BlockBody {.gcsafe, raises:[RlpError].} =
124+
BlockBody {.gcsafe, raises: [RlpError].} =
117125
BlockBody(
118126
uncles : @[],
119127
transactions: ethTxs p.transactions,
120128
withdrawals : ethWithdrawals p.withdrawals,
129+
blockAccessList: ethBlockAccessList p.blockAccessList,
121130
)
122131

123132
func ethBlock*(p: ExecutionPayload,
124133
parentBeaconBlockRoot: Opt[Hash32],
125134
requestsHash: Opt[Hash32]):
126-
Block {.gcsafe, raises:[RlpError].} =
135+
Block {.gcsafe, raises: [RlpError].} =
127136
Block(
128137
header : blockHeader(p, parentBeaconBlockRoot, requestsHash),
129138
uncles : @[],
130139
transactions: ethTxs p.transactions,
131140
withdrawals : ethWithdrawals p.withdrawals,
141+
blockAccessList: ethBlockAccessList p.blockAccessList,
132142
)

execution_chain/beacon/web3_eth_conv.nim

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,26 @@ func ethWithdrawals*(x: Opt[seq[WithdrawalV1]]):
8484
if x.isNone: Opt.none(seq[Withdrawal])
8585
else: Opt.some(ethWithdrawals x.get)
8686

87-
func ethTx*(x: Web3Tx): common.Transaction {.gcsafe, raises:[RlpError].} =
87+
func ethTx*(x: Web3Tx): common.Transaction {.gcsafe, raises: [RlpError].} =
8888
result = rlp.decode(distinctBase x, common.Transaction)
8989

9090
func ethTxs*(list: openArray[Web3Tx]):
91-
seq[common.Transaction] {.gcsafe, raises:[RlpError].} =
91+
seq[common.Transaction] {.gcsafe, raises: [RlpError].} =
9292
result = newSeqOfCap[common.Transaction](list.len)
9393
for x in list:
9494
result.add ethTx(x)
9595

96+
func ethBlockAccessList*(
97+
bal: openArray[byte]): BlockAccessList {.gcsafe, raises: [RlpError].} =
98+
rlp.decode(bal, BlockAccessList)
99+
100+
func ethBlockAccessList*(
101+
bal: Opt[seq[byte]]): Opt[BlockAccessList] {.gcsafe, raises: [RlpError].} =
102+
if bal.isNone():
103+
Opt.none(BlockAccessList)
104+
else:
105+
Opt.some(ethBlockAccessList(bal.get))
106+
96107
# ------------------------------------------------------------------------------
97108
# Eth types to Web3 types
98109
# ------------------------------------------------------------------------------
@@ -154,4 +165,13 @@ func w3Txs*(list: openArray[common.Transaction]): seq[Web3Tx] =
154165
for tx in list:
155166
result.add w3Tx(tx)
156167

168+
func w3BlockAccessList*(bal: BlockAccessList): seq[byte] =
169+
bal.encode()
170+
171+
func w3BlockAccessList*(bal: Opt[BlockAccessList]): Opt[seq[byte]] =
172+
if bal.isNone():
173+
Opt.none(seq[byte])
174+
else:
175+
Opt.some(w3BlockAccessList(bal.get))
176+
157177
chronicles.formatIt(Quantity): $(distinctBase it)

execution_chain/block_access_list/block_access_list_builder.nim

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ type
4343
accounts*: Table[Address, AccountData]
4444
## Maps address -> account data
4545

46+
BlockAccessListRef* = ref BlockAccessList
47+
4648
template init*(T: type AccountData): T =
4749
AccountData()
4850

@@ -119,11 +121,11 @@ func slotCmp(x, y: StorageKey | StorageValue): int =
119121
func slotChangesCmp(x, y: SlotChanges): int =
120122
cmp(x.slot.data.toHex(), y.slot.data.toHex())
121123

122-
func addressCmp(x, y: AccountChanges): int =
124+
func accChangesCmp(x, y: AccountChanges): int =
123125
cmp(x.address.data.toHex(), y.address.data.toHex())
124126

125-
func buildBlockAccessList*(builder: BlockAccessListBuilderRef): BlockAccessList =
126-
var blockAccessList: BlockAccessList
127+
func buildBlockAccessList*(builder: BlockAccessListBuilderRef): BlockAccessListRef =
128+
let blockAccessList: BlockAccessListRef = new BlockAccessList
127129

128130
for address, accData in builder.accounts.mpairs():
129131
# Collect and sort storageChanges
@@ -163,7 +165,7 @@ func buildBlockAccessList*(builder: BlockAccessListBuilderRef): BlockAccessList
163165
codeChanges.add((BlockAccessIndex(balIndex), Bytecode(code)))
164166
codeChanges.sort(balIndexCmp)
165167

166-
blockAccessList.add(AccountChanges(
168+
blockAccessList[].add(AccountChanges(
167169
address: address,
168170
storageChanges: storageChanges,
169171
storageReads: storageReads,
@@ -172,6 +174,6 @@ func buildBlockAccessList*(builder: BlockAccessListBuilderRef): BlockAccessList
172174
codeChanges: codeChanges
173175
))
174176

175-
blockAccessList.sort(addressCmp)
177+
blockAccessList[].sort(accChangesCmp)
176178

177179
blockAccessList

0 commit comments

Comments
 (0)