Skip to content

Commit

Permalink
Implement EIP-7002 and EIP-7251 (#2616)
Browse files Browse the repository at this point in the history
  • Loading branch information
jangko committed Sep 12, 2024
1 parent 6503d51 commit 178d77a
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 2 deletions.
2 changes: 2 additions & 0 deletions nimbus/constants.nim
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,6 @@ const

HISTORY_STORAGE_ADDRESS* = hexToByteArray[20]("0x0aae40965e6800cd9b1f4b05ff21581047e3f91e")
DEPOSIT_CONTRACT_ADDRESS* = hexToByteArray[20]("0x00000000219ab540356cbb839cbe05303d7705fa")
WITHDRAWAL_REQUEST_ADDRESS* = hexToByteArray[20]("0x00A3ca265EBcb825B45F985A16CEFB49958cE017")
CONSOLIDATION_REQUEST_ADDRESS* = hexToByteArray[20]("0x00b42dbF2194e931E80326D950320f7d9Dbeac02")
# End
17 changes: 17 additions & 0 deletions nimbus/core/executor/process_block.nim
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,23 @@ proc procBlkEpilogue(
expectedDeposits.add req
if depositReqs != expectedDeposits:
return err("EIP-6110 deposit requests mismatch")

let withdrawalReqs = processDequeueWithdrawalRequests(vmState)
var expectedWithdrawals: seq[Request]
for req in blk.requests.get:
if req.requestType == WithdrawalRequestType:
expectedWithdrawals.add req
if withdrawalReqs != expectedWithdrawals:
return err("EIP-7002 withdrawal requests mismatch")

let consolidationReqs = processDequeueConsolidationRequests(vmState)
var expectedConsolidations: seq[Request]
for req in blk.requests.get:
if req.requestType == ConsolidationRequestType:
expectedConsolidations.add req
if consolidationReqs != expectedConsolidations:
return err("EIP-7251 consolidation requests mismatch")

ok()

# ------------------------------------------------------------------------------
Expand Down
86 changes: 84 additions & 2 deletions nimbus/core/executor/process_transaction.nim
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import
std/strformat,
results,
stew/arrayops,
stew/endians2,
../../common/common,
../../db/ledger,
../../transaction/call_evm,
Expand Down Expand Up @@ -159,7 +161,7 @@ proc processBeaconBlockRoot*(vmState: BaseVMState, beaconRoot: Hash256):

proc processParentBlockHash*(vmState: BaseVMState, prevHash: Hash256):
Result[void, string] =
## processParentBlockHash stores the parent block hash in the
## processParentBlockHash stores the parent block hash in the
## history storage contract as per EIP-2935.
let
statedb = vmState.stateDB
Expand All @@ -186,7 +188,87 @@ proc processParentBlockHash*(vmState: BaseVMState, prevHash: Hash256):

statedb.persist(clearEmptyAccount = true)
ok()


func parseWithdrawalRequest(data: openArray[byte]): WithdrawalRequest =
template copyFrom(T: type, input, a, b): auto =
T.initCopyFrom(input.toOpenArray(a, b))
WithdrawalRequest(
sourceAddress: array[20, byte].copyFrom(data, 0, 19),
validatorPubkey: array[48, byte].copyFrom(data, 20, 20+47),
amount: uint64.fromBytesLE(data.toOpenArray(68, 68+7)),
)

proc processDequeueWithdrawalRequests*(vmState: BaseVMState): seq[Request] =
## processDequeueWithdrawalRequests applies the EIP-7002 system call
## to the withdrawal requests contract.
let
statedb = vmState.stateDB
call = CallParams(
vmState : vmState,
sender : SYSTEM_ADDRESS,
gasLimit : 30_000_000.GasInt,
gasPrice : 0.GasInt,
to : WITHDRAWAL_REQUEST_ADDRESS,

# It's a systemCall, no need for other knicks knacks
sysCall : true,
noAccessList: true,
noIntrinsic : true,
noGasCharge : true,
noRefund : true,
)

# runComputation a.k.a syscall/evm.call
let res = call.runComputation(Blob)
statedb.persist(clearEmptyAccount = true)

for i in 0..<res.len div 76:
let start = i * 76
result.add Request(
requestType: WithdrawalRequestType,
withdrawal: parseWithdrawalRequest(res.toOpenArray(i, i + 75))
)

func parseConsolidationRequest(data: openArray[byte]): ConsolidationRequest =
template copyFrom(T: type, input, a, b): auto =
T.initCopyFrom(input.toOpenArray(a, b))
ConsolidationRequest(
sourceAddress: array[20, byte].copyFrom(data, 0, 19),
sourcePubkey: array[48, byte].copyFrom(data, 20, 20+47),
targetPubkey: array[48, byte].copyFrom(data, 68, 68+47),
)

proc processDequeueConsolidationRequests*(vmState: BaseVMState): seq[Request] =
## processDequeueConsolidationRequests applies the EIP-7251 system call
## to the consolidation requests contract.
let
statedb = vmState.stateDB
call = CallParams(
vmState : vmState,
sender : SYSTEM_ADDRESS,
gasLimit : 30_000_000.GasInt,
gasPrice : 0.GasInt,
to : CONSOLIDATION_REQUEST_ADDRESS,

# It's a systemCall, no need for other knicks knacks
sysCall : true,
noAccessList: true,
noIntrinsic : true,
noGasCharge : true,
noRefund : true,
)

# runComputation a.k.a syscall/evm.call
let res = call.runComputation(Blob)
statedb.persist(clearEmptyAccount = true)

for i in 0..<res.len div 116:
let start = i * 116
result.add Request(
requestType: ConsolidationRequestType,
consolidation: parseConsolidationRequest(res.toOpenArray(i, i + 115))
)

proc processTransaction*(
vmState: BaseVMState; ## Parent accounts environment for transaction
tx: Transaction; ## Transaction to validate
Expand Down
2 changes: 2 additions & 0 deletions nimbus/transaction/call_common.nim
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,8 @@ proc finishRunningComputation(
elif T is string:
if c.isError:
result = c.error.info
elif T is Blob:
result = move(c.output)
else:
{.error: "Unknown computation output".}

Expand Down
18 changes: 18 additions & 0 deletions tools/t8n/helpers.nim
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,20 @@ proc `@@`(x: DepositRequest): JsonNode =
"index": @@(x.index),
}

proc `@@`(x: WithdrawalRequest): JsonNode =
%{
"sourceAddress": @@(x.sourceAddress),
"validatorPubkey": @@(x.validatorPubkey),
"amount": @@(x.amount),
}

proc `@@`(x: ConsolidationRequest): JsonNode =
%{
"sourceAddress": @@(x.sourceAddress),
"sourcePubkey": @@(x.sourcePubkey),
"targetPubkey": @@(x.targetPubkey),
}

proc `@@`[T](x: seq[T]): JsonNode =
result = newJArray()
for c in x:
Expand Down Expand Up @@ -448,3 +462,7 @@ proc `@@`*(x: ExecutionResult): JsonNode =
result["requestsRoot"] = @@(x.requestsRoot)
if x.depositRequests.isSome:
result["depositRequests"] = @@(x.depositRequests)
if x.withdrawalRequests.isSome:
result["withdrawalRequests"] = @@(x.withdrawalRequests)
if x.consolidationRequests.isSome:
result["consolidationRequests"] = @@(x.consolidationRequests)
19 changes: 19 additions & 0 deletions tools/t8n/transition.nim
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,15 @@ proc exec(ctx: var TransContext,
let miner = ctx.env.currentCoinbase
coinbaseStateClearing(vmState, miner, stateReward.isSome())

var
withdrawalReqs: seq[Request]
consolidationReqs: seq[Request]

if vmState.com.isPragueOrLater(ctx.env.currentTimestamp):
# Execute EIP-7002 and EIP-7251 before calculating rootHash
withdrawalReqs = processDequeueWithdrawalRequests(vmState)
consolidationReqs = processDequeueConsolidationRequests(vmState)

let stateDB = vmState.stateDB
stateDB.postState(result.alloc)
result.result = ExecutionResult(
Expand Down Expand Up @@ -353,6 +362,16 @@ proc exec(ctx: var TransContext,
deposits.add req.deposit
result.result.depositRequests = Opt.some(deposits)

var withdrawals: seq[WithdrawalRequest]
for req in withdrawalReqs:
withdrawals.add req.withdrawal
result.result.withdrawalRequests = Opt.some(withdrawals)

var consolidations: seq[ConsolidationRequest]
for req in consolidationReqs:
consolidations.add req.consolidation
result.result.consolidationRequests = Opt.some(consolidations)

template wrapException(body: untyped) =
when wrapExceptionEnabled:
try:
Expand Down
2 changes: 2 additions & 0 deletions tools/t8n/types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ type
currentExcessBlobGas*: Opt[uint64]
requestsRoot*: Opt[Hash256]
depositRequests*: Opt[seq[DepositRequest]]
withdrawalRequests*: Opt[seq[WithdrawalRequest]]
consolidationRequests*: Opt[seq[ConsolidationRequest]]

const
ErrorEVM* = 2.T8NExitCode
Expand Down

0 comments on commit 178d77a

Please sign in to comment.