Skip to content

Commit 67825d8

Browse files
committed
core, light, params: implement eip2028 (ethereum#19931)
1 parent b708614 commit 67825d8

File tree

5 files changed

+48
-30
lines changed

5 files changed

+48
-30
lines changed

core/bench_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func genValueTx(nbytes int) func(int, *BlockGen) {
8585
return func(i int, gen *BlockGen) {
8686
toaddr := common.Address{}
8787
data := make([]byte, nbytes)
88-
gas, _ := IntrinsicGas(data, false, false)
88+
gas, _ := IntrinsicGas(data, false, false, false)
8989
tx, _ := types.SignTx(types.NewTransaction(gen.TxNonce(benchRootAddr), toaddr, big.NewInt(1), gas, nil, data), types.HomesteadSigner{}, benchRootKey)
9090
gen.AddTx(tx)
9191
}

core/state_transition.go

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@ The state transitioning model does all all the necessary work to work out a vali
4242
3) Create a new state object if the recipient is \0*32
4343
4) Value transfer
4444
== If contract creation ==
45-
4a) Attempt to run transaction data
46-
4b) If valid, use result as code for the new state object
45+
46+
4a) Attempt to run transaction data
47+
4b) If valid, use result as code for the new state object
48+
4749
== end ==
4850
5) Run Script section
4951
6) Derive new state root
@@ -77,10 +79,10 @@ type Message interface {
7779
}
7880

