Stop charging gas for retryable redeem gas pool update on ArbOS 60+#4101
Stop charging gas for retryable redeem gas pool update on ArbOS 60+#4101
Conversation
❌ 10 Tests Failed:
View the top 3 failed tests by shortest run time
📣 Thoughts on this report? Let Codecov know! | Powered by Codecov |
4fa5689 to
85e2c9c
Compare
32ca70c to
2bc088b
Compare
gligneul
left a comment
There was a problem hiding this comment.
Looks good, just minor comments.
749e9c7 to
29a5c43
Compare
| } | ||
|
|
||
| func TestRetryableRedeem(t *testing.T) { | ||
| func overrideStateArbOSVersion(evm *vm.EVM, arbosVersion uint64) error { |
There was a problem hiding this comment.
instead of that, use newMockEVMForTestingWithVersion
There was a problem hiding this comment.
I don't follw. If newMockEVMForTestingWithVersion needs to be fixed, let's fix it. Let's talk about it later.
| // L2PricingState().ShrinkBacklog(). BacklogUpdateCost() returns | ||
| // that amount based on the storage read/write mix used by ShrinkBacklog(). | ||
| backlogUpdateCost := uint64(0) | ||
| if c.State.L2PricingState().ArbosVersion >= params.ArbosVersion_60 { |
There was a problem hiding this comment.
in all of those this shouldn't be ArbosVersion60, but arbosVersion_RedeemChargingFix or something similar.
So we could easily change the version in which this applies (can be a number only after it's issued)
There was a problem hiding this comment.
I fixed it to ArbosVersion_MultiGasConstraintsVersion to exclude the possibility of an intermediate state under which there is no implementation.
| backlogUpdateCost := uint64(0) | ||
| if c.State.L2PricingState().ArbosVersion >= params.ArbosVersion_60 { | ||
| // Charge static price for any pricer starting from ArbOS 60 | ||
| backlogUpdateCost = l2pricing.ArbOS60StaticBacklogUpdateCost |
There was a problem hiding this comment.
why not just add that logic into L2PricingState().BacklogUpdateCost() ?
| return retryTxHash, c.State.L2PricingState().ShrinkBacklog(gasToDonate, multigas.ComputationGas(gasToDonate)) | ||
| // Starting from ArbOS 60, we don't charge gas for the ShrinkBacklog call here | ||
| if c.State.L2PricingState().ArbosVersion >= params.ArbosVersion_60 { | ||
| err = c.WithUnmeteredGasAccounting(func() error { |
There was a problem hiding this comment.
I get the idea and kind of like it.. however, since the context only exists for a specific call and will be removed once you return from this function (it is created in "func (p *Precompile) Call"), I think this adds more complexity then safety, and it'll probably be simpler to just have a context.StopCollectingGas() function or something similar. This will also allow you to reuse the call to ShrinkBacklog between the options and help us in case we do anything else in the end of the function make sure we don't spend (and need to allocate) more gas.
There was a problem hiding this comment.
I agree, but there is one nuance: after the method completes, the context is still in use, and I see a difference of 3 gas units if I leave it free. I corrected it to a compromise option with defer c.SetUnmeteredGasAccounting(false)
29a5c43 to
48b4998
Compare
6f44f27 to
e458d6d
Compare
| } | ||
|
|
||
| func TestRetryableSubmissionAndRedeemFees(t *testing.T) { | ||
| t.Helper() |
There was a problem hiding this comment.
this is the main test func, should not be a helper
| // This ensures that the gas pool has enough gas to run the retryable attempt. | ||
| // TODO(NIT-4120): clarify the gas dimension for gasToDonate | ||
| // Starting from ArbosVersion_MultiGasConstraintsVersion, don't charge gas for the ShrinkBacklog call. | ||
| stopChargingGas := c.State.L2PricingState().ArbosVersion >= params.ArbosVersion_MultiGasConstraintsVersion |
There was a problem hiding this comment.
where do you charge the backlog update cost?
There was a problem hiding this comment.
This is my current understanding:
| ArbOS version | Active pricer(s) possible | BacklogUpdateCost() behaviour |
|---|---|---|
| < 50 | Legacy | StorageReadCost + StorageWriteCost |
| SingleGasConstraintsVersion (50) | Legacy / SingleGasConstraints | StorageReadCost (for model detection) + legacy fallback cost. Buggy if constraints > 0 |
| MultiConstraintFix (51) | Legacy / SingleGasConstraints | If constraints exist: • StorageReadCost (model check)• StorageReadCost (iterate)• N × (StorageReadCost + StorageWriteCost)Else legacy cost |
| >= MultiGasConstraintsVersion (60) | Legacy / SingleGas / MultiGas | Always MultiConstraintStaticBacklogUpdateCost, independent of model |
So having the single gas constraints configured on ArbOS 50 should be the only broken state (fixed by MultiConstraintFix)
There was a problem hiding this comment.
So backlogUpdateCost := c.State.L2PricingState().BacklogUpdateCost() should be always the correct value
There was a problem hiding this comment.
With the latest changes:
- MultiConstraintStaticBacklogUpdateCost is the actual charged price for the redeem backlog update.
- Fix redeem test: the extra
storage.StorageWriteCost - storage.StorageWriteZeroCostis now expected only for < ArbOS 60.
…edeem-gas-budgeting-fro-arbos-60
Fixes NIT-4152
pulls in OffchainLabs/go-ethereum#599
Changes:
WithUnmeteredGasAccountingto the precompile context to ignore gas charges within theShrinkBacklogcall.