core: implement eip-7981: Increase Access List Cost

This commit is contained in:
MariusVanDerWijden 2026-04-17 17:38:48 +02:00
parent 3cd0340d34
commit 16ba4de5a0
6 changed files with 45 additions and 26 deletions

View file

@ -148,7 +148,7 @@ func Transaction(ctx *cli.Context) error {
} }
// For Prague txs, validate the floor data gas. // For Prague txs, validate the floor data gas.
if rules.IsPrague { if rules.IsPrague {
floorDataGas, err := core.FloorDataGas(rules, tx.Data()) floorDataGas, err := core.FloorDataGas(rules, tx.Data(), tx.AccessList())
if err != nil { if err != nil {
r.Error = err r.Error = err
results = append(results, r) results = append(results, r)

View file

@ -487,7 +487,7 @@ func TestEIP8037MaxRegularGasValidation(t *testing.T) {
} }
// Verify that floor data gas exceeds MaxTxGas // Verify that floor data gas exceeds MaxTxGas
floorGas, err := FloorDataGas(rules, largeData) floorGas, err := FloorDataGas(rules, largeData, nil)
if err != nil { if err != nil {
t.Fatalf("Failed to calculate floor data gas: %v", err) t.Fatalf("Failed to calculate floor data gas: %v", err)
} }

View file

@ -114,22 +114,38 @@ func IntrinsicGas(data []byte, accessList types.AccessList, authList []types.Set
} }
} }
if accessList != nil { if accessList != nil {
gas.RegularGas += uint64(len(accessList)) * params.TxAccessListAddressGas addresses := uint64(len(accessList))
gas.RegularGas += uint64(accessList.StorageKeys()) * params.TxAccessListStorageKeyGas storageKeys := uint64(accessList.StorageKeys())
} if (math.MaxUint64-gas.RegularGas)/params.TxAccessListAddressGas < addresses {
if authList != nil { return vm.GasCosts{}, ErrGasUintOverflow
}
gas.RegularGas += addresses * params.TxAccessListAddressGas
if (math.MaxUint64-gas.RegularGas)/params.TxAccessListStorageKeyGas < storageKeys {
return vm.GasCosts{}, ErrGasUintOverflow
}
gas.RegularGas += storageKeys * params.TxAccessListStorageKeyGas
// EIP-7981: access list data is charged in addition to the base charge.
if rules.IsAmsterdam { if rules.IsAmsterdam {
gas.RegularGas += uint64(len(authList)) * params.TxAuthTupleRegularGas const (
gas.StateGas += uint64(len(authList)) * (params.AuthorizationCreationSize + params.AccountCreationSize) * costPerStateByte addressCost = common.AddressLength * params.TxCostFloorPerToken7976 * params.TxTokenPerNonZeroByte
} else { storageKeyCost = common.HashLength * params.TxCostFloorPerToken7976 * params.TxTokenPerNonZeroByte
gas.RegularGas += uint64(len(authList)) * params.CallNewAccountGas )
if (math.MaxUint64-gas.RegularGas)/addressCost < addresses {
return vm.GasCosts{}, ErrGasUintOverflow
}
gas.RegularGas += addresses * addressCost
if (math.MaxUint64-gas.RegularGas)/storageKeyCost < storageKeys {
return vm.GasCosts{}, ErrGasUintOverflow
}
gas.RegularGas += storageKeys * storageKeyCost
} }
} }
return gas, nil return gas, nil
} }
// FloorDataGas computes the minimum gas required for a transaction based on its data tokens (EIP-7623). // FloorDataGas computes the minimum gas required for a transaction based on its data tokens (EIP-7623).
func FloorDataGas(rules params.Rules, data []byte) (uint64, error) { func FloorDataGas(rules params.Rules, data []byte, accessList types.AccessList) (uint64, error) {
var ( var (
tokens uint64 tokens uint64
tokenCost uint64 tokenCost uint64
@ -139,6 +155,9 @@ func FloorDataGas(rules params.Rules, data []byte) (uint64, error) {
// From 10/40 to 64/64 for zero/non-zero bytes. // From 10/40 to 64/64 for zero/non-zero bytes.
tokens = uint64(len(data)) * params.TxTokenPerNonZeroByte tokens = uint64(len(data)) * params.TxTokenPerNonZeroByte
tokenCost = params.TxCostFloorPerToken7976 tokenCost = params.TxCostFloorPerToken7976
// EIP-7981 adds additional tokens for every entry in the accesslist
tokens += uint64(len(accessList)) * common.AddressLength * params.TxTokenPerNonZeroByte
tokens += uint64(accessList.StorageKeys()) * common.HashLength * params.TxTokenPerNonZeroByte
} else { } else {
var ( var (
z = uint64(bytes.Count(data, []byte{0})) z = uint64(bytes.Count(data, []byte{0}))
@ -486,7 +505,7 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
// Compute the floor data cost (EIP-7623), needed for both Prague and Amsterdam validation. // Compute the floor data cost (EIP-7623), needed for both Prague and Amsterdam validation.
if rules.IsPrague { if rules.IsPrague {
floorDataGas, err = FloorDataGas(rules, msg.Data) floorDataGas, err = FloorDataGas(rules, msg.Data, msg.AccessList)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -144,7 +144,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
// Ensure the transaction can cover floor data gas. // Ensure the transaction can cover floor data gas.
if rules.IsPrague { if rules.IsPrague {
floorDataGas, err := core.FloorDataGas(rules, tx.Data()) floorDataGas, err := core.FloorDataGas(rules, tx.Data(), tx.AccessList())
if err != nil { if err != nil {
return err return err
} }

View file

@ -214,18 +214,18 @@ func (t *BlockTest) Network() string {
func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis { func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis {
return &core.Genesis{ return &core.Genesis{
Config: config, Config: config,
Nonce: t.json.Genesis.Nonce.Uint64(), Nonce: t.json.Genesis.Nonce.Uint64(),
Timestamp: t.json.Genesis.Timestamp, Timestamp: t.json.Genesis.Timestamp,
ParentHash: t.json.Genesis.ParentHash, ParentHash: t.json.Genesis.ParentHash,
ExtraData: t.json.Genesis.ExtraData, ExtraData: t.json.Genesis.ExtraData,
GasLimit: t.json.Genesis.GasLimit, GasLimit: t.json.Genesis.GasLimit,
GasUsed: t.json.Genesis.GasUsed, GasUsed: t.json.Genesis.GasUsed,
Difficulty: t.json.Genesis.Difficulty, Difficulty: t.json.Genesis.Difficulty,
Mixhash: t.json.Genesis.MixHash, Mixhash: t.json.Genesis.MixHash,
Coinbase: t.json.Genesis.Coinbase, Coinbase: t.json.Genesis.Coinbase,
Alloc: t.json.Pre, Alloc: t.json.Pre,
BaseFee: t.json.Genesis.BaseFeePerGas, BaseFee: t.json.Genesis.BaseFeePerGas,
BlobGasUsed: t.json.Genesis.BlobGasUsed, BlobGasUsed: t.json.Genesis.BlobGasUsed,
ExcessBlobGas: t.json.Genesis.ExcessBlobGas, ExcessBlobGas: t.json.Genesis.ExcessBlobGas,
SlotNumber: t.json.Genesis.SlotNumber, SlotNumber: t.json.Genesis.SlotNumber,

View file

@ -93,7 +93,7 @@ func (tt *TransactionTest) Run() error {
if rules.IsPrague { if rules.IsPrague {
var floorDataGas uint64 var floorDataGas uint64
floorDataGas, err = core.FloorDataGas(rules, tx.Data()) floorDataGas, err = core.FloorDataGas(rules, tx.Data(), tx.AccessList())
if err != nil { if err != nil {
return return
} }