mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-10 00:41:35 +00:00
core: implement eip-7981: Increase Access List Cost
This commit is contained in:
parent
3cd0340d34
commit
16ba4de5a0
6 changed files with 45 additions and 26 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue