Skip to content

Commit

Permalink
core: EIP-3860: extra charge for creation transaction
Browse files Browse the repository at this point in the history
  • Loading branch information
gumb0 committed Nov 15, 2021
1 parent d719143 commit 7c6961f
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 11 deletions.
11 changes: 9 additions & 2 deletions cmd/evm/internal/t8ntool/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,19 @@ func Transaction(ctx *cli.Context) error {
txStr = ctx.String(InputTxsFlag.Name)
inputData = &input{}
chainConfig *params.ChainConfig
eip3860 = false
)
// Construct the chainconfig
if cConf, _, err := tests.GetChainConfig(ctx.String(ForknameFlag.Name)); err != nil {
if cConf, extraEips, err := tests.GetChainConfig(ctx.String(ForknameFlag.Name)); err != nil {
return NewError(ErrorVMConfig, fmt.Errorf("failed constructing chain configuration: %v", err))
} else {
chainConfig = cConf
for _, eip := range extraEips {
if eip == 3860 {
eip3860 = true
break
}
}
}
// Set the chain id
chainConfig.ChainID = big.NewInt(ctx.Int64(ChainIDFlag.Name))
Expand Down Expand Up @@ -140,7 +147,7 @@ func Transaction(ctx *cli.Context) error {
}
// Check intrinsic gas
if gas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil,
chainConfig.IsHomestead(new(big.Int)), chainConfig.IsIstanbul(new(big.Int))); err != nil {
chainConfig.IsHomestead(new(big.Int)), chainConfig.IsIstanbul(new(big.Int)), eip3860); err != nil {
r.Error = err
results = append(results, r)
continue
Expand Down
2 changes: 1 addition & 1 deletion core/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func genValueTx(nbytes int) func(int, *BlockGen) {
return func(i int, gen *BlockGen) {
toaddr := common.Address{}
data := make([]byte, nbytes)
gas, _ := IntrinsicGas(data, nil, false, false, false)
gas, _ := IntrinsicGas(data, nil, false, false, false, false)
signer := types.MakeSigner(gen.config, big.NewInt(int64(i)))
gasPrice := big.NewInt(0)
if gen.header.BaseFee != nil {
Expand Down
27 changes: 23 additions & 4 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,17 @@ func (result *ExecutionResult) Revert() []byte {
}

// IntrinsicGas computes the 'intrinsic gas' for a message with the given data.
func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation bool, isHomestead, isEIP2028 bool) (uint64, error) {
func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation bool, isHomestead, isEIP2028 bool, isEIP3860 bool) (uint64, error) {
// Set the starting gas for the raw transaction
var gas uint64
if isContractCreation && isHomestead {
gas = params.TxGasContractCreation
} else {
gas = params.TxGas
}
dataLen := uint64(len(data))
// Bump the required gas by the amount of transactional data
if len(data) > 0 {
if dataLen > 0 {
// Zero and non-zero bytes are priced differently
var nz uint64
for _, byt := range data {
Expand All @@ -142,11 +143,19 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation b
}
gas += nz * nonZeroGas

z := uint64(len(data)) - nz
z := dataLen - nz
if (math.MaxUint64-gas)/params.TxDataZeroGas < z {
return 0, ErrGasUintOverflow
}
gas += z * params.TxDataZeroGas

if isContractCreation && isEIP3860 {
lenWords := toWordSize(dataLen)
if (math.MaxUint64-gas)/params.InitCodeWordGas < lenWords {
return 0, ErrGasUintOverflow
}
gas += lenWords * params.InitCodeWordGas
}
}
if accessList != nil {
gas += uint64(len(accessList)) * params.TxAccessListAddressGas
Expand All @@ -155,6 +164,15 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation b
return gas, nil
}

// toWordSize returns the ceiled word size required for init code payment calculation.
func toWordSize(size uint64) uint64 {
if size > math.MaxUint64-31 {
return math.MaxUint64/32 + 1
}

return (size + 31) / 32
}

// NewStateTransition initialises and returns a new state transition object.
func NewStateTransition(evm *vm.EVM, msg Message, gp *GasPool) *StateTransition {
return &StateTransition{
Expand Down Expand Up @@ -292,10 +310,11 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) {
homestead := st.evm.ChainConfig().IsHomestead(st.evm.Context.BlockNumber)
istanbul := st.evm.ChainConfig().IsIstanbul(st.evm.Context.BlockNumber)
london := st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber)
eip3860 := st.evm.Config.HasEip3860()
contractCreation := msg.To() == nil

// Check clauses 4-5, subtract intrinsic gas if everything is correct
gas, err := IntrinsicGas(st.data, st.msg.AccessList(), contractCreation, homestead, istanbul)
gas, err := IntrinsicGas(st.data, st.msg.AccessList(), contractCreation, homestead, istanbul, eip3860)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion core/tx_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
return ErrInsufficientFunds
}
// Ensure the transaction has more gas than the basic tx fee.
intrGas, err := IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, true, pool.istanbul)
intrGas, err := IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, true, pool.istanbul, true)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion eth/tracers/js/tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,8 @@ func (jst *jsTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Ad
// Compute intrinsic gas
isHomestead := env.ChainConfig().IsHomestead(env.Context.BlockNumber)
isIstanbul := env.ChainConfig().IsIstanbul(env.Context.BlockNumber)
intrinsicGas, err := core.IntrinsicGas(input, nil, jst.ctx["type"] == "CREATE", isHomestead, isIstanbul)
hasEip3860 := env.Config.HasEip3860()
intrinsicGas, err := core.IntrinsicGas(input, nil, jst.ctx["type"] == "CREATE", isHomestead, isIstanbul, hasEip3860)
if err != nil {
return
}
Expand Down
2 changes: 1 addition & 1 deletion light/txpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error
}

// Should supply enough intrinsic gas
gas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, true, pool.istanbul)
gas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, true, pool.istanbul, true)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion tests/transaction_test_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (tt *TransactionTest) Run(config *params.ChainConfig) error {
return nil, nil, err
}
// Intrinsic gas
requiredGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, isHomestead, isIstanbul)
requiredGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, isHomestead, isIstanbul, false)
if err != nil {
return nil, nil, err
}
Expand Down

0 comments on commit 7c6961f

Please sign in to comment.