feat: bus mapping for sload and sstore#418
Conversation
CPerezz
left a comment
There was a problem hiding this comment.
I just reviewed SSTORE opcode implementation in bus-mapping and some other stuff you added but stopped due to:
-
The PR is marked as Ready for Review but is not up to date with
main. That basically causes that you haven't synced with #349 and therefore, you've implemented a test-utils module which should most probably be removed. -
Also, the tests for SSTORE are missing a lot of different cases which are only testeable with the additions to
mockcrate inmain.
My suggestion:
- Remove all of the test-utils you've introduced in this PR (makes the review much more complex as there are a lot of files and different topics to review/address) when in theory the PR just wants to implement SSTORE and SLOAD bus-mapping opcodes.
- The circuit impl is only done for SSTORE. Either you add both or none and do it in another follow-up PR.
Before introducing test-suit/mock changes or new utils, please, file an issue before so that this does not happen again and work is lost or unusable.
Also, make sure that the PRs are more atomic. As otherways, the review time that consumes is massive and not so productive.
Thanks. Carlos.
|
|
||
| for (index, geth_step) in geth_trace.struct_logs.iter().enumerate() { | ||
| let mut state_ref = self.state_ref(&mut tx, &mut tx_ctx); | ||
| log::trace!("handle {}th opcode {:?} ", index, geth_step.op); |
There was a problem hiding this comment.
I prefer tokio/tracing for these things. But maybe it's not the best option.
Maybe @ed255 has some suggestions
There was a problem hiding this comment.
I'm happy with using the log crate here, it's very lightweight and if logs aren't activated they don't add any performance penalty as far as I know. I don't know about tokio/tracing so I can't comment on that.
| // Fields with transaction lifespan, will be clear in `clear_access_list_and_refund`. | ||
| access_list_account: HashSet<Address>, | ||
| access_list_account_storage: HashSet<(Address, U256)>, | ||
| // `dirty_storage` constains writes during current transaction. |
There was a problem hiding this comment.
| // `dirty_storage` constains writes during current transaction. | |
| // `dirty_storage` contains writes during current transaction. |
| #[serde(default)] | ||
| refund: Gas, |
There was a problem hiding this comment.
Maybe add a comment to highlight that this does not pertain to the original GethExecStepInternal (alias StructLogs in Geth) and that it has been only added to allow compilation. As the only place where this is needed is in GethExecStep.
Also, maybe an Option<Gas> type makes everything easier IDK. And you just need to add it in GethExecStep without touching the internal one.
There was a problem hiding this comment.
BTW, how was this working before that PR if we did not have this field in the struct??
Has it appeared after the change to latest for the geth version used??
| services: | ||
| geth0: | ||
| image: "ethereum/client-go:stable" | ||
| image: "ethereum/client-go:latest" |
There was a problem hiding this comment.
Are we sure about that? Note that Geth is now with the integration of the merge and ETH2 so I'm not sure if we want all that stuff inside in our tests now.
There was a problem hiding this comment.
Is there any reason specific to that PR that requires the latest version?
| #[cfg(test)] | ||
| #[ctor::ctor] | ||
| fn init_env_logger() { | ||
| // Enable RUST_LOG during tests | ||
| env_logger::init(); | ||
| } |
There was a problem hiding this comment.
2 concerns about this:
- Can we make it feature-dependant? I'm not sure if we will always want to print all the logs for all the tests as we will not see anything else than logs and the stdout will explode really quickly.
- Why
ctoras opposite tolazy_static+ initialization function? Is it a common practice?
There was a problem hiding this comment.
I understand the concerns here!
For the first point, this would be a dev feature right? I don't think rust supports dev features though (I don't think we should expose a public feature that starts the env_logger, as that's a decision that must be made by the consumer of the library). Nevertheless, for the concern about having lots of outputs by default, we could mitigate this by setting the default log level to error, and then via the RUST_LOG env var you can dynamically enable lower levels.
For the second point, I find the usage of ctor interesting, because it guarantees that env_logger::init() is called once always in tests at the beginning, without requiring updating the tests themselves. Using lazy_static would require that every test function calls a setup function (or use a crate that handles test setup, but in any case we still need to add 1 line for each test function, which is cumbersome).
| let geth_step = &geth_steps[0]; | ||
| let mut exec_step = state.new_step(geth_step)?; | ||
|
|
||
| let _call_id = state.call()?.call_id; |
| let value_prev = *value_prev; | ||
| let (_, committed_value) = state.sdb.get_committed_storage(&contract_addr, &key); | ||
| let committed_value = *committed_value; |
There was a problem hiding this comment.
| let value_prev = *value_prev; | |
| let (_, committed_value) = state.sdb.get_committed_storage(&contract_addr, &key); | |
| let committed_value = *committed_value; | |
| let value_prev = value_prev.clone(); | |
| let (_, committed_value) = state.sdb.get_committed_storage(&contract_addr, &key); | |
| let committed_value = committed_value.clone(); |
Make the clones explicit please.
| value: true, | ||
| value_prev: is_warm, |
| use pretty_assertions::assert_eq; | ||
|
|
||
| #[test] | ||
| fn sstore_opcode_impl() { |
There was a problem hiding this comment.
This test is missing several things IMO:
- Refund logic was added to the crate but is never tested to be working correctly. I think SSTORE should have a testcase where it does not only write but also plays with the refund.
- We should also add testcases for
COLD&WARMsituations. - This should be using the
mock::TestContexthelpers added in Modularize mock crate for easier and more customizable testing setup generation #349.
Please take a look to it and how to use it and it will allow you to perform all the testing you need.
|
So we cannot reopen this.... sorry .. will open a pr |
…merged into `ErrorOutOfGasMemoryCopy`. (privacy-ethereum#418)
Some explanation:
dirty_storageis added to statedb.rs, just like StateDB in go-ethereum.refundin trace