-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement EIP-158 and EIP-2200 which allow to pass 7 extra spec tests #18
Conversation
Signed-off-by: Ignacio Hagopian <[email protected]>
Signed-off-by: Ignacio Hagopian <[email protected]>
Signed-off-by: Ignacio Hagopian <[email protected]>
Signed-off-by: Ignacio Hagopian <[email protected]>
Signed-off-by: Ignacio Hagopian <[email protected]>
Signed-off-by: Ignacio Hagopian <[email protected]>
@@ -171,6 +172,7 @@ pub const Blockchain = struct { | |||
.chain_id = chain.chain_id, | |||
}; | |||
|
|||
try state.startTx(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a new method in statedb
which does some tx-scope clearing for:
- Account access lists
- Storage slot accessed list.
- and other tasks that are relevant whenever we start a new tx.
for (env.state.touched_addresses.items) |address| { | ||
if (env.state.isEmpty(address)) | ||
env.state.destroyAccount(address); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now statedb tracks all touched addresses, so it can destroy them as explained in EIP-158.
const k = std.mem.readIntSlice(u256, &key.*.bytes, std.builtin.Endian.Big); | ||
const storage_status: evmc.enum_evmc_storage_status = blk: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the most important gap and change of this PR.
See the link mentioned in L163 and EIP-2200.
What we do now, is that stated has a reference to the state of the world when the tx started. This allows to do this logic of comparing the original vs current vs new value to charge the appropriate gas.
const receipient_balance = vm.env.state.getAccount(fromEVMCAddress(msg.*.recipient)).balance; | ||
vm.env.state.setBalance(sender, receipient_balance + value) catch |err| switch (err) { | ||
const recipient_balance = vm.env.state.getAccount(recipient_addr).balance; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a typo here and a small refactoring.
vm.env.state.* = prev_statedb; | ||
} | ||
|
||
evmclog.debug("call() depth={d} ended", .{msg.*.depth}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added this log since it's useful to see also when we finished in a call scope.
std.log.info("newPayloadV2Handler: {any}", .{params}); | ||
// std.log.info("newPayloadV2Handler: {any}", .{params}); | ||
|
||
var block = params.toBlock(); | ||
std.debug.print("block number={}\n", .{block.header.block_number}); | ||
_ = block; | ||
// std.debug.print("block number={}\n", .{block.header.block_number}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now, I commented this since it added some extra noise in the logs.
// original_db contains the state of the world when the transaction starts. | ||
// It assists in charging the right amount of gas for SSTORE. | ||
original_db: ?AccountDB = null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Useful for EIP-2200 impl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ideally we would use some sort of journal, but let's not overcomplicate things at this point.
// Tx-scoped lists. | ||
touched_addresses: ArrayList(Address), | ||
accessed_accounts: AddressSet, | ||
accessed_storage_keys: AddressKeySet, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are the tx-scoped fields for access lists and EIP-158 EIPs.
if (std.mem.eql(u8, &value, &std.mem.zeroes(Bytes32))) { | ||
_ = account.storage.remove(key); | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a bug, since writing the zero value should mean we remove the key/value pair from the state. (i.e: empty, not explicitly zero). Note that this is required for now in the "MPT world" for the current spec tests to pass, this will evolve with VKT.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left a general comment, no action needed. This can be merged as far as I'm concerned.
// original_db contains the state of the world when the transaction starts. | ||
// It assists in charging the right amount of gas for SSTORE. | ||
original_db: ?AccountDB = null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ideally we would use some sort of journal, but let's not overcomplicate things at this point.
Note: This PR should be reviewed after #17, since it's building on top of it
This PR implements some remaining gaps:
Now from the EVMOne side the only gaps are emitting logs and self-destruct. We can do the former without much rush, and the latter might depend since we might want to implement directly on Cancun/Prague expectations.
This allows us to run all the rest of the exec-spec-tests of the file we imported from Shanghai. So we moved from passing 1 test there to now 8.
Moving forward, I could keep adding other files in the Shanghai dataset, and I'm pretty sure most of them will pass. Now I'm more interested in probably implementing other gaps at the "blockchain" level like generating receipts, and having a MPT impl to calculate tx/receipts root.