-
Notifications
You must be signed in to change notification settings - Fork 1.7k
light-fetch: Differentiate between out-of-gas/manual throw and use required gas from response on failure #9824
Conversation
@niklasad1 looks nice, but I'm yet to test it. Could you add a unit test? :) |
452a20d
to
418d20f
Compare
@ordian Might be a little annoying but change the |
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 PR looks good (with the switch to virtual this is a nice optimization and should indeed solve the transaction cost issue (I did not test)), I got a few comment/suggestion.
I still believe we need to switch back to non virtual execution or find a way to circumvent the issue I talk to you about last friday (currently I could not think of any other way than switching back).
rpc/src/v1/helpers/light_fetch.rs
Outdated
} else { | ||
return Ok(future::Loop::Continue(params)) | ||
} | ||
// `OutOfGas` exception can't occur here because of virtual execution context |
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.
Even if it will not be executed, I think we should keep the existing code (with the new NotEnoughBaseGas exeption). That way we can still support non updated full peers (there should not be much in fact), and we could revert to non virtual full node execution more easily in the future (switching back to non virtual will not imply having to update every light client).
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.
I don't understand this. NotEnoughBasGas
is not an exception, see https://github.com/paritytech/parity-ethereum/blob/master/ethcore/vm/src/error.rs#L38-#L86
Clarify please :P
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.
👍 indeed, we could use vm::Error::OutOfGas instead.
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.
Right, got it very good catch 👍
Ok(future::Loop::Break(Err(ExecutionError::NotEnoughBaseGas { required, got }))) | ||
} | ||
} | ||
// Non-recoverable execution error |
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.
Here (we need to test to assert the error actually occurs), there is possibly 'ExecutionError::BlockGasLimitReached', maybe we do not need the previous test.
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.
Well, If we get BlockGasLimitReached
then it is definitely a faulty request and AFAIK any of the others errors can't be recovered!
The possible errors can be found:
https://github.com/paritytech/parity-ethereum/blob/master/ethcore/src/executed.rs#L74-#L118
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.
Yes I was just wondering if the test above could be remove, but it seems safe to keep it.
trace!(target: "light_fetch", "Not enough start gas provided required: {}, got: {}", required, got); | ||
if required <= params.hdr.gas_limit() { | ||
params.tx.gas = required; | ||
return Ok(future::Loop::Continue(params)) |
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.
I am just thinking about it, but we probably want to apply a margin (a n% fix additional cost) : since the transaction may not run in the same block (and even in the same block it can vary) the cost may change when running the actual transaction.
It is not really related to this PR, but likely to happen with some contracts, this PR may makes it more obvious (previously by doubling gas cost there was lesser chance for it to happen).
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 something that we have historically decided not to handle on the node side in order to give the most faithful estimate we can. Wrappers around the RPCs typically add a few percent to the result of estimateGas
.
read_only
can't run out-of-gas and use required gas from response on failure418d20f
to
592ca94
Compare
rpc/src/v1/helpers/light_fetch.rs
Outdated
// TODO: how to distinguish between actual OOG and | ||
// exception? | ||
if executed.exception.is_some() { | ||
// `OutOfGas` exception can only occur on full-nodes that run `Parity-Ethereum v2.1.1` or older |
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.
From our chat conversation of today, I think we may still run into out of gas.
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.
Thanks, should be sufficient just to change the comment right?
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.
I think so, (we thankfully kept code for iterative querying).
6f8f743
to
4786558
Compare
if params.tx.gas > params.hdr.gas_limit() { | ||
trace!(target: "light_fetch", "OutOutGas exception received, gas increase: failed"); |
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.
Why dont we try with the params.hdr.gas_limit()
at the very end? I can easily imagine a situation, where block_gas_limit / 2 + 1
is not sufficient, but block_gas_limit / 2 + 2
is enough.
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 is todo to use binary search, maybe we should implement that (copy https://github.com/paritytech/parity-ethereum/blob/5f3ae4dee34ede2738473b35db22f8d65351b69b/ethcore/src/client/client.rs#L1539 ?).
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.
I'm in favor of merging this PR. This comment can be addressed in a separate one.
Same thing here, I just feel that @tomusdrw comment should be addressed (when we multiply gas by 2 we should finish with max block size (if not already eq to max block size)). Something along the line of : if params.tx.gas == params.hdr.gas_limit() {
trace!(target: "light_fetch", "OutOutGas exception received, gas increase: failed");
} else {
params.tx.gas = params.tx.gas * 2_u32;
if params.tx.gas > params.hdr.gas_limit() {
params.tx.gas = params.hdr.gas_limit();
}
trace!(target: "light_fetch", "OutOutGas exception received, gas increase: succeed");
return Ok(future::Loop::Continue(params))
}
|
* Change START_GAS: 50_000 -> 60_000 * When the `OutOfGas exception` is received then try to double the gas until it succeeds or block gas limit is reached * When `NotEnoughBasGas error` is received then use the required gas provided in the response
Try the `block_gas_limit` before regard the execution as an error
4786558
to
73c00b9
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.
LGTM, just a small nitpick on the comparison but it should not really be an issue.
Co-Authored-By: niklasad1 <niklasadolfsson1@gmail.com>
…quired gas from response on failure (#9824) * fix start_gas, handle OOG exceptions & NotEnoughGas * Change START_GAS: 50_000 -> 60_000 * When the `OutOfGas exception` is received then try to double the gas until it succeeds or block gas limit is reached * When `NotEnoughBasGas error` is received then use the required gas provided in the response * fix(light-fetch): ensure block_gas_limit is tried Try the `block_gas_limit` before regard the execution as an error * Update rpc/src/v1/helpers/light_fetch.rs Co-Authored-By: niklasad1 <niklasadolfsson1@gmail.com>
…quired gas from response on failure (#9824) * fix start_gas, handle OOG exceptions & NotEnoughGas * Change START_GAS: 50_000 -> 60_000 * When the `OutOfGas exception` is received then try to double the gas until it succeeds or block gas limit is reached * When `NotEnoughBasGas error` is received then use the required gas provided in the response * fix(light-fetch): ensure block_gas_limit is tried Try the `block_gas_limit` before regard the execution as an error * Update rpc/src/v1/helpers/light_fetch.rs Co-Authored-By: niklasad1 <niklasadolfsson1@gmail.com>
* bump stable 2.1.6 * ethcore: use Machine::verify_transaction on parent block (#9900) * ethcore: use Machine::verify_transaction on parent block also fixes off-by-one activation of transaction permission contract * ethcore: clarify call to verify_transaction * fix: Intermittent failing CI due to addr in use (#9885) Allow OS to set port at runtime * gitlab-ci: make android release build succeed (#9743) * use docker cargo config file for android builds * make android build succeed * Update light-client hardcoded headers for foundation: #6692865, ropsten: #4417537, kovan: #9363457 * Remove rust-toolchain file (#9906) * light-fetch: Differentiate between out-of-gas/manual throw and use required gas from response on failure (#9824) * fix start_gas, handle OOG exceptions & NotEnoughGas * Change START_GAS: 50_000 -> 60_000 * When the `OutOfGas exception` is received then try to double the gas until it succeeds or block gas limit is reached * When `NotEnoughBasGas error` is received then use the required gas provided in the response * fix(light-fetch): ensure block_gas_limit is tried Try the `block_gas_limit` before regard the execution as an error * Update rpc/src/v1/helpers/light_fetch.rs Co-Authored-By: niklasad1 <niklasadolfsson1@gmail.com> * fix #9824 merge artifacts * simplify cargo audit * ci: nuke the gitlab caches (#9855)
* Bump beta to version 2.2.1 * fix: Intermittent failing CI due to addr in use (#9885) Allow OS to set port at runtime * Use Weak reference in PubSubClient (#9886) * Fix json tracer overflow (#9873) * Fix json tracer overflow * Replace trace_executed with a direct trace push * Remove unused variable * Add test for 5a51 * Remove duplicate json! * Fix docker script (#9854) * Dockerfile: change source path of the newly added check_sync.sh (#9869) * Allow to seal work on latest block (#9876) * Allow to seal work on latest block. * Test from @todr to check sealing conditions. * gitlab-ci: make android release build succeed (#9743) * use docker cargo config file for android builds * make android build succeed * ethcore: use Machine::verify_transaction on parent block (#9900) * ethcore: use Machine::verify_transaction on parent block also fixes off-by-one activation of transaction permission contract * ethcore: clarify call to verify_transaction * foundation: #6692865, ropsten: #4417537, kovan: #9363457 * Remove rust-toolchain file (#9906) * EIP-712 implementation (#9631) * EIP-712 impl * added more tests * removed size parsing unwrap * corrected TYPE_REGEX to disallow zero sized fixed length arrays, replaced LinkedHashSet with IndexSet, added API spec to docs, fixed Type::Byte encoding branch * use Option<u64> instead of u64 for Type::Array::Length * replace `.iter()` with `.values()` Co-Authored-By: seunlanlege <seunlanlege@gmail.com> * tabify eip712.rs * use proper comments for docs * Cargo.lock: revert unrelated changes * tabify encode.rs * EIP 191 (#9701) * added sign_191 rpc method * fixed hash_structured_data return type * added ConfirmationPayload::SignMessage for non-prefixed signatures, added tests for sign191 * renamed WithValidator -> PresignedTransaction * rename applicationData to data in test * adds docs for EIP191Version, renamed SignRequest to EIP191SignRequest * light-fetch: Differentiate between out-of-gas/manual throw and use required gas from response on failure (#9824) * fix start_gas, handle OOG exceptions & NotEnoughGas * Change START_GAS: 50_000 -> 60_000 * When the `OutOfGas exception` is received then try to double the gas until it succeeds or block gas limit is reached * When `NotEnoughBasGas error` is received then use the required gas provided in the response * fix(light-fetch): ensure block_gas_limit is tried Try the `block_gas_limit` before regard the execution as an error * Update rpc/src/v1/helpers/light_fetch.rs Co-Authored-By: niklasad1 <niklasadolfsson1@gmail.com> * simplify cargo audit * Use block header for building finality (#9914) * ci: nuke the gitlab caches (#9855)
Attempt to close #6155 & close #9031
What does this PR:
start_gas
replied to us to set the nextstart_gas
if it doesn't exceed the block's gas limit (however this could be changed to set thestart_gas
regardless of block_limit and continue until we getBlockGasLimitReached
error instead, will probably require at least one extra network request)Example execution with 50_000 as start_gas: