-
Notifications
You must be signed in to change notification settings - Fork 764
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
Reduce gas/storage limits in nested calls #6890
base: master
Are you sure you want to change the base?
Conversation
376e944
to
4832380
Compare
Also, a limit of 0 when determining a nested call's metering limit would mean it was free to use all of the callee's resources. Now, a limit of 0 means that the nested call will have an empty storage meter.
In particular, this commit removes the usage of `0` as unlimited metering in the following tests: - `nonce` - `last_frame_output_works_on_instantiate` - `instantiation_from_contract` - `immutable_data_set_works_only_once` - `immutable_data_set_errors_with_empty_data` - `immutable_data_access_checks_work`
ed1f312
to
8e66f50
Compare
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.
The basic idea of the 63/64 rule looks correct to me but there are many failing tests. I left some nits.
substrate/frame/revive/src/gas.rs
Outdated
.min(self.gas_left); | ||
self.gas_left -= amount; | ||
GasMeter::new(amount) | ||
// The reduction to 63/64 is to emulate EIP-150 |
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 should be a doc-comment
debug_assert!(matches!(self.contract_state(), ContractState::Alive)); | ||
|
||
// Limit gas for nested call, per EIP-150. |
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 could go into the doc-comment (which is no no-longer correct I think)
This fixes, among other tests: * `tests::gas_consumed_is_linear_for_nested_calls` test * `tests::deposit_limit_in_nested_calls` * `tests::transient_storage_limit_in_call` * `tests::call_return_code` * `test::chain_extension_temp_storage_works` * `tests::origin_api_works` * `tests::read_only_call_works`
@xermicus the meters in |
Sorry if this wasn't clear: Only |
@athei Most of the previously failing tests were caused by the contract code of those tests using the now-removed '0 means "use all available gas"' semantic. After fixing this,
The contracts the above tests rely on have removed usages of 0 as "use all", so their failures are somewhere else. |
14 unit tests are still failing, among them these 2 tests fail because of a The remaining tests fail with
⬆️ is context in case you have any insights to share - the tests all failing for the same reason must be a clue to the underlying problem. I'll move fast so paritytech/revive#117 can continue. |
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.
Looks good. Just some nits.
Regarding the failing tests: Your code looks correct to me. However, it is a breaking change as it prevents sub calls from using all the remaining gas which was possible before. So I assume the tests rely in one way or another on this behavior and need to be changed.
This can be a bit finicky and requires some knowledge of how the error handling works in contracts to debug. The error you are asserting on here is what is returned from the root contract that is called from the transaction. However, when this contract calls into another contract and the callee encounters an error like The change you made by removing This is actually expected and nice that it is covered by test cases. You should change the tests to adapt to the new behavior. You can see that the caller contract also returns the sub calls return code in addition to reverting. So you can check this return code in your test and are not at the mercy of the generic |
Use `BareCallBuilder::bare_call` instead of `CallBuilder::call` to allow scrutiny of contract return code with `assert_return_code`, and disambiguate the cause of the `ContractReverted` error that `CallBuilder::build` would have raised.
Thanks for clarifying this - in The remaining ones throw |
1844efa
to
b090e5f
Compare
Apologies for the force-push - I made a mistake in a commit prior to the |
A limit of `0` no longer signifies "no limit", and must thus be changed to `u64::MAX`.
/cmd fmt |
Command "fmt" has started 🚀 See logs here |
Command "fmt" has finished ✅ See logs here |
A deposit limit of 0 no longer is a special case, and is treated as no limit being available for use in a benchmarking function.
The only tests that still need to be addressed:
|
@athei One question: What is the meaning of This is causing |
The line you quoted is |
There, its meaning was "use all available gas", which needed to be updated to `Weight::MAX`.
/// | ||
/// Deposit limits are `U256`, but balances are represented as `u64`. | ||
/// To represent no deposit limits on an operation, this should be used. | ||
pub const U256_MAX: [u8; 32] = u64_to_u256_bytes(u64::MAX); |
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.
Should be the same, right?
pub const U256_MAX: [u8; 32] = u64_to_u256_bytes(u64::MAX); | |
pub const U256_MAX: [u8; 32] = [1; 32]; |
Weight::zero(), | ||
U256::zero(), | ||
Weight::MAX, | ||
U256::from(u64::MAX), |
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.
Same for the other occurrences.
U256::from(u64::MAX), | |
U256::MAX, |
All GitHub workflows were cancelled due to failure one of the required jobs. |
Closes #6846 .