Implement EIP-4788: Beacon block root in the EVM (#1722)
* Implement EIP-4788: Beacon block root in the EVM * EIP-4788: Fix genesis.parentBeaconBlockRoot initialization
This commit is contained in:
parent
57a22bbfab
commit
96fb355efe
|
@ -156,6 +156,9 @@ proc generatePayload*(ben: BeaconEngineRef,
|
|||
pos.timestamp = ethTime attrs.timestamp
|
||||
pos.feeRecipient = ethAddr attrs.suggestedFeeRecipient
|
||||
|
||||
if attrs.parentBeaconBlockRoot.isSome:
|
||||
pos.parentBeaconBlockRoot = ethHash attrs.parentBeaconBlockRoot.get
|
||||
|
||||
xp.setWithdrawals(attrs)
|
||||
|
||||
if headBlock.blockHash != xp.head.blockHash:
|
||||
|
|
|
@ -37,6 +37,7 @@ type
|
|||
baseFeePerGas*: Option[UInt256]
|
||||
blobGasUsed* : Option[uint64] # EIP-4844
|
||||
excessBlobGas*: Option[uint64] # EIP-4844
|
||||
parentBeaconBlockRoot*: Option[Hash256] # EIP-4788
|
||||
|
||||
GenesisAlloc* = Table[EthAddress, GenesisAccount]
|
||||
GenesisAccount* = object
|
||||
|
@ -69,6 +70,7 @@ type
|
|||
baseFeePerGas*: Option[UInt256]
|
||||
blobGasUsed* : Option[uint64] # EIP-4844
|
||||
excessBlobGas*: Option[uint64] # EIP-4844
|
||||
parentBeaconBlockRoot*: Option[Hash256] # EIP-4788
|
||||
|
||||
const
|
||||
CustomNet* = 0.NetworkId
|
||||
|
|
|
@ -83,6 +83,7 @@ proc toGenesisHeader*(
|
|||
if fork >= Cancun:
|
||||
result.blobGasUsed = g.blobGasUsed
|
||||
result.excessBlobGas = g.excessBlobGas
|
||||
result.parentBeaconBlockRoot = g.parentBeaconBlockRoot
|
||||
|
||||
proc toGenesisHeader*(
|
||||
genesis: Genesis;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{.used.}
|
||||
|
||||
import
|
||||
stew/byteutils,
|
||||
eth/common/eth_types
|
||||
|
||||
# proc default(t: typedesc): t = discard -- notused
|
||||
|
@ -85,4 +86,10 @@ const
|
|||
MAX_BLOB_GAS_PER_BLOCK* = 786432
|
||||
MAX_ALLOWED_BLOB* = MAX_BLOB_GAS_PER_BLOCK div GAS_PER_BLOB
|
||||
|
||||
# EIP-4788 addresses
|
||||
# BeaconRootsStorageAddress is the address where historical beacon roots are stored as per EIP-4788
|
||||
BeaconRootsStorageAddress* = hexToByteArray[20]("0xbEac00dDB15f3B6d645C48263dC93862413A222D")
|
||||
# SystemAddress is where the system-transaction is sent from as per EIP-4788
|
||||
SystemAddress* = hexToByteArray[20]("0xfffffffffffffffffffffffffffffffffffffffe")
|
||||
|
||||
# End
|
||||
|
|
|
@ -14,6 +14,7 @@ type
|
|||
feeRecipient : EthAddress
|
||||
timestamp : EthTime
|
||||
prevRandao : Hash256
|
||||
parentBeaconBlockRoot: Hash256
|
||||
|
||||
proc prepare*(ctx: CasperRef, header: var BlockHeader) =
|
||||
header.coinbase = ctx.feeRecipient
|
||||
|
@ -40,6 +41,9 @@ func timestamp*(ctx: CasperRef): EthTime =
|
|||
func prevRandao*(ctx: CasperRef): Hash256 =
|
||||
ctx.prevRandao
|
||||
|
||||
func parentBeaconBlockRoot*(ctx: CasperRef): Hash256 =
|
||||
ctx.parentBeaconBlockRoot
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Setters
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -52,3 +56,6 @@ proc `timestamp=`*(ctx: CasperRef, val: EthTime) =
|
|||
|
||||
proc `prevRandao=`*(ctx: CasperRef, val: Hash256) =
|
||||
ctx.prevRandao = val
|
||||
|
||||
proc `parentBeaconBlockRoot=`*(ctx: CasperRef, val: Hash256) =
|
||||
ctx.parentBeaconBlockRoot = val
|
||||
|
|
|
@ -34,6 +34,11 @@ proc processTransactions*(vmState: BaseVMState;
|
|||
{.gcsafe, raises: [CatchableError].} =
|
||||
vmState.receipts = newSeq[Receipt](transactions.len)
|
||||
vmState.cumulativeGasUsed = 0
|
||||
|
||||
if header.parentBeaconBlockRoot.isSome:
|
||||
vmState.processBeaconBlockRoot(header.parentBeaconBlockRoot.get).isOkOr:
|
||||
return err(error)
|
||||
|
||||
for txIndex, tx in transactions:
|
||||
var sender: EthAddress
|
||||
if not tx.getSender(sender):
|
||||
|
@ -58,6 +63,13 @@ proc procBlkPreamble(vmState: BaseVMState;
|
|||
blockNumber = header.blockNumber
|
||||
return false
|
||||
|
||||
if vmState.determineFork >= FkCancun:
|
||||
if header.parentBeaconBlockRoot.isNone:
|
||||
raise ValidationError.newException("Post-Cancun block header must have parentBeaconBlockRoot")
|
||||
else:
|
||||
if header.parentBeaconBlockRoot.isSome:
|
||||
raise ValidationError.newException("Pre-Cancun block header must not have parentBeaconBlockRoot")
|
||||
|
||||
if header.txRoot != EMPTY_ROOT_HASH:
|
||||
if body.transactions.len == 0:
|
||||
debug "No transactions in body",
|
||||
|
|
|
@ -15,10 +15,12 @@ import
|
|||
../../common/common,
|
||||
../../db/accounts_cache,
|
||||
../../transaction/call_evm,
|
||||
../../transaction/call_common,
|
||||
../../transaction,
|
||||
../../vm_state,
|
||||
../../vm_types,
|
||||
../../evm/async/operations,
|
||||
../../constants,
|
||||
../validate,
|
||||
chronos,
|
||||
stew/results
|
||||
|
@ -129,6 +131,43 @@ proc asyncProcessTransactionImpl(
|
|||
# Public functions
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
proc processBeaconBlockRoot*(vmState: BaseVMState, beaconRoot: Hash256):
|
||||
Result[void, string] {.raises: [CatchableError].} =
|
||||
## processBeaconBlockRoot applies the EIP-4788 system call to the
|
||||
## beacon block root contract. This method is exported to be used in tests.
|
||||
## If EIP-4788 is enabled, we need to invoke the beaconroot storage
|
||||
## contract with the new root.
|
||||
let
|
||||
statedb = vmState.stateDB
|
||||
call = CallParams(
|
||||
vmState: vmState,
|
||||
sender: SystemAddress,
|
||||
gasLimit: 30_000_000.GasInt,
|
||||
gasPrice: 0.GasInt,
|
||||
to: BeaconRootsStorageAddress,
|
||||
input: @(beaconRoot.data),
|
||||
)
|
||||
|
||||
# runComputation a.k.a syscall/evm.call
|
||||
if call.runComputation().isError:
|
||||
return err("processBeaconBlockRoot: syscall error")
|
||||
|
||||
# We can choose to set SystemAddress nonce to 0
|
||||
# like erigon or geth(their EVM have explicit nonce set)
|
||||
# or we delete the account manually instead of let it deleted
|
||||
# by AccountsCache.persist.
|
||||
statedb.deleteAccount(SystemAddress)
|
||||
|
||||
when false:
|
||||
# nimbus EVM automatically increase sender nonce by one
|
||||
# for each call/create.
|
||||
statedb.setNonce(SystemAddress, 0)
|
||||
# statedb.persist probably not needed as each processTransaction
|
||||
# will call it.
|
||||
statedb.persist(clearEmptyAccount = true, clearCache = false)
|
||||
|
||||
ok()
|
||||
|
||||
proc asyncProcessTransaction*(
|
||||
vmState: BaseVMState; ## Parent accounts environment for transaction
|
||||
tx: Transaction; ## Transaction to validate
|
||||
|
|
|
@ -230,6 +230,9 @@ proc getHeader*(dh: TxChainRef): BlockHeader
|
|||
if dh.com.forkGTE(Shanghai):
|
||||
result.withdrawalsRoot = some(calcWithdrawalsRoot(dh.withdrawals))
|
||||
|
||||
if dh.com.forkGTE(Cancun):
|
||||
result.parentBeaconBlockRoot = some(dh.com.pos.parentBeaconBlockRoot)
|
||||
|
||||
dh.prepareForSeal(result)
|
||||
|
||||
proc clearAccounts*(dh: TxChainRef)
|
||||
|
|
|
@ -670,7 +670,7 @@ func witnessData(acc: RefAccount): WitnessData =
|
|||
result.storageKeys = initHashSet[UInt256]()
|
||||
update(result, acc)
|
||||
|
||||
proc collectWitnessData*(ac: var AccountsCache) =
|
||||
proc collectWitnessData*(ac: AccountsCache) =
|
||||
# make sure all savepoint already committed
|
||||
doAssert(ac.savePoint.parentSavepoint.isNil)
|
||||
# usually witness data is collected before we call persist()
|
||||
|
@ -694,10 +694,10 @@ proc makeMultiKeys*(ac: AccountsCache): MultikeysRef =
|
|||
result.add(k, v.codeTouched, multiKeys(v.storageKeys))
|
||||
result.sort()
|
||||
|
||||
proc accessList*(ac: var AccountsCache, address: EthAddress) {.inline.} =
|
||||
proc accessList*(ac: AccountsCache, address: EthAddress) {.inline.} =
|
||||
ac.savePoint.accessList.add(address)
|
||||
|
||||
proc accessList*(ac: var AccountsCache, address: EthAddress, slot: UInt256) {.inline.} =
|
||||
proc accessList*(ac: AccountsCache, address: EthAddress, slot: UInt256) {.inline.} =
|
||||
ac.savePoint.accessList.add(address, slot)
|
||||
|
||||
func inAccessList*(ac: AccountsCache, address: EthAddress): bool =
|
||||
|
|
|
@ -1158,6 +1158,14 @@ proc blockexcessBlobGas(ud: RootRef, params: Args, parent: Node): RespResult {.a
|
|||
else:
|
||||
ok(respNull())
|
||||
|
||||
proc blockParentBeaconBlockRoot(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} =
|
||||
let h = HeaderNode(parent)
|
||||
if h.header.parentBeaconBlockRoot.isSome:
|
||||
resp(h.header.parentBeaconBlockRoot.get)
|
||||
else:
|
||||
ok(respNull())
|
||||
|
||||
|
||||
const blockProcs = {
|
||||
"parent": blockParent,
|
||||
"number": blockNumberImpl,
|
||||
|
@ -1190,7 +1198,8 @@ const blockProcs = {
|
|||
"withdrawalsRoot": blockWithdrawalsRoot,
|
||||
"withdrawals": blockWithdrawals,
|
||||
"blobGasUsed": blockBlobGasUsed,
|
||||
"excessBlobGas": blockExcessBlobGas
|
||||
"excessBlobGas": blockExcessBlobGas,
|
||||
"parentBeaconBlockRoot": blockParentBeaconBlockRoot,
|
||||
}
|
||||
|
||||
proc callResultData(ud: RootRef, params: Args, parent: Node): RespResult {.apiPragma.} =
|
||||
|
|
|
@ -339,6 +339,10 @@ type Block {
|
|||
# (bounded at 0).
|
||||
excessBlobGas: Long
|
||||
|
||||
# EIP-4788: This root consumes 32 bytes and is exactly the hash tree root
|
||||
# of the parent beacon block for the given execution block.
|
||||
parentBeaconBlockRoot: Bytes32
|
||||
|
||||
#--------------------------Extensions-------------------------------
|
||||
|
||||
# RawHeader is the RLP encoding of the block's header.
|
||||
|
|
|
@ -78,6 +78,7 @@ type
|
|||
withdrawalsRoot*: Option[Hash256] # EIP-4895
|
||||
blobGasUsed*: Option[HexQuantityStr] # EIP-4844
|
||||
excessBlobGas*: Option[HexQuantityStr] # EIP-4844
|
||||
parentBeaconBlockRoot*: Option[Hash256] # EIP-4788
|
||||
|
||||
TransactionObject* = object # A transaction object, or null when no transaction was found:
|
||||
# Returned to user
|
||||
|
|
|
@ -244,6 +244,8 @@ proc populateBlockObject*(header: BlockHeader, chain: CoreDbRef, fullTx: bool, i
|
|||
if header.excessBlobGas.isSome:
|
||||
result.excessBlobGas = some(encodeQuantity(header.excessBlobGas.get))
|
||||
|
||||
result.parentBeaconBlockRoot = header.parentBeaconBlockRoot
|
||||
|
||||
proc populateReceipt*(receipt: Receipt, gasUsed: GasInt, tx: Transaction,
|
||||
txIndex: int, header: BlockHeader): ReceiptObject
|
||||
{.gcsafe, raises: [ValidationError].} =
|
||||
|
|
|
@ -115,7 +115,8 @@ proc parseHeader*(n: JsonNode): BlockHeader =
|
|||
mixDigest : omitZero(Hash256, "currentRandom"),
|
||||
fee : optional(UInt256, "currentBaseFee"),
|
||||
excessBlobGas: optional(uint64, "excessBlobGas"),
|
||||
blobGasUsed: optional(uint64, "blobGasUsed")
|
||||
blobGasUsed: optional(uint64, "blobGasUsed"),
|
||||
parentBeaconBlockRoot: optional(Hash256, "parentBeaconBlockRoot"),
|
||||
)
|
||||
|
||||
proc parseTx*(n: JsonNode, dataIndex, gasIndex, valueIndex: int): Transaction =
|
||||
|
|
|
@ -183,6 +183,7 @@ proc parseEnv*(ctx: var TransContext, n: JsonNode) =
|
|||
optional(ctx.env, uint64, currentExcessBlobGas)
|
||||
optional(ctx.env, uint64, parentBlobGasUsed)
|
||||
optional(ctx.env, uint64, parentExcessBlobGas)
|
||||
optional(ctx.env, Hash256, parentBeaconBlockRoot)
|
||||
|
||||
if n.hasKey("blockHashes"):
|
||||
let w = n["blockHashes"]
|
||||
|
@ -442,7 +443,7 @@ proc `@@`*(x: ExecutionResult): JsonNode =
|
|||
result["currentBaseFee"] = @@(x.currentBaseFee)
|
||||
if x.withdrawalsRoot.isSome:
|
||||
result["withdrawalsRoot"] = @@(x.withdrawalsRoot)
|
||||
if x.blobGasUsed.isSome:
|
||||
result["blobGasUsed"] = @@(x.blobGasUsed)
|
||||
if x.excessBlobGas.isSome:
|
||||
result["excessBlobGas"] = @@(x.excessBlobGas)
|
||||
if x.currentBlobGasUsed.isSome:
|
||||
result["currentBlobGasUsed"] = @@(x.currentBlobGasUsed)
|
||||
if x.currentExcessBlobGas.isSome:
|
||||
result["currentExcessBlobGas"] = @@(x.currentExcessBlobGas)
|
||||
|
|
|
@ -524,6 +524,24 @@ const
|
|||
output: T8nOutput(trace: true, result: true),
|
||||
expOut: "exp.txt",
|
||||
),
|
||||
TestSpec(
|
||||
name : "Cancun tests",
|
||||
base : "testdata/28",
|
||||
input : t8nInput(
|
||||
"alloc.json", "txs.rlp", "env.json", "Cancun", "",
|
||||
),
|
||||
output: T8nOutput(alloc: true, result: true),
|
||||
expOut: "exp.json",
|
||||
),
|
||||
TestSpec(
|
||||
name : "More cancun tests",
|
||||
base : "/testdata/29",
|
||||
input : t8nInput(
|
||||
"alloc.json", "txs.json", "env.json", "Cancun", "",
|
||||
),
|
||||
output: T8nOutput(alloc: true, result: true),
|
||||
expOut: "exp.json",
|
||||
),
|
||||
]
|
||||
|
||||
proc main() =
|
||||
|
|
|
@ -15,5 +15,6 @@
|
|||
}
|
||||
],
|
||||
"parentBlobGasUsed": "0x100",
|
||||
"parentExcessBlobGas": "0x100"
|
||||
"parentExcessBlobGas": "0x100",
|
||||
"parentBeaconBlockRoot" : "0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"gasUsed": "0x0",
|
||||
"currentBaseFee": "0x500",
|
||||
"withdrawalsRoot": "0x4921c0162c359755b2ae714a0978a1dad2eb8edce7ff9b38b9b6fc4cbc547eb5",
|
||||
"blobGasUsed": "0x0",
|
||||
"excessBlobGas": "0x0"
|
||||
"currentBlobGasUsed": "0x0",
|
||||
"currentExcessBlobGas": "0x0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,6 @@
|
|||
"currentTimestamp" : "0x03e8",
|
||||
"parentBlobGasUsed" : "0x2000",
|
||||
"parentExcessBlobGas" : "0x1000",
|
||||
"previousHash" : "0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
"parentBeaconBlockRoot" : "0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
|
||||
"withdrawals": []
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
|
||||
"balance" : "0x016345785d8a0000",
|
||||
"code" : "0x",
|
||||
"nonce" : "0x00",
|
||||
"storage" : {
|
||||
}
|
||||
},
|
||||
"0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
|
||||
"balance" : "0x016345785d8a0000",
|
||||
"code" : "0x60004960015500",
|
||||
"nonce" : "0x00",
|
||||
"storage" : {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
|
||||
"currentNumber" : "0x01",
|
||||
"currentTimestamp" : "0x079e",
|
||||
"currentGasLimit" : "0x7fffffffffffffff",
|
||||
"previousHash" : "0x3a9b485972e7353edd9152712492f0c58d89ef80623686b6bf947a4a6dce6cb6",
|
||||
"currentBlobGasUsed" : "0x00",
|
||||
"parentTimestamp" : "0x03b6",
|
||||
"parentDifficulty" : "0x00",
|
||||
"parentUncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"currentRandom" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"withdrawals" : [
|
||||
],
|
||||
"parentBaseFee" : "0x0a",
|
||||
"parentGasUsed" : "0x00",
|
||||
"parentGasLimit" : "0x7fffffffffffffff",
|
||||
"parentExcessBlobGas" : "0x00",
|
||||
"parentBlobGasUsed" : "0x00",
|
||||
"blockHashes" : {
|
||||
"0" : "0x3a9b485972e7353edd9152712492f0c58d89ef80623686b6bf947a4a6dce6cb6"
|
||||
},
|
||||
"parentBeaconBlockRoot": "0x0000beac00beac00beac00beac00beac00beac00beac00beac00beac00beac00"
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"alloc": {
|
||||
"0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba": {
|
||||
"balance": "0x150ca"
|
||||
},
|
||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"balance": "0x16345785d80c3a9",
|
||||
"nonce": "0x1"
|
||||
},
|
||||
"0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"code": "0x60004960015500",
|
||||
"storage": {
|
||||
"0x0000000000000000000000000000000000000000000000000000000000000001": "0x01a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"
|
||||
},
|
||||
"balance": "0x16345785d8a0000"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"stateRoot": "0xa40cb3fab01848e922a48bd24191815df9f721ad4b60376edac75161517663e8",
|
||||
"txRoot": "0x4409cc4b699384ba5f8248d92b784713610c5ff9c1de51e9239da0dac76de9ce",
|
||||
"receiptsRoot": "0xbff643da765981266133094092d98c81d2ac8e9a83a7bbda46c3d736f1f874ac",
|
||||
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"receipts": [
|
||||
{
|
||||
"type": "0x3",
|
||||
"root": "0x",
|
||||
"status": "0x1",
|
||||
"cumulativeGasUsed": "0xa865",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"logs": null,
|
||||
"transactionHash": "0x7508d7139d002a4b3a26a4f12dec0d87cb46075c78bf77a38b569a133b509262",
|
||||
"contractAddress": "0x0000000000000000000000000000000000000000",
|
||||
"gasUsed": "0xa865",
|
||||
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"transactionIndex": "0x0"
|
||||
}
|
||||
],
|
||||
"currentDifficulty": null,
|
||||
"gasUsed": "0xa865",
|
||||
"currentBaseFee": "0x9",
|
||||
"withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"currentExcessBlobGas": "0x0",
|
||||
"currentBlobGasUsed": "0x20000"
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
"0xf88bb88903f8860180026483061a8094b94f5374fce5edbc8e2a8697c15331677e6ebf0b8080c00ae1a001a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d801a025e16bb498552165016751911c3608d79000ab89dc3100776e729e6ea13091c7a03acacff7fc0cff6eda8a927dec93ca17765e1ee6cbc06c5954ce102e097c01d2"
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
|
||||
"balance" : "0x016345785d8a0000",
|
||||
"code" : "0x",
|
||||
"nonce" : "0x00",
|
||||
"storage" : {
|
||||
}
|
||||
},
|
||||
"0xbEac00dDB15f3B6d645C48263dC93862413A222D" : {
|
||||
"balance" : "0x1",
|
||||
"code" : "0x3373fffffffffffffffffffffffffffffffffffffffe14604457602036146024575f5ffd5b620180005f350680545f35146037575f5ffd5b6201800001545f5260205ff35b6201800042064281555f359062018000015500",
|
||||
"nonce" : "0x00",
|
||||
"storage" : {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
|
||||
"currentNumber" : "0x01",
|
||||
"currentTimestamp" : "0x079e",
|
||||
"currentGasLimit" : "0x7fffffffffffffff",
|
||||
"previousHash" : "0x3a9b485972e7353edd9152712492f0c58d89ef80623686b6bf947a4a6dce6cb6",
|
||||
"currentBlobGasUsed" : "0x00",
|
||||
"parentTimestamp" : "0x03b6",
|
||||
"parentDifficulty" : "0x00",
|
||||
"parentUncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"currentRandom" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"withdrawals" : [
|
||||
],
|
||||
"parentBaseFee" : "0x0a",
|
||||
"parentGasUsed" : "0x00",
|
||||
"parentGasLimit" : "0x7fffffffffffffff",
|
||||
"parentExcessBlobGas" : "0x00",
|
||||
"parentBlobGasUsed" : "0x00",
|
||||
"parentBeaconBlockRoot": "0x0000beac00beac00beac00beac00beac00beac00beac00beac00beac00beac00"
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"alloc": {
|
||||
"0xbeac00ddb15f3b6d645c48263dc93862413a222d": {
|
||||
"code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604457602036146024575f5ffd5b620180005f350680545f35146037575f5ffd5b6201800001545f5260205ff35b6201800042064281555f359062018000015500",
|
||||
"storage": {
|
||||
"0x000000000000000000000000000000000000000000000000000000000000079e": "0x000000000000000000000000000000000000000000000000000000000000079e",
|
||||
"0x000000000000000000000000000000000000000000000000000000000001879e": "0x0000beac00beac00beac00beac00beac00beac00beac00beac00beac00beac00"
|
||||
},
|
||||
"balance": "0x1"
|
||||
},
|
||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"balance": "0x16345785d871db8",
|
||||
"nonce": "0x1"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"stateRoot": "0x2db9f6bc233e8fd0af2d8023404493a19b37d9d69ace71f4e73158851fced574",
|
||||
"txRoot": "0x248074fabe112f7d93917f292b64932394f835bb98da91f21501574d58ec92ab",
|
||||
"receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa",
|
||||
"logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"receipts": [
|
||||
{
|
||||
"type": "0x2",
|
||||
"root": "0x",
|
||||
"status": "0x1",
|
||||
"cumulativeGasUsed": "0x5208",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"logs": null,
|
||||
"transactionHash": "0x84f70aba406a55628a0620f26d260f90aeb6ccc55fed6ec2ac13dd4f727032ed",
|
||||
"contractAddress": "0x0000000000000000000000000000000000000000",
|
||||
"gasUsed": "0x5208",
|
||||
"blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"transactionIndex": "0x0"
|
||||
}
|
||||
],
|
||||
"currentDifficulty": null,
|
||||
"gasUsed": "0x5208",
|
||||
"currentBaseFee": "0x9",
|
||||
"withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||
"currentExcessBlobGas": "0x0",
|
||||
"currentBlobGasUsed": "0x0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
## EIP 4788
|
||||
|
||||
This test contains testcases for EIP-4788. The 4788-contract is
|
||||
located at address `0xbeac00ddb15f3b6d645c48263dc93862413a222d`, and this test executes a simple transaction. It also
|
||||
implicitly invokes the system tx, which sets calls the contract and sets the
|
||||
storage values
|
||||
```
|
||||
$ dir=./testdata/29/ && go run . t8n --state.fork=Cancun --input.alloc=$dir/alloc.json --input.txs=$dir/txs.json --input.env=$dir/env.json --output.alloc=stdout
|
||||
INFO [08-15|20:07:56.335] Trie dumping started root=ecde45..2af8a7
|
||||
INFO [08-15|20:07:56.335] Trie dumping complete accounts=2 elapsed="225.848µs"
|
||||
INFO [08-15|20:07:56.335] Wrote file file=result.json
|
||||
{
|
||||
"alloc": {
|
||||
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": {
|
||||
"balance": "0x16345785d871db8",
|
||||
"nonce": "0x1"
|
||||
},
|
||||
"0xbeac00541d49391ed88abf392bfc1f4dea8c4143": {
|
||||
"code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604457602036146024575f5ffd5b620180005f350680545f35146037575f5ffd5b6201800001545f5260205ff35b6201800042064281555f359062018000015500",
|
||||
"storage": {
|
||||
"0x000000000000000000000000000000000000000000000000000000000000079e": "0x000000000000000000000000000000000000000000000000000000000000079e",
|
||||
"0x000000000000000000000000000000000000000000000000000000000001879e": "0x0000beac00beac00beac00beac00beac00beac00beac00beac00beac00beac00"
|
||||
},
|
||||
"balance": "0x
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
|
@ -0,0 +1,19 @@
|
|||
[
|
||||
{
|
||||
"input" : "0x",
|
||||
"gas" : "0x10000000",
|
||||
"nonce" : "0x0",
|
||||
"to" : "0x1111111111111111111111111111111111111111",
|
||||
"value" : "0x0",
|
||||
"secretKey" : "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
|
||||
"chainId" : "0x1",
|
||||
"type" : "0x2",
|
||||
"v": "0x0",
|
||||
"r": "0x0",
|
||||
"s": "0x0",
|
||||
"maxFeePerGas" : "0xfa0",
|
||||
"maxPriorityFeePerGas" : "0x0",
|
||||
"accessList" : [
|
||||
]
|
||||
}
|
||||
]
|
|
@ -101,7 +101,7 @@ proc envToHeader(env: EnvStruct): BlockHeader =
|
|||
fee : env.currentBaseFee,
|
||||
withdrawalsRoot: env.withdrawals.calcWithdrawalsRoot(),
|
||||
blobGasUsed: env.currentBlobGasUsed,
|
||||
excessBlobGas: env.currentExcessBlobGas
|
||||
excessBlobGas: env.currentExcessBlobGas,
|
||||
)
|
||||
|
||||
proc postState(db: AccountsCache, alloc: var GenesisAlloc) =
|
||||
|
@ -217,6 +217,10 @@ proc exec(ctx: var TransContext,
|
|||
vmState.receipts = newSeqOfCap[Receipt](txList.len)
|
||||
vmState.cumulativeGasUsed = 0
|
||||
|
||||
if ctx.env.parentBeaconBlockRoot.isSome:
|
||||
vmState.processBeaconBlockRoot(ctx.env.parentBeaconBlockRoot.get).isOkOr:
|
||||
raise newError(ErrorConfig, error)
|
||||
|
||||
var blobGasUsed = 0'u64
|
||||
for txIndex, txRes in txList:
|
||||
if txRes.isErr:
|
||||
|
@ -306,8 +310,8 @@ proc exec(ctx: var TransContext,
|
|||
)
|
||||
|
||||
if fork >= FkCancun:
|
||||
result.result.blobGasUsed = some blobGasUsed
|
||||
result.result.excessBlobGas = some calcExcessBlobGas(vmState.parent)
|
||||
result.result.currentBlobGasUsed = some blobGasUsed
|
||||
result.result.currentExcessBlobGas = some calcExcessBlobGas(vmState.parent)
|
||||
|
||||
template wrapException(body: untyped) =
|
||||
when wrapExceptionEnabled:
|
||||
|
@ -413,7 +417,7 @@ proc transitionAction*(ctx: var TransContext, conf: T8NConf) =
|
|||
ommersHash: uncleHash,
|
||||
blockNumber: ctx.env.currentNumber - 1.toBlockNumber,
|
||||
blobGasUsed: ctx.env.parentBlobGasUsed,
|
||||
excessBlobGas: ctx.env.parentExcessBlobGas
|
||||
excessBlobGas: ctx.env.parentExcessBlobGas,
|
||||
)
|
||||
|
||||
# Sanity check, to not `panic` in state_transition
|
||||
|
@ -436,9 +440,15 @@ proc transitionAction*(ctx: var TransContext, conf: T8NConf) =
|
|||
if ctx.env.parentExcessBlobGas.isNone:
|
||||
raise newError(ErrorConfig, "Cancun config but missing 'parentExcessBlobGas' in env section")
|
||||
|
||||
if ctx.env.parentBeaconBlockRoot.isNone:
|
||||
raise newError(ErrorConfig, "Cancun config but missing 'parentBeaconBlockRoot' in env section")
|
||||
|
||||
let res = loadKzgTrustedSetup()
|
||||
if res.isErr:
|
||||
raise newError(ErrorConfig, res.error)
|
||||
else:
|
||||
# un-set it if it has been set too early
|
||||
ctx.env.parentBeaconBlockRoot = none(Hash256)
|
||||
|
||||
if com.forkGTE(MergeFork):
|
||||
if ctx.env.currentRandom.isNone:
|
||||
|
|
|
@ -48,6 +48,7 @@ type
|
|||
currentExcessBlobGas*: Option[uint64]
|
||||
parentBlobGasUsed*: Option[uint64]
|
||||
parentExcessBlobGas*: Option[uint64]
|
||||
parentBeaconBlockRoot*: Option[Hash256]
|
||||
|
||||
TxsType* = enum
|
||||
TxsNone
|
||||
|
@ -96,8 +97,8 @@ type
|
|||
gasUsed*: GasInt
|
||||
currentBaseFee*: Option[UInt256]
|
||||
withdrawalsRoot*: Option[Hash256]
|
||||
blobGasUsed*: Option[uint64]
|
||||
excessBlobGas*: Option[uint64]
|
||||
currentBlobGasUsed*: Option[uint64]
|
||||
currentExcessBlobGas*: Option[uint64]
|
||||
|
||||
const
|
||||
ErrorEVM* = 2.T8NExitCode
|
||||
|
|
Loading…
Reference in New Issue