Implement EIP-7002 and EIP-7251 (#2616)
This commit is contained in:
parent
6503d51b44
commit
178d77ab31
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
import
|
||||
std/strformat,
|
||||
results,
|
||||
stew/arrayops,
|
||||
stew/endians2,
|
||||
../../common/common,
|
||||
../../db/ledger,
|
||||
../../transaction/call_evm,
|
||||
|
@ -187,6 +189,86 @@ 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
|
||||
|
|
|
@ -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".}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
@ -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)
|
||||
|
|
|
@ -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(
|
||||
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue