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.
if rules.IsPrague {
floorDataGas, err := core.FloorDataGas(rules, tx.Data())
floorDataGas, err := core.FloorDataGas(rules, tx.Data(), tx.AccessList())
if err != nil {
r.Error = err
results = append(results, r)

View file

@ -487,7 +487,7 @@ func TestEIP8037MaxRegularGasValidation(t *testing.T) {
}
// Verify that floor data gas exceeds MaxTxGas
floorGas, err := FloorDataGas(rules, largeData)
floorGas, err := FloorDataGas(rules, largeData, nil)
if err != nil {
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 {
gas.RegularGas += uint64(len(accessList)) * params.TxAccessListAddressGas
gas.RegularGas += uint64(accessList.StorageKeys()) * params.TxAccessListStorageKeyGas
}
if authList != nil {
addresses := uint64(len(accessList))
storageKeys := uint64(accessList.StorageKeys())
if (math.MaxUint64-gas.RegularGas)/params.TxAccessListAddressGas < addresses {
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 {
gas.RegularGas += uint64(len(authList)) * params.TxAuthTupleRegularGas
gas.StateGas += uint64(len(authList)) * (params.AuthorizationCreationSize + params.AccountCreationSize) * costPerStateByte
} else {
gas.RegularGas += uint64(len(authList)) * params.CallNewAccountGas
const (
addressCost = common.AddressLength * params.TxCostFloorPerToken7976 * params.TxTokenPerNonZeroByte
storageKeyCost = common.HashLength * params.TxCostFloorPerToken7976 * params.TxTokenPerNonZeroByte
)
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
}
// 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 (
tokens 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.
tokens = uint64(len(data)) * params.TxTokenPerNonZeroByte
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 {
var (
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.
if rules.IsPrague {
floorDataGas, err = FloorDataGas(rules, msg.Data)
floorDataGas, err = FloorDataGas(rules, msg.Data, msg.AccessList)
if err != nil {
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.
if rules.IsPrague {
floorDataGas, err := core.FloorDataGas(rules, tx.Data())
floorDataGas, err := core.FloorDataGas(rules, tx.Data(), tx.AccessList())
if err != nil {
return err
}

View file

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

View file

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