mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-11 06:23:47 +00:00
core/vm, params, tests: update gas price parameters (#35497)
https://github.com/ethereum/EIPs/pull/12083
This commit is contained in:
parent
b3e26093ec
commit
82061af43f
4 changed files with 46 additions and 27 deletions
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue