-
Notifications
You must be signed in to change notification settings - Fork 143
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
fix: Fail cleanly on negative gas limit #17486
base: main
Are you sure you want to change the base?
Conversation
…e gas limit Signed-off-by: Kim Rader <[email protected]>
Coverage summary from CodacySee diff coverage on Codacy
Coverage variation details
Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: Diff coverage details
Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: See your quality gate settings Change summary preferencesCodacy stopped sending the deprecated coverage status on June 5th, 2024. Learn more |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #17486 +/- ##
=========================================
Coverage 68.96% 68.97%
- Complexity 22767 22775 +8
=========================================
Files 2619 2619
Lines 98282 98300 +18
Branches 10184 10187 +3
=========================================
+ Hits 67783 67802 +19
- Misses 26669 26671 +2
+ Partials 3830 3827 -3
|
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.
Questions you could answer if you wish, and a request for some testi for the change to GasLimitDeterministicThrottle
.
if (txGasLimit < 0) { | ||
throw new IllegalArgumentException("Gas limit must be non-negative, but was " + txGasLimit); | ||
} |
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.
Is this reasonable for it to throw on negative? I traced back one call chain (the one through ThrottleAccumulator.checkAndEnforceThrottle
) to QueryWorkflowIMpl.handleQuery
which is the first one with a try/catch
and it looks like that'll catch it as a Exception
, emit an error, and than fail the transaction. Instead of reporting BUSY
(which, admittedly, is odd for negative gas, probably should be caught and translated toINSUFFICIENT_GAS
). There's another call chain too, I didn't follow it to the tops of it, but doesn't look like any close exception handler there either. If we're sticking with the signature of this method so that it returns boolean
maybe it should just return false
- it's invalid input so just throttle it.
Or maybe it just needs to throw a PrecheckException
instead of IllegalArgumentException
.
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.
Also, should have a test for negative in GasLimitDeterministicThrottleTest
.
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.
Also, I wonder if we should disallow anything less than the intrinsic gas limit here. It's just going to get rejected at precheck anyway. Is there a reason to disallow those txs earlier? Some kind of fairness or DoS argument?
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 my first iteration of this PR, I had it throwing a PreCheckException
here. I ended up changing that on the grounds that I didn't want to add a dependency on com.hedera.node.app.spi
module. The throws IllegalArgumentException
is just a sanity check, any execution path should fail long before it gets here.
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 will add a test for negative gasLimit in GasLimitDeterministicThrottleTest
.
.orElse(0L); | ||
default -> 0L; | ||
}; | ||
if (gas < 0) { |
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.
Again, my question would be: Why <0
instead of <=0
or even <= 21000
.
(Don't know the answer here or above, which is why I'm asking.)
In this case you'd have to signal the default
case - i.e., not a contract-related operation throttled by gas - separately than using 0L
.
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.
Needs a test in IngestCheckerTest.ThrottleTests
?
Actually, I don't see a test for any of the conditions in assertThrottlingPreconditions
. Also actually, assertThrottlingPreconditions
seems misnamed? Until this code you just added it doesn't seem to be checking throttling preconditions at all, just some interesting system preconditions.
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.
Most of the preconditions are checked during pureChecks
methods on each transaction type. That's where we check whether the gas limit is <=intrinsicGas. But, checking throttles comes earlier in the ingest workflow than running pureChecks. Before we check throttles, we do just the bare minimum checks necessary to ensure that the throttle checking code will succeed. That's what this method is about.
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.
And yes, I'll add that test too.
@@ -1272,4 +1272,29 @@ final Stream<DynamicTest> callHtsSystemContractTest() { | |||
.hasKnownStatus(SUCCESS)); | |||
})); | |||
} | |||
|
|||
@HapiTest | |||
final Stream<DynamicTest> negativeGasFailsGracefully() { |
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 tests new code at IngestChecker.assertThrottlingPreconditions
. Needs a separate test for new code at GasLimitDeterministicThrottle.allow
. If there's a way to hapispec test throttles, don't know.
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 GasLimitDeterministicThrottle.allow txGasLimit<0 code path should never execute. I'll create a unit test for it but I don't think there's any way to create a hapi test.
Signed-off-by: Kim Rader <[email protected]>
Signed-off-by: Kim Rader <[email protected]>
Signed-off-by: Kim Rader <[email protected]>
Description:
When a contract transaction is submitted with a negative gas limit, we currently throw an exception. Instead we should return INSUFFICIENT_GAS.
Related issue(s):
Fixes #17470