Skip to content
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

Merged
merged 6 commits into from
Feb 7, 2024

Conversation

jsign
Copy link
Owner

@jsign jsign commented Jan 23, 2024

Note: This PR should be reviewed after #17, since it's building on top of it

This PR implements some remaining gaps:

  • EIP-158, which is related to state clearing.
  • EIP-2200, which was an important gap to charge SSTORE correctly.

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.

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();
Copy link
Owner Author

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.

Comment on lines +295 to +298
for (env.state.touched_addresses.items) |address| {
if (env.state.isEmpty(address))
env.state.destroyAccount(address);
}
Copy link
Owner Author

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: {
Copy link
Owner Author

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.

Comment on lines -324 to +391
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;
Copy link
Owner Author

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});
Copy link
Owner Author

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.

Comment on lines -71 to +75
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});
Copy link
Owner Author

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.

Comment on lines +20 to +22
// 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,
Copy link
Owner Author

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.

Copy link
Collaborator

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.

Comment on lines +27 to 30
// Tx-scoped lists.
touched_addresses: ArrayList(Address),
accessed_accounts: AddressSet,
accessed_storage_keys: AddressKeySet,
Copy link
Owner Author

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.

Comment on lines +108 to +111
if (std.mem.eql(u8, &value, &std.mem.zeroes(Bytes32))) {
_ = account.storage.remove(key);
return;
}
Copy link
Owner Author

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.

@jsign jsign changed the title [Draft] Implement EIP-158 and EIP-2200 which allow to pass 7 extra spec tests [on hold] Implement EIP-158 and EIP-2200 which allow to pass 7 extra spec tests Jan 23, 2024
@jsign jsign mentioned this pull request Jan 30, 2024
@jsign jsign changed the title [on hold] Implement EIP-158 and EIP-2200 which allow to pass 7 extra spec tests Implement EIP-158 and EIP-2200 which allow to pass 7 extra spec tests Jan 30, 2024
Base automatically changed from jsign-vm2 to main February 6, 2024 23:19
Copy link
Collaborator

@gballet gballet left a 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.

Comment on lines +20 to +22
// 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,
Copy link
Collaborator

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.

@jsign jsign merged commit 2a4bcb1 into main Feb 7, 2024
4 checks passed
@jsign jsign deleted the jsign-vm3 branch February 7, 2024 17:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants