core/vm, params, tests: update gas price parameters (#35497)

https://github.com/ethereum/EIPs/pull/12083
This commit is contained in:
rjl493456442 2026-08-10 14:46:13 +08:00 committed by GitHub
parent b3e26093ec
commit 82061af43f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 46 additions and 27 deletions

View file

@ -190,24 +190,21 @@ func TestSStoreChargedAtOpcodeEnd(t *testing.T) {
}
// The SSTORE reentrancy sentry checks gas_left only; the reservoir is excluded.
// Uses a noop write (1->1->1): the two PUSH1s cost 6, leaving gas_left at the
// sentry (2300) for a 2306 budget. Under EIP-8038 the cold-slot access that
// follows a cleared sentry costs COLD_STORAGE_ACCESS (3000).
// Uses a noop write (1->1->1): the two PUSH1s cost 6, so a budget of
// 6 + SstoreSentryGasEIP2200 leaves gas_left exactly at the sentry.
func TestSStoreStipendExcludesReservoir(t *testing.T) {
// execution at the sentry, huge reservoir: must still fail, proving the
const pushes = 6
// Execution gas at the sentry, huge reservoir: must still fail, proving the
// reservoir does not count toward the sentry.
if _, _, err := run8037(t, sstore(0, 1), NewGasBudget(2306, math.MaxUint64/2), new(uint256.Int), setSlot(0, 1)); err == nil {
atSentry := pushes + params.SstoreSentryGasEIP2200
if _, _, err := run8037(t, sstore(0, 1), NewGasBudget(atSentry, math.MaxUint64/2), new(uint256.Int), setSlot(0, 1)); err == nil {
t.Fatal("expected sentry failure with execution gas at the limit")
}
// Enough execution gas to clear the sentry and pay the cold-slot access
// (6 for the PUSH1s + COLD_STORAGE_ACCESS) succeeds with a huge reservoir.
execution := 6 + params.ColdStorageAccessAmsterdam
if _, _, err := run8037(t, sstore(0, 1), NewGasBudget(execution, math.MaxUint64/2), new(uint256.Int), setSlot(0, 1)); err != nil {
t.Fatalf("unexpected failure above sentry: %v", err)
}
// One gas short of the cold-slot access still fails (now on OOG, not sentry).
if _, _, err := run8037(t, sstore(0, 1), NewGasBudget(execution-1, math.MaxUint64/2), new(uint256.Int), setSlot(0, 1)); err == nil {
t.Fatal("expected OOG when execution gas cannot cover cold-slot access")
// One gas above the sentry succeeds: the cold-slot access is cheaper than the
// sentry, so clearing the sentry is sufficient.
if _, _, err := run8037(t, sstore(0, 1), NewGasBudget(atSentry+1, math.MaxUint64/2), new(uint256.Int), setSlot(0, 1)); err != nil {
t.Fatalf("unexpected failure one gas above the sentry: %v", err)
}
}

View file

@ -378,16 +378,37 @@ func TestEIP8038SelfdestructAccountWrite(t *testing.T) {
// TestEIP8038SStoreAccessGuard covers the affordability check that bails out
// before the slot is read once the gas left cannot cover the slot's access cost.
// The two PUSH1s cost 6, so a 2506 budget leaves 2500 at the SSTORE: above the
// reentrancy sentry (2300) yet below COLD_STORAGE_ACCESS (3000). The guard must
// fire, distinguishable from the sentry/charge OOG by its "slot access" message.
//
// Under the current schedule that guard is a backstop rather than a reachable
// path: both access costs, COLD_STORAGE_ACCESS (2,100) and WARM_ACCESS (100),
// are below the reentrancy sentry (2,300), and the sentry is checked first, so
// any gas that reaches the guard already covers the access. The guard is kept
// as defensive code because the two are independent parameters.
//
// This test pins that relationship. If a repricing lifts either access cost
// above the sentry the guard becomes reachable again, and this test fails to
// say so rather than letting SSTORE's failure mode change unnoticed.
func TestEIP8038SStoreAccessGuard(t *testing.T) {
budget := NewGasBudget(6+params.SstoreSentryGasEIP2200+200, 0)
for _, tc := range []struct {
name string
cost uint64
}{
{"cold", params.ColdStorageAccessAmsterdam},
{"warm", params.WarmStorageAccessAmsterdam},
} {
if tc.cost > params.SstoreSentryGasEIP2200 {
t.Fatalf("%s slot access (%d) exceeds the reentrancy sentry (%d): the guard "+
"is reachable again and needs a test exercising it", tc.name, tc.cost, params.SstoreSentryGasEIP2200)
}
}
// Below the sentry the sentry itself must be what rejects the call, not the
// slot-access guard behind it.
budget := NewGasBudget(6+params.SstoreSentryGasEIP2200, 0)
_, _, err := run8038(t, sstore(0, 1), budget, new(uint256.Int), nil)
if err == nil {
t.Fatal("expected failure: gas left cannot cover cold-slot access")
t.Fatal("expected failure: gas left is at the reentrancy sentry")
}
if !strings.Contains(err.Error(), "not enough gas for slot access") {
t.Fatalf("got %q, want the slot-access guard error", err)
if !strings.Contains(err.Error(), "not enough gas for reentrancy sentry") {
t.Fatalf("got %q, want the reentrancy sentry error", err)
}
}

View file

@ -113,15 +113,15 @@ const (
// EIP-8038: state-access gas cost update (Amsterdam).
ColdAccountAccessAmsterdam uint64 = 3000 // COLD_ACCOUNT_ACCESS: cold touch of an account
WarmAccountAccessAmsterdam uint64 = 100 // WARM_ACCESS: warm touch of an account
AccountWriteAmsterdam uint64 = 8000 // ACCOUNT_WRITE: surcharge for first-time write to an account
CallValueTransferAmsterdam uint64 = 10300 // CALL_VALUE = ACCOUNT_WRITE + CallStipend (2300)
ColdStorageAccessAmsterdam uint64 = 3000 // COLD_STORAGE_ACCESS: cold touch of a storage slot
AccountWriteAmsterdam uint64 = 9000 // ACCOUNT_WRITE: surcharge for first-time write to an account
CallValueTransferAmsterdam uint64 = 11300 // CALL_VALUE = ACCOUNT_WRITE + CallStipend (2300)
ColdStorageAccessAmsterdam uint64 = 2100 // COLD_STORAGE_ACCESS: cold touch of a storage slot
WarmStorageAccessAmsterdam uint64 = 100 // WARM_STORAGE_ACCESS: warm touch of a storage slot
StorageWriteAmsterdam uint64 = 10000 // STORAGE_WRITE: surcharge for first-time write to a storage slot
StorageClearRefundAmsterdam uint64 = 12480 // STORAGE_CLEAR_REFUND: refund for clearing a storage slot
CreateAccessAmsterdam uint64 = 11000 // CREATE_ACCESS = ACCOUNT_WRITE + COLD_STORAGE_ACCESS
StorageClearRefundAmsterdam uint64 = 11616 // STORAGE_CLEAR_REFUND: refund for clearing a storage slot
CreateAccessAmsterdam uint64 = 12000 // CREATE_ACCESS = ACCOUNT_WRITE + COLD_ACCOUNT_ACCESS
TxAccessListAddressGasAmsterdam uint64 = 2900 // ACCESS_LIST_ADDRESS_COST
TxAccessListStorageKeyGasAmsterdam uint64 = 2900 // ACCESS_LIST_STORAGE_KEY_COST
TxAccessListStorageKeyGasAmsterdam uint64 = 2000 // ACCESS_LIST_STORAGE_KEY_COST
// These have been changed during the course of the chain
CallGasFrontier uint64 = 40 // Once per CALL operation & message call transaction.

View file

@ -227,6 +227,7 @@ func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis {
BaseFee: t.json.Genesis.BaseFeePerGas,
BlobGasUsed: t.json.Genesis.BlobGasUsed,
ExcessBlobGas: t.json.Genesis.ExcessBlobGas,
SlotNumber: t.json.Genesis.SlotNumber,
}
}