Update EIP-8272: specify RECENT_ROOT_CODE - #12131
Conversation
File
|
… a native write The spec left RECENT_ROOT_CODE TBD, so the 64-byte salt-root write was handled as a VM-level special case on four paths. ethereum/EIPs#12131 specifies the bytecode, so the predeploy carries it and the write is ordinary EVM execution: the entry a caller commits and the gas it pays are both what the code does, and the four interception points go away. Without the code the write bypassed the EIP-8037 state-gas charge for the created slot, which forked the family devnet against a client that executes the predeploy.
|
Thanks for filling in The hex matches the assembly, the
The embedded domain constants also match A few points I think are worth clarifying before merge:
None of these are objections to the bytecode itself. The core implementation looks sound; my requests are mainly about making the edge semantics and activation requirements explicit enough for independent client implementations. |
|
I'd propose to use fjl/geas instead. We did that for other EIPs that shipped before. |
… a native write The spec left RECENT_ROOT_CODE TBD, so the 64-byte salt-root write was handled as a VM-level special case on four paths. ethereum/EIPs#12131 specifies the bytecode, so the predeploy carries it and the write is ordinary EVM execution: the entry a caller commits and the gas it pays are both what the code does, and the four interception points go away. Without the code the write bypassed the EIP-8037 state-gas charge for the created slot, which forked the family devnet against a client that executes the predeploy.
|
thanks @AnkushinDaniil @ilitteri! I agree with @nerolation that the runtime should be written in fjl/geas and maintained in ethereum/sys-asm with generated bytecode and tests my suggestion would be to keep RECENT_ROOT_LENGTH = 8192, and then no strong preference between the modulo operation or using the 0x1fff mask. Feels like the trade off is simplicity or gas efficiency (saves 2 gas on writes) but forced to rely on a power of two mask and then I think a synthetic deployment transaction is better, it would follow existing EIP precedent and avoid a special fork state change |
|
Thanks both. Agreed on all three. Moved the runtime to geas and opened it against Keeping On the synthetic deployment transaction: I will rewrite the Activation section to install the code with a Nick-method deployment rather than a fork state change, following the 4788 precedent. That makes the address deployment-derived instead of the current |
RECENT_ROOT_CODEis currentlyTBD, so the recent root contract has a fully specified behaviour and no code that implements it. A client that installs the predeploy today installs an empty account, every write is a plain value transfer that commits nothing, and every reference then fails its check. That makes the whole recent root path untestable end to end, so this fills the constant in.The code is assembled directly from the "Recent root contract" section rather than compiled, so the mapping between the two is line by line and reviewable. It is 144 bytes.
Two prohibitions in that section are met without an explicit check, which the text now says out loud. In static context the
sstorefails on its own. UnderDELEGATECALLorCALLCODEthesstorewrites to the calling account, so recent root storage is untouched either way.The current slot comes from
SLOTNUM, which this EIP already requires through EIP-7843, so the contract never needs to know the slot duration.I ran it on a devnet before proposing it. A write from an EOA produced exactly the
storage_keyandentry_hashthe section prescribes:A write costs 127244 gas. All three revert conditions hold: calldata shorter than 64 bytes, longer than 64 bytes, and a nonzero call value.
Two things I would rather the authors decide than assume:
The modulus is compiled as a mask,
push2 0x1fff, which is correct only whileRECENT_ROOT_LENGTHis 8192. If that constant is still open, amodcosts 3 more gas and survives any future value.The address is fixed at
0x…8272and the code is installed at activation, so there is no deployment transaction and no synthetic sender the way EIP-2935 and EIP-4788 have one. That seemed right for this EIP, but it is a departure from those two and worth confirming.