7981
// IntrinsicGas computes the 'intrinsic gas' for a message with the given data.
80-
func IntrinsicGas(data []byte, contractCreation, homestead bool) (uint64, error) {
82+
func IntrinsicGas(data []byte, contractCreation, isEIP155 bool, isEIP2028 bool) (uint64, error) {
8183
// Set the starting gas for the raw transaction
8284
var gas uint64
83-
if contractCreation && homestead {
85+
if contractCreation && isEIP155 {
8486
gas = params.TxGasContractCreation
8587
} else {
8688
gas = params.TxGas
@@ -95,10 +97,14 @@ func IntrinsicGas(data []byte, contractCreation, homestead bool) (uint64, error)
9597
}
9698
}
9799
// Make sure we don't exceed uint64 for all data combinations
98-
if (math.MaxUint64-gas)/params.TxDataNonZeroGas < nz {
100+
nonZeroGas := params.TxDataNonZeroGasFrontier
101+
if isEIP2028 {
102+
nonZeroGas = params.TxDataNonZeroGasEIP2028
103+
}
104+
if (math.MaxUint64-gas)/nonZeroGas < nz {
99105
return 0, vm.ErrOutOfGas
100106
}
101-
gas += nz * params.TxDataNonZeroGas
107+
gas += nz * nonZeroGas
102108

103109
z := uint64(len(data)) - nz
104110
if (math.MaxUint64-gas)/params.TxDataZeroGas < z {
@@ -223,10 +229,11 @@ func (st *StateTransition) TransitionDb(owner common.Address) (ret []byte, usedG
223229
sender := st.from() // err checked in preCheck
224230

225231
homestead := st.evm.ChainConfig().IsHomestead(st.evm.BlockNumber)
232+
istanbul := st.evm.ChainConfig().IsIstanbul(st.evm.BlockNumber)
226233
contractCreation := msg.To() == nil
227234

228235
// Pay intrinsic gas
229-
gas, err := IntrinsicGas(st.data, contractCreation, homestead)
236+
gas, err := IntrinsicGas(st.data, contractCreation, homestead, istanbul)
230237
if err != nil {
231238
return nil, 0, false, err, nil
232239
}

core/tx_pool.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ type TxPool struct {
237237
signer types.Signer
238238
mu sync.RWMutex
239239

240+
istanbul bool // Fork indicator whether we are in the istanbul stage.
241+
240242
currentState *state.StateDB // Current state in the blockchain head
241243
pendingNonces *txNoncer // Pending state tracking virtual nonces
242244
currentMaxGas uint64 // Current gas limit for transaction caps
@@ -606,7 +608,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
606608

607609
if tx.To() == nil || (tx.To() != nil && !tx.IsSpecialTransaction()) {
608610
// Ensure the transaction has more gas than the basic tx fee.
609-
intrGas, err := IntrinsicGas(tx.Data(), tx.To() == nil, true)
611+
intrGas, err := IntrinsicGas(tx.Data(), tx.To() == nil, true, pool.istanbul)
610612
if err != nil {
611613
return err
612614
}
@@ -1258,6 +1260,10 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) {
12581260
log.Debug("Reinjecting stale transactions", "count", len(reinject))
12591261
senderCacher.recover(pool.signer, reinject)
12601262
pool.addTxsLocked(reinject, false)
1263+
1264+
// Update all fork indicator by next pending block number.
1265+
next := new(big.Int).Add(newHead.Number, big.NewInt(1))
1266+
pool.istanbul = pool.chainconfig.IsIstanbul(next)
12611267
}
12621268

12631269
// promoteExecutables moves transactions that have become processable from the

light/txpool.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package light
1919
import (
2020
"context"
2121
"fmt"
22+
"math/big"
2223
"sync"
2324
"time"
2425

@@ -66,7 +67,7 @@ type TxPool struct {
6667
mined map[common.Hash][]*types.Transaction // mined transactions by block hash
6768
clearIdx uint64 // earliest block nr that can contain mined tx info
6869

69-
homestead bool
70+
istanbul bool // Fork indicator whether we are in the istanbul stage.
7071
}
7172

7273
// TxRelayBackend provides an interface to the mechanism that forwards transacions
@@ -310,7 +311,10 @@ func (pool *TxPool) setNewHead(head *types.Header) {
310311
txc, _ := pool.reorgOnNewHead(ctx, head)
311312
m, r := txc.getLists()
312313
pool.relay.NewHead(pool.head, m, r)
313-
pool.homestead = pool.config.IsHomestead(head.Number)
314+
315+
// Update fork indicator by next pending block number
316+
next := new(big.Int).Add(head.Number, big.NewInt(1))
317+
pool.istanbul = pool.config.IsIstanbul(next)
314318
pool.signer = types.MakeSigner(pool.config, head.Number)
315319
}
316320

@@ -403,7 +407,7 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error
403407
}
404408

405409
// Should supply enough intrinsic gas
406-
gas, err := core.IntrinsicGas(tx.Data(), tx.To() == nil, pool.homestead)
410+
gas, err := core.IntrinsicGas(tx.Data(), tx.To() == nil, true, pool.istanbul)
407411
if err != nil {
408412
return err
409413
}

params/protocol_params.go

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ var (
2323
)
2424

2525
const (
26-
GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations.
27-
MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be.
26+
GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations.
27+
MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be.
2828
MaxGasLimit uint64 = 0x7fffffffffffffff // Maximum the gas limit (2^63-1).
29-
GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block.
29+
GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block.
3030
XDCGenesisGasLimit uint64 = 84000000
3131

3232
MaximumExtraDataSize uint64 = 32 // Maximum size extra data may be after Genesis.
@@ -50,17 +50,23 @@ const (
5050
JumpdestGas uint64 = 1 // Refunded gas, once per SSTORE operation if the zeroness changes to zero.
5151
EpochDuration uint64 = 30000 // Duration between proof-of-work epochs.
5252
CallGas uint64 = 40 // Once per CALL operation & message call transaction.
53-
CreateDataGas uint64 = 200 //
54-
CallCreateDepth uint64 = 1024 // Maximum depth of call/create stack.
55-
ExpGas uint64 = 10 // Once per EXP instruction
56-
LogGas uint64 = 375 // Per LOG* operation.
57-
CopyGas uint64 = 3 //
58-
StackLimit uint64 = 1024 // Maximum size of VM stack allowed.
59-
TierStepGas uint64 = 0 // Once per operation, for a selection of them.
60-
LogTopicGas uint64 = 375 // Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas.
61-
CreateGas uint64 = 32000 // Once per CREATE operation & contract-creation transaction.
53+
54+
CreateDataGas uint64 = 200 //
55+
CallCreateDepth uint64 = 1024 // Maximum depth of call/create stack.
56+
ExpGas uint64 = 10 // Once per EXP instruction
57+
LogGas uint64 = 375 // Per LOG* operation.
58+
CopyGas uint64 = 3 //
59+
StackLimit uint64 = 1024 // Maximum size of VM stack allowed.
60+
TierStepGas uint64 = 0 // Once per operation, for a selection of them.
61+
LogTopicGas uint64 = 375 // Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas.
62+
CreateGas uint64 = 32000 // Once per CREATE operation & contract-creation transaction.
63+
Create2Gas uint64 = 32000 // Once per CREATE2 operation
64+
SelfdestructRefundGas uint64 = 24000 // Refunded following a selfdestruct operation.
65+
MemoryGas uint64 = 3 // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL.
66+
TxDataNonZeroGasFrontier uint64 = 68 // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions.
67+
TxDataNonZeroGasEIP2028 uint64 = 16 // Per byte of non zero data attached to a transaction after EIP 2028 (part in Istanbul)
68+
6269
SuicideRefundGas uint64 = 24000 // Refunded following a suicide operation.
63-
MemoryGas uint64 = 3 // Times the address of the (highest referenced byte in memory + 1). NOTE: referencing happens on read, write and in instructions such as RETURN and CALL.
6470
TxDataNonZeroGas uint64 = 68 // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions.
6571

6672
MaxCodeSize = 24576 // Maximum bytecode to permit for a contract
@@ -104,11 +110,6 @@ const (
104110
SstoreResetGasEIP2200 uint64 = 5000 // Once per SSTORE operation from clean non-zero to something else
105111
SstoreClearsScheduleRefundEIP2200 uint64 = 15000 // Once per SSTORE operation for clearing an originally existing storage slot
106112

107-
Create2Gas uint64 = 32000 // Once per CREATE2 operation
108-
SelfdestructRefundGas uint64 = 24000 // Refunded following a selfdestruct operation.
109-
TxDataNonZeroGasFrontier uint64 = 68 // Per byte of data attached to a transaction that is not equal to zero. NOTE: Not payable on data of calls between transactions.
110-
TxDataNonZeroGasEIP2028 uint64 = 16 // Per byte of non zero data attached to a transaction after EIP 2028 (part in Istanbul)
111-
112113
// These have been changed during the course of the chain
113114
CallGasFrontier uint64 = 40 // Once per CALL operation & message call transaction.
114115
CallGasEIP150 uint64 = 700 // Static portion of gas for CALL-derivates after EIP 150 (Tangerine)

0 commit comments

Comments
 (0)