feat(arbos60): add multi-gas constraints pricing model#700
Conversation
c1c7363 to
f338aff
Compare
There was a problem hiding this comment.
Pull request overview
Implements ArbOS 60 multi-gas constraints pricing with per-resource weighted backlogs and per-resource base fees, and wires it into transaction processing and pricing updates.
Changes:
- Added storage-backed
MultiGasConstraintandMultiGasFeesprimitives for ArbOS 60+ multi-dimensional pricing. - Updated
L2PricingStateto select aGasModel, update multi-gas backlogs/exponents, and commit per-resource fees. - Integrated multi-gas backlog growth in tx processing and added extensive tests across pricing, storage, and precompile-related behaviors.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Nethermind.Arbitrum/Math/MathExtensions.cs | Adds inlining hints for saturating arithmetic helpers used by backlog math. |
| src/Nethermind.Arbitrum/Execution/ArbitrumTransactionProcessor.cs | Routes gas pool/backlog updates by GasModel, wiring multi-gas growth. |
| src/Nethermind.Arbitrum/Evm/MultiGas.cs | Adds CheckResourceKind helper and adjusts docs. |
| src/Nethermind.Arbitrum/Evm/ArbitrumGasPolicy.cs | Tracks code deposit under StorageGrowth for multi-gas accounting. |
| src/Nethermind.Arbitrum/Arbos/Storage/MultiGasFees.cs | New storage struct for next/current per-resource base fees with commit rotation. |
| src/Nethermind.Arbitrum/Arbos/Storage/MultiGasConstraint.cs | New storage struct for weighted multi-resource constraints and weighted backlog updates. |
| src/Nethermind.Arbitrum/Arbos/Storage/L2PricingState.cs | Core pricing/state changes: GasModel, multi-gas exponent calc, fee update/commit, backlog routing. |
| src/Nethermind.Arbitrum/Arbos/Storage/GasConstraint.cs | Cleans up storage clearing via new Clear() methods; makes class sealed. |
| src/Nethermind.Arbitrum/Arbos/Storage/ArbosStorage.cs | Adds Clear() to slot and storage-backed primitives. |
| src/Nethermind.Arbitrum/Arbos/ArbosVersion.cs | Introduces version 60 constants / alias for multi-gas constraints enablement. |
| src/Nethermind.Arbitrum.Test/Precompiles/PrecompileContextTests.cs | Adds tests for multi-gas tracking (some currently don’t exercise production code). |
| src/Nethermind.Arbitrum.Test/Precompiles/ConstraintsPrecompileTests.cs | Adds tests around configuring and using multi-gas constraints. |
| src/Nethermind.Arbitrum.Test/Infrastructure/ArbosStateTestExtensions.cs | Adds test-only helpers for reading/writing multi-gas fees. |
| src/Nethermind.Arbitrum.Test/Evm/MultiGasTests.cs | Adds tests for CheckResourceKind validation behavior. |
| src/Nethermind.Arbitrum.Test/Arbos/Storage/L2PricingStateTests.cs | Expands test coverage for gas model selection, backlog updates, multi-gas pricing, and guards. |
| src/Nethermind.Arbitrum.Test/Arbos/L2Pricing/PricingModelMultiGasTests.cs | Adds equivalence tests across legacy/single/multi-gas models. |
| src/Nethermind.Arbitrum.Test/Arbos/L2Pricing/MultiGasFeesTests.cs | Adds tests for per-resource fees and commit semantics. |
| src/Nethermind.Arbitrum.Test/Arbos/L2Pricing/MultiGasConstraintTests.cs | Adds tests for weighted backlog math and storage behavior. |
| src/Nethermind.Arbitrum.Test/Arbos/ArbosStorageTests.BackedByType.cs | Adds tests for new Clear() methods on storage-backed primitives. |
| src/Nethermind | Updates submodule pointer. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
wurdum
left a comment
There was a problem hiding this comment.
Please add integration tests to make sure e2e compatibility with nitro
Added more tests. The next step in my plan is to adopt system tests |
d900d77 to
f55414e
Compare
|
@AnkushinDaniil I've opened a new pull request, #712, to work on those changes. Once the pull request is ready, I'll request review from you. |
|
I would wait for system tests inclusion for better stability and assurance. I don't think there is any reason to rush this..my humble opinion. |
Add ArbOS 60 multi-gas constraints with per-resource weights: - MultiGasConstraint: storage-backed constraint with weighted resources - MultiGasFees: per-resource base fee storage (next-block/current-block) - L2PricingState: constraint management, exponent calculation, pricing updates - GasModel enum for routing: Legacy, SingleGasConstraints, MultiGasConstraints - Input validation and bounds checking throughout
- Add Clear() to storage-backed types (ArbosStorageSlot, ArbosStorageBackedUInt/ULong/UInt256) - Add MultiGas.CheckResourceKind() validation for defensive programming - Throw InvalidOperationException on divisor == 0 instead of silent continue - Move test-only methods to test project via extension methods - Move weights dictionary inside loop to match reference implementation
In ArbOS 60+ (multi-gas constraints), BacklogUpdateCost returns a static cost (StorageReadCost + StorageWriteCost) regardless of constraint count. The C# implementation was missing this early return and continued with additional overhead calculations. Added tests to verify the static cost behavior in ArbOS 60 and the dynamic cost calculation in ArbOS 51.
…ization Performance improvements for multi-gas constraints implementation: - Add [AggressiveInlining] to SaturateMul and SaturateSub for consistency with SaturateAdd (MathExtensions.cs) - Seal leaf classes (MultiGasConstraint, GasConstraint, MultiGasFees, L2PricingState) to enable JIT devirtualization - Replace yield iterator in CalcMultiGasConstraintsExponents with direct loop to avoid state machine allocation per-call - Use inline array FeeBuffer instead of heap-allocated UInt256[] in MultiDimensionalPriceForRefund to eliminate per-transaction allocation
Add 24 tests to achieve full patch coverage: - Exception guards: divisor-zero checks in CalcMultiGasConstraintsExponents and UpdatePricingModelMultiConstraints - Migration path: SetMultiGasConstraintsFromSingleGasConstraints conversion, uint32 clamping, and clearing existing constraints - Legacy pricing: GasPoolUpdateCost for ArbOS 49/50, legacy backlog grow/shrink, high backlog pricing - Multi-gas fees: CommitMultiGasFees early return and commit paths, L1Calldata/zero fee fallback to baseFeeWei - MultiGas: CheckResourceKind validation for valid and invalid kinds - ArbosStorage: Clear methods for UInt, ULong, UInt256 backed storage
Remove ShouldUseGasConstraints() which was a C#-only helper that didn't exist in Nitro. Use GetGasModelToUse() directly instead, which matches Nitro's GasModelToUse() function. Changes: - Remove ShouldUseGasConstraints() from L2PricingState - Update tests to use GetGasModelToUse() assertions - Remove tests that directly tested the removed method
…sPool UpdateGasPool now routes to GrowBacklog for ArbOS 60+ MultiGasConstraints mode, matching Nitro's tx_processor behavior. Legacy and SingleGasConstraints modes continue using AddToGasPool. Added tests mirroring Nitro's TestMultiGasConstraintBacklogGrowth and TestMultiGasConstraintBacklogDecay patterns for weighted accumulation.
Remove Arrange/Act/Assert comments from ConstraintsPrecompileTests and PrecompileContextTests per code style guidelines.
|
Well done. Figuring out where to put all these |
…pport The IJsonTypeInfoResolver approach (da1ebcb) broke polymorphic serialization — ArbitrumReceiptForRpc properties (GasUsedForL1, MultiGasUsed) were not serialized in comparison mode responses. Revert to a custom JsonConverter<ReceiptForRpc> that delegates to the runtime type, restoring correct receipt comparison.
- Remove unused `spec` variable in ArbitrumBlockProducer - Replace `var` with explicit types (ReceiptForRpcPolymorphicConverter, TestArbosStorage) - Introduce DisabledArbOsVersionOverride and make IArbOSVersionOverride required - Split L2PricingStateTests into partial classes by feature area
|
FYI: Looks like folks in OffchainLabs changed the list of multi-gas resources |
Updated with changes from: OffchainLabs/go-ethereum#636 |
…com/NethermindEth/nethermind-arbitrum into daniil/arbos60-multigas-constraints
Summary
Implements ArbOS 60 multi-gas constraints pricing model with per-resource weights. Includes MultiGas tracking fixes and comparison mode test isolation improvements (merged from #723).
Key Features
Core Pricing Model
GasModelenum for routing:Legacy,SingleGasConstraints,MultiGasConstraintsMaxPricingExponentBipscap (85,000)UpdateGasPoolnow callsGrowBacklog(computeGas, AccumulatedMultiGas)for ArbOS 60+MultiGas Tracking (from #723)
Comparison Mode (from #723)
IResettableBlockTreeArchitecture
Gas Model Selection
flowchart TD Start([GetGasModelToUse]) --> V60{ArbOS >= 60?} V60 -->|Yes| MC{MultiGasConstraints<br/>Length > 0?} MC -->|Yes| MGC[MultiGasConstraints] MC -->|No| V50 V60 -->|No| V50{ArbOS >= 50?} V50 -->|Yes| SC{Constraints<br/>Length > 0?} SC -->|Yes| SGC[SingleGasConstraints] SC -->|No| LEG[Legacy] V50 -->|No| LEG style MGC fill:#22c55e,stroke:#16a34a,color:#000 style SGC fill:#3b82f6,stroke:#2563eb,color:#000 style LEG fill:#a1a1aa,stroke:#71717a,color:#000Storage Layout
classDiagram class MultiGasConstraint { <<12 slots>> +ulong Target +uint AdjustmentWindow +ulong Backlog +ulong MaxWeight +ulong WeightedResources_8 +GrowBacklog(MultiGas) +ShrinkBacklog(MultiGas) } class MultiGasFees { <<16 slots>> +UInt256 NextBlockFees_8 +UInt256 CurrentBlockFees_8 +CommitNextToCurrent() } class GasConstraint { <<3 slots - Legacy>> +ulong Target +ulong AdjustmentWindow +ulong Backlog } class ResourceKind { <<enum>> Unknown Computation HistoryGrowth StorageAccess StorageGrowth L1Calldata L2Calldata WasmComputation } MultiGasConstraint --> ResourceKind : weights per kind MultiGasFees --> ResourceKind : fees per kindPricing Update Flow (Per Block)
sequenceDiagram participant Block as Block Producer participant L2P as L2PricingState participant MGC as MultiGasConstraint participant MGF as MultiGasFees participant Storage as BaseFeeWei Block->>L2P: UpdatePricingModel(timePassed) Note over L2P: Model = MultiGasConstraints loop For each constraint L2P->>MGC: Get backlog, target L2P->>L2P: newBacklog = backlog - timePassed * target L2P->>MGC: SetBacklog(newBacklog) end L2P->>L2P: CalcMultiGasConstraintsExponents() Note over L2P: exponent = backlog * weight * BIPS / divisor loop For each ResourceKind L2P->>L2P: baseFee = minBaseFee * exp(exponent) L2P->>MGF: SetNextBlockFee(kind, baseFee) end L2P->>Storage: Set max of all baseFees Block->>L2P: CommitMultiGasFees() L2P->>MGF: CommitNextToCurrent() Note over MGF: nextBlockFees copied to currentBlockFeesTransaction Gas Tracking
flowchart LR subgraph TX [Transaction Execution] OP[EVM Opcode] -->|gas + resourceKind| ACC[Accumulate MultiGas] end subgraph GROW [Post-TX: UpdateGasPool → GrowBacklog] ACC -->|TxExecContext.AccumulatedMultiGas| UB[GrowBacklog] UB -->|for each constraint| WB[Weighted Update] WB -->|add weighted amount| MGC2[MultiGasConstraint] end subgraph SHRINK [Block End: ShrinkBacklog] TIME[timePassed * target] --> SB[ShrinkBacklog] SB -->|subtract capacity| MGC3[MultiGasConstraint] end style TX fill:#60a5fa,stroke:#3b82f6,color:#000 style GROW fill:#f87171,stroke:#ef4444,color:#000 style SHRINK fill:#4ade80,stroke:#22c55e,color:#000Weighted Backlog Calculation
flowchart TD subgraph Input [Input] MG[MultiGas<br/>per-resource usage] W[Constraint Weights<br/>per-resource multiplier] end subgraph Calculation [Calculation] MG -->|amount| MUL[Multiply] W -->|weight| MUL MUL -->|saturating| WA[weightedAmount] WA -->|saturating add/sub| BL[totalBacklog] end subgraph Output [Output] BL --> SET[constraint.SetBacklog] end style Input fill:#fbbf24,stroke:#f59e0b,color:#000 style Calculation fill:#c084fc,stroke:#a855f7,color:#000 style Output fill:#4ade80,stroke:#22c55e,color:#000System Test Validation
New logic has been validated by Nitro comparison system tests. The following 4 multi-gas specific tests were added to the passing list as part of this PR:
TestSetAndGetGasPricingConstraintsTestSetAndGetMultiGasPricingConstraintsTestMultiGasRefundForNormalTxTestMultiGasRefundForRetryableTxThese tests run in comparison mode against Nitro, validating state root parity at every block.
Total passing comparison tests: 46 (see
tools/comparison/passing-tests.txt).Unit & Integration Tests
MultiGasConstraintTests.cs— Storage operations, backlog updates (including Nitro-mirrored weighted accumulation tests)MultiGasFeesTests.cs— Fee commit workflowPricingModelMultiGasTests.cs— Pricing model equivalence testsL2PricingStateTests.cs— Constraint lifecycle, exponent calculationDependencies
IResettableBlockTree, MultiGas gas tracking in EVM