mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-22 15:59:26 +00:00
Merge remote-tracking branch 'origin/master' into eof-opcodes
This commit is contained in:
commit
02a16f1802
23 changed files with 423 additions and 84 deletions
3
cmd/evm/testdata/evmrun/3.out.1.txt
vendored
3
cmd/evm/testdata/evmrun/3.out.1.txt
vendored
|
|
@ -1,12 +1,13 @@
|
||||||
{
|
{
|
||||||
"root": "b444481d1367188172f8c6091e948aaa68bae763fd26d6b9e994306a66bf69f9",
|
"root": "b444481d1367188172f8c6091e948aaa68bae763fd26d6b9e994306a66bf69f9",
|
||||||
"accounts": {
|
"accounts": {
|
||||||
"pre(0x30d7a0694cb29af31b982480e11d7ebb003a3fca4026939149071f014689b142)": {
|
"0x0000000000000000000000007265636569766572": {
|
||||||
"balance": "0",
|
"balance": "0",
|
||||||
"nonce": 0,
|
"nonce": 0,
|
||||||
"root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
"root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||||
"codeHash": "0x3e48ef54b89079a075f3b8fc253c657a86b110a7aed3568c1517b10edf2c3eb6",
|
"codeHash": "0x3e48ef54b89079a075f3b8fc253c657a86b110a7aed3568c1517b10edf2c3eb6",
|
||||||
"code": "0x6040",
|
"code": "0x6040",
|
||||||
|
"address": "0x0000000000000000000000007265636569766572",
|
||||||
"key": "0x30d7a0694cb29af31b982480e11d7ebb003a3fca4026939149071f014689b142"
|
"key": "0x30d7a0694cb29af31b982480e11d7ebb003a3fca4026939149071f014689b142"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
3
cmd/evm/testdata/evmrun/4.out.1.txt
vendored
3
cmd/evm/testdata/evmrun/4.out.1.txt
vendored
|
|
@ -1,12 +1,13 @@
|
||||||
{
|
{
|
||||||
"root": "b444481d1367188172f8c6091e948aaa68bae763fd26d6b9e994306a66bf69f9",
|
"root": "b444481d1367188172f8c6091e948aaa68bae763fd26d6b9e994306a66bf69f9",
|
||||||
"accounts": {
|
"accounts": {
|
||||||
"pre(0x30d7a0694cb29af31b982480e11d7ebb003a3fca4026939149071f014689b142)": {
|
"0x0000000000000000000000007265636569766572": {
|
||||||
"balance": "0",
|
"balance": "0",
|
||||||
"nonce": 0,
|
"nonce": 0,
|
||||||
"root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
"root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
|
||||||
"codeHash": "0x3e48ef54b89079a075f3b8fc253c657a86b110a7aed3568c1517b10edf2c3eb6",
|
"codeHash": "0x3e48ef54b89079a075f3b8fc253c657a86b110a7aed3568c1517b10edf2c3eb6",
|
||||||
"code": "0x6040",
|
"code": "0x6040",
|
||||||
|
"address": "0x0000000000000000000000007265636569766572",
|
||||||
"key": "0x30d7a0694cb29af31b982480e11d7ebb003a3fca4026939149071f014689b142"
|
"key": "0x30d7a0694cb29af31b982480e11d7ebb003a3fca4026939149071f014689b142"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,7 @@ var (
|
||||||
// is only used for necessary consensus checks. The legacy consensus engine can be any
|
// is only used for necessary consensus checks. The legacy consensus engine can be any
|
||||||
// engine implements the consensus interface (except the beacon itself).
|
// engine implements the consensus interface (except the beacon itself).
|
||||||
type Beacon struct {
|
type Beacon struct {
|
||||||
ethone consensus.Engine // Original consensus engine used in eth1, e.g. ethash or clique
|
ethone consensus.Engine // Original consensus engine used in eth1, e.g. ethash or clique
|
||||||
ttdblock *uint64 // Merge block-number for testchain generation without TTDs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a consensus engine with the given embedded eth1 engine.
|
// New creates a consensus engine with the given embedded eth1 engine.
|
||||||
|
|
@ -73,16 +72,12 @@ func New(ethone consensus.Engine) *Beacon {
|
||||||
return &Beacon{ethone: ethone}
|
return &Beacon{ethone: ethone}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestingTTDBlock is a replacement mechanism for TTD-based pre-/post-merge
|
// isPostMerge reports whether the given block number is assumed to be post-merge.
|
||||||
// splitting. With chain history deletion, TD calculations become impossible.
|
// Here we check the MergeNetsplitBlock to allow configuring networks with a PoW or
|
||||||
// This is fine for progressing the live chain, but to be able to generate test
|
// PoA chain for unit testing purposes.
|
||||||
// chains, we do need a split point. This method supports setting an explicit
|
func isPostMerge(config *params.ChainConfig, block uint64) bool {
|
||||||
// block number to use as the splitter *for testing*, instead of having to keep
|
mergedAtGenesis := config.TerminalTotalDifficulty != nil && config.TerminalTotalDifficulty.Sign() == 0
|
||||||
// the notion of TDs in the client just for testing.
|
return mergedAtGenesis || config.MergeNetsplitBlock != nil && block >= config.MergeNetsplitBlock.Uint64()
|
||||||
//
|
|
||||||
// The block with supplied number is regarded as the last pre-merge block.
|
|
||||||
func (beacon *Beacon) TestingTTDBlock(number uint64) {
|
|
||||||
beacon.ttdblock = &number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Author implements consensus.Engine, returning the verified author of the block.
|
// Author implements consensus.Engine, returning the verified author of the block.
|
||||||
|
|
@ -332,15 +327,7 @@ func (beacon *Beacon) verifyHeaders(chain consensus.ChainHeaderReader, headers [
|
||||||
// Prepare implements consensus.Engine, initializing the difficulty field of a
|
// Prepare implements consensus.Engine, initializing the difficulty field of a
|
||||||
// header to conform to the beacon protocol. The changes are done inline.
|
// header to conform to the beacon protocol. The changes are done inline.
|
||||||
func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error {
|
func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error {
|
||||||
// The beacon engine requires access to total difficulties to be able to
|
if !isPostMerge(chain.Config(), header.Number.Uint64()) {
|
||||||
// seal pre-merge and post-merge blocks. With the transition to removing
|
|
||||||
// old blocks, TDs become unaccessible, thus making TTD based pre-/post-
|
|
||||||
// merge decisions impossible.
|
|
||||||
//
|
|
||||||
// We do not need to seal non-merge blocks anymore live, but we do need
|
|
||||||
// to be able to generate test chains, thus we're reverting to a testing-
|
|
||||||
// settable field to direct that.
|
|
||||||
if beacon.ttdblock != nil && *beacon.ttdblock >= header.Number.Uint64() {
|
|
||||||
return beacon.ethone.Prepare(chain, header)
|
return beacon.ethone.Prepare(chain, header)
|
||||||
}
|
}
|
||||||
header.Difficulty = beaconDifficulty
|
header.Difficulty = beaconDifficulty
|
||||||
|
|
@ -450,15 +437,7 @@ func (beacon *Beacon) SealHash(header *types.Header) common.Hash {
|
||||||
// the difficulty that a new block should have when created at time
|
// the difficulty that a new block should have when created at time
|
||||||
// given the parent block's time and difficulty.
|
// given the parent block's time and difficulty.
|
||||||
func (beacon *Beacon) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int {
|
func (beacon *Beacon) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int {
|
||||||
// The beacon engine requires access to total difficulties to be able to
|
if !isPostMerge(chain.Config(), parent.Number.Uint64()+1) {
|
||||||
// seal pre-merge and post-merge blocks. With the transition to removing
|
|
||||||
// old blocks, TDs become unaccessible, thus making TTD based pre-/post-
|
|
||||||
// merge decisions impossible.
|
|
||||||
//
|
|
||||||
// We do not need to seal non-merge blocks anymore live, but we do need
|
|
||||||
// to be able to generate test chains, thus we're reverting to a testing-
|
|
||||||
// settable field to direct that.
|
|
||||||
if beacon.ttdblock != nil && *beacon.ttdblock > parent.Number.Uint64() {
|
|
||||||
return beacon.ethone.CalcDifficulty(chain, time, parent)
|
return beacon.ethone.CalcDifficulty(chain, time, parent)
|
||||||
}
|
}
|
||||||
return beaconDifficulty
|
return beaconDifficulty
|
||||||
|
|
|
||||||
|
|
@ -91,8 +91,10 @@ func TestCreation(t *testing.T) {
|
||||||
{1735372, 1677557087, ID{Hash: checksumToBytes(0xb96cbd13), Next: 1677557088}}, // Last MergeNetsplit block
|
{1735372, 1677557087, ID{Hash: checksumToBytes(0xb96cbd13), Next: 1677557088}}, // Last MergeNetsplit block
|
||||||
{1735372, 1677557088, ID{Hash: checksumToBytes(0xf7f9bc08), Next: 1706655072}}, // First Shanghai block
|
{1735372, 1677557088, ID{Hash: checksumToBytes(0xf7f9bc08), Next: 1706655072}}, // First Shanghai block
|
||||||
{1735372, 1706655071, ID{Hash: checksumToBytes(0xf7f9bc08), Next: 1706655072}}, // Last Shanghai block
|
{1735372, 1706655071, ID{Hash: checksumToBytes(0xf7f9bc08), Next: 1706655072}}, // Last Shanghai block
|
||||||
{1735372, 1706655072, ID{Hash: checksumToBytes(0x88cf81d9), Next: 0}}, // First Cancun block
|
{1735372, 1706655072, ID{Hash: checksumToBytes(0x88cf81d9), Next: 1741159776}}, // First Cancun block
|
||||||
{1735372, 2706655072, ID{Hash: checksumToBytes(0x88cf81d9), Next: 0}}, // Future Cancun block
|
{1735372, 1741159775, ID{Hash: checksumToBytes(0x88cf81d9), Next: 1741159776}}, // Last Cancun block
|
||||||
|
{1735372, 1741159776, ID{Hash: checksumToBytes(0xed88b5fd), Next: 0}}, // First Prague block
|
||||||
|
{1735372, 2741159776, ID{Hash: checksumToBytes(0xed88b5fd), Next: 0}}, // Future Prague block
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Holesky test cases
|
// Holesky test cases
|
||||||
|
|
@ -104,8 +106,10 @@ func TestCreation(t *testing.T) {
|
||||||
{123, 0, ID{Hash: checksumToBytes(0xc61a6098), Next: 1696000704}}, // First MergeNetsplit block
|
{123, 0, ID{Hash: checksumToBytes(0xc61a6098), Next: 1696000704}}, // First MergeNetsplit block
|
||||||
{123, 1696000704, ID{Hash: checksumToBytes(0xfd4f016b), Next: 1707305664}}, // First Shanghai block
|
{123, 1696000704, ID{Hash: checksumToBytes(0xfd4f016b), Next: 1707305664}}, // First Shanghai block
|
||||||
{123, 1707305663, ID{Hash: checksumToBytes(0xfd4f016b), Next: 1707305664}}, // Last Shanghai block
|
{123, 1707305663, ID{Hash: checksumToBytes(0xfd4f016b), Next: 1707305664}}, // Last Shanghai block
|
||||||
{123, 1707305664, ID{Hash: checksumToBytes(0x9b192ad0), Next: 0}}, // First Cancun block
|
{123, 1707305664, ID{Hash: checksumToBytes(0x9b192ad0), Next: 1740434112}}, // First Cancun block
|
||||||
{123, 2707305664, ID{Hash: checksumToBytes(0x9b192ad0), Next: 0}}, // Future Cancun block
|
{123, 1740434111, ID{Hash: checksumToBytes(0x9b192ad0), Next: 1740434112}}, // Last Cancun block
|
||||||
|
{123, 1740434112, ID{Hash: checksumToBytes(0xdfbd9bed), Next: 0}}, // First Prague block
|
||||||
|
{123, 2740434112, ID{Hash: checksumToBytes(0xdfbd9bed), Next: 0}}, // Future Prague block
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,7 @@ func (bc *testBlockChain) CurrentBlock() *types.Header {
|
||||||
GasLimit: gasLimit,
|
GasLimit: gasLimit,
|
||||||
BaseFee: baseFee,
|
BaseFee: baseFee,
|
||||||
ExcessBlobGas: &excessBlobGas,
|
ExcessBlobGas: &excessBlobGas,
|
||||||
|
Difficulty: common.Big0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1565,8 +1566,9 @@ func TestAdd(t *testing.T) {
|
||||||
if tt.block != nil {
|
if tt.block != nil {
|
||||||
// Fake a header for the new set of transactions
|
// Fake a header for the new set of transactions
|
||||||
header := &types.Header{
|
header := &types.Header{
|
||||||
Number: big.NewInt(int64(chain.CurrentBlock().Number.Uint64() + 1)),
|
Number: big.NewInt(int64(chain.CurrentBlock().Number.Uint64() + 1)),
|
||||||
BaseFee: chain.CurrentBlock().BaseFee, // invalid, but nothing checks it, yolo
|
Difficulty: common.Big0,
|
||||||
|
BaseFee: chain.CurrentBlock().BaseFee, // invalid, but nothing checks it, yolo
|
||||||
}
|
}
|
||||||
// Inject the fake block into the chain
|
// Inject the fake block into the chain
|
||||||
txs := make([]*types.Transaction, len(tt.block))
|
txs := make([]*types.Transaction, len(tt.block))
|
||||||
|
|
|
||||||
|
|
@ -60,4 +60,13 @@ var (
|
||||||
// input transaction of non-blob type when a blob transaction from this sender
|
// input transaction of non-blob type when a blob transaction from this sender
|
||||||
// remains pending (and vice-versa).
|
// remains pending (and vice-versa).
|
||||||
ErrAlreadyReserved = errors.New("address already reserved")
|
ErrAlreadyReserved = errors.New("address already reserved")
|
||||||
|
|
||||||
|
// ErrAuthorityReserved is returned if a transaction has an authorization
|
||||||
|
// signed by an address which already has in-flight transactions known to the
|
||||||
|
// pool.
|
||||||
|
ErrAuthorityReserved = errors.New("authority already reserved")
|
||||||
|
|
||||||
|
// ErrAuthorityNonce is returned if a transaction has an authorization with
|
||||||
|
// a nonce that is not currently valid for the authority.
|
||||||
|
ErrAuthorityNonceTooLow = errors.New("authority nonce too low")
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
@ -196,6 +197,20 @@ func (config *Config) sanitize() Config {
|
||||||
// The pool separates processable transactions (which can be applied to the
|
// The pool separates processable transactions (which can be applied to the
|
||||||
// current state) and future transactions. Transactions move between those
|
// current state) and future transactions. Transactions move between those
|
||||||
// two states over time as they are received and processed.
|
// two states over time as they are received and processed.
|
||||||
|
//
|
||||||
|
// In addition to tracking transactions, the pool also tracks a set of pending SetCode
|
||||||
|
// authorizations (EIP7702). This helps minimize number of transactions that can be
|
||||||
|
// trivially churned in the pool. As a standard rule, any account with a deployed
|
||||||
|
// delegation or an in-flight authorization to deploy a delegation will only be allowed a
|
||||||
|
// single transaction slot instead of the standard number. This is due to the possibility
|
||||||
|
// of the account being sweeped by an unrelated account.
|
||||||
|
//
|
||||||
|
// Because SetCode transactions can have many authorizations included, we avoid explicitly
|
||||||
|
// checking their validity to save the state lookup. So long as the encompassing
|
||||||
|
// transaction is valid, the authorization will be accepted and tracked by the pool. In
|
||||||
|
// case the pool is tracking a pending / queued transaction from a specific account, it
|
||||||
|
// will reject new transactions with delegations from that account with standard in-flight
|
||||||
|
// transactions.
|
||||||
type LegacyPool struct {
|
type LegacyPool struct {
|
||||||
config Config
|
config Config
|
||||||
chainconfig *params.ChainConfig
|
chainconfig *params.ChainConfig
|
||||||
|
|
@ -263,7 +278,7 @@ func New(config Config, chain BlockChain) *LegacyPool {
|
||||||
// pool, specifically, whether it is a Legacy, AccessList or Dynamic transaction.
|
// pool, specifically, whether it is a Legacy, AccessList or Dynamic transaction.
|
||||||
func (pool *LegacyPool) Filter(tx *types.Transaction) bool {
|
func (pool *LegacyPool) Filter(tx *types.Transaction) bool {
|
||||||
switch tx.Type() {
|
switch tx.Type() {
|
||||||
case types.LegacyTxType, types.AccessListTxType, types.DynamicFeeTxType:
|
case types.LegacyTxType, types.AccessListTxType, types.DynamicFeeTxType, types.SetCodeTxType:
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
|
|
@ -540,7 +555,8 @@ func (pool *LegacyPool) validateTxBasics(tx *types.Transaction) error {
|
||||||
Accept: 0 |
|
Accept: 0 |
|
||||||
1<<types.LegacyTxType |
|
1<<types.LegacyTxType |
|
||||||
1<<types.AccessListTxType |
|
1<<types.AccessListTxType |
|
||||||
1<<types.DynamicFeeTxType,
|
1<<types.DynamicFeeTxType |
|
||||||
|
1<<types.SetCodeTxType,
|
||||||
MaxSize: txMaxSize,
|
MaxSize: txMaxSize,
|
||||||
MinTip: pool.gasTip.Load().ToBig(),
|
MinTip: pool.gasTip.Load().ToBig(),
|
||||||
}
|
}
|
||||||
|
|
@ -565,6 +581,11 @@ func (pool *LegacyPool) validateTx(tx *types.Transaction) error {
|
||||||
if list := pool.queue[addr]; list != nil {
|
if list := pool.queue[addr]; list != nil {
|
||||||
have += list.Len()
|
have += list.Len()
|
||||||
}
|
}
|
||||||
|
if pool.currentState.GetCodeHash(addr) != types.EmptyCodeHash || len(pool.all.auths[addr]) != 0 {
|
||||||
|
// Allow at most one in-flight tx for delegated accounts or those with
|
||||||
|
// a pending authorization.
|
||||||
|
return have, max(0, 1-have)
|
||||||
|
}
|
||||||
return have, math.MaxInt
|
return have, math.MaxInt
|
||||||
},
|
},
|
||||||
ExistingExpenditure: func(addr common.Address) *big.Int {
|
ExistingExpenditure: func(addr common.Address) *big.Int {
|
||||||
|
|
@ -581,6 +602,18 @@ func (pool *LegacyPool) validateTx(tx *types.Transaction) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
KnownConflicts: func(from common.Address, auths []common.Address) []common.Address {
|
||||||
|
var conflicts []common.Address
|
||||||
|
// Authorities cannot conflict with any pending or queued transactions.
|
||||||
|
for _, addr := range auths {
|
||||||
|
if list := pool.pending[addr]; list != nil {
|
||||||
|
conflicts = append(conflicts, addr)
|
||||||
|
} else if list := pool.queue[addr]; list != nil {
|
||||||
|
conflicts = append(conflicts, addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return conflicts
|
||||||
|
},
|
||||||
}
|
}
|
||||||
if err := txpool.ValidateTransactionWithState(tx, pool.signer, opts); err != nil {
|
if err := txpool.ValidateTransactionWithState(tx, pool.signer, opts); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -1334,15 +1367,13 @@ func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.T
|
||||||
// Drop all transactions that are deemed too old (low nonce)
|
// Drop all transactions that are deemed too old (low nonce)
|
||||||
forwards := list.Forward(pool.currentState.GetNonce(addr))
|
forwards := list.Forward(pool.currentState.GetNonce(addr))
|
||||||
for _, tx := range forwards {
|
for _, tx := range forwards {
|
||||||
hash := tx.Hash()
|
pool.all.Remove(tx.Hash())
|
||||||
pool.all.Remove(hash)
|
|
||||||
}
|
}
|
||||||
log.Trace("Removed old queued transactions", "count", len(forwards))
|
log.Trace("Removed old queued transactions", "count", len(forwards))
|
||||||
// Drop all transactions that are too costly (low balance or out of gas)
|
// Drop all transactions that are too costly (low balance or out of gas)
|
||||||
drops, _ := list.Filter(pool.currentState.GetBalance(addr), gasLimit)
|
drops, _ := list.Filter(pool.currentState.GetBalance(addr), gasLimit)
|
||||||
for _, tx := range drops {
|
for _, tx := range drops {
|
||||||
hash := tx.Hash()
|
pool.all.Remove(tx.Hash())
|
||||||
pool.all.Remove(hash)
|
|
||||||
}
|
}
|
||||||
log.Trace("Removed unpayable queued transactions", "count", len(drops))
|
log.Trace("Removed unpayable queued transactions", "count", len(drops))
|
||||||
queuedNofundsMeter.Mark(int64(len(drops)))
|
queuedNofundsMeter.Mark(int64(len(drops)))
|
||||||
|
|
@ -1531,8 +1562,8 @@ func (pool *LegacyPool) demoteUnexecutables() {
|
||||||
drops, invalids := list.Filter(pool.currentState.GetBalance(addr), gasLimit)
|
drops, invalids := list.Filter(pool.currentState.GetBalance(addr), gasLimit)
|
||||||
for _, tx := range drops {
|
for _, tx := range drops {
|
||||||
hash := tx.Hash()
|
hash := tx.Hash()
|
||||||
log.Trace("Removed unpayable pending transaction", "hash", hash)
|
|
||||||
pool.all.Remove(hash)
|
pool.all.Remove(hash)
|
||||||
|
log.Trace("Removed unpayable pending transaction", "hash", hash)
|
||||||
}
|
}
|
||||||
pendingNofundsMeter.Mark(int64(len(drops)))
|
pendingNofundsMeter.Mark(int64(len(drops)))
|
||||||
|
|
||||||
|
|
@ -1641,12 +1672,15 @@ type lookup struct {
|
||||||
slots int
|
slots int
|
||||||
lock sync.RWMutex
|
lock sync.RWMutex
|
||||||
txs map[common.Hash]*types.Transaction
|
txs map[common.Hash]*types.Transaction
|
||||||
|
|
||||||
|
auths map[common.Address][]common.Hash // All accounts with a pooled authorization
|
||||||
}
|
}
|
||||||
|
|
||||||
// newLookup returns a new lookup structure.
|
// newLookup returns a new lookup structure.
|
||||||
func newLookup() *lookup {
|
func newLookup() *lookup {
|
||||||
return &lookup{
|
return &lookup{
|
||||||
txs: make(map[common.Hash]*types.Transaction),
|
txs: make(map[common.Hash]*types.Transaction),
|
||||||
|
auths: make(map[common.Address][]common.Hash),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1697,6 +1731,7 @@ func (t *lookup) Add(tx *types.Transaction) {
|
||||||
slotsGauge.Update(int64(t.slots))
|
slotsGauge.Update(int64(t.slots))
|
||||||
|
|
||||||
t.txs[tx.Hash()] = tx
|
t.txs[tx.Hash()] = tx
|
||||||
|
t.addAuthorities(tx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove removes a transaction from the lookup.
|
// Remove removes a transaction from the lookup.
|
||||||
|
|
@ -1704,6 +1739,7 @@ func (t *lookup) Remove(hash common.Hash) {
|
||||||
t.lock.Lock()
|
t.lock.Lock()
|
||||||
defer t.lock.Unlock()
|
defer t.lock.Unlock()
|
||||||
|
|
||||||
|
t.removeAuthorities(hash)
|
||||||
tx, ok := t.txs[hash]
|
tx, ok := t.txs[hash]
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Error("No transaction found to be deleted", "hash", hash)
|
log.Error("No transaction found to be deleted", "hash", hash)
|
||||||
|
|
@ -1727,6 +1763,43 @@ func (t *lookup) TxsBelowTip(threshold *big.Int) types.Transactions {
|
||||||
return found
|
return found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addAuthorities tracks the supplied tx in relation to each authority it
|
||||||
|
// specifies.
|
||||||
|
func (t *lookup) addAuthorities(tx *types.Transaction) {
|
||||||
|
for _, addr := range tx.SetCodeAuthorities() {
|
||||||
|
list, ok := t.auths[addr]
|
||||||
|
if !ok {
|
||||||
|
list = []common.Hash{}
|
||||||
|
}
|
||||||
|
if slices.Contains(list, tx.Hash()) {
|
||||||
|
// Don't add duplicates.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
list = append(list, tx.Hash())
|
||||||
|
t.auths[addr] = list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// removeAuthorities stops tracking the supplied tx in relation to its
|
||||||
|
// authorities.
|
||||||
|
func (t *lookup) removeAuthorities(hash common.Hash) {
|
||||||
|
for addr := range t.auths {
|
||||||
|
list := t.auths[addr]
|
||||||
|
// Remove tx from tracker.
|
||||||
|
if i := slices.Index(list, hash); i >= 0 {
|
||||||
|
list = append(list[:i], list[i+1:]...)
|
||||||
|
} else {
|
||||||
|
log.Error("Authority with untracked tx", "addr", addr, "hash", hash)
|
||||||
|
}
|
||||||
|
if len(list) == 0 {
|
||||||
|
// If list is newly empty, delete it entirely.
|
||||||
|
delete(t.auths, addr)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
t.auths[addr] = list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// numSlots calculates the number of slots needed for a single transaction.
|
// numSlots calculates the number of slots needed for a single transaction.
|
||||||
func numSlots(tx *types.Transaction) int {
|
func numSlots(tx *types.Transaction) int {
|
||||||
return int((tx.Size() + txSlotSize - 1) / txSlotSize)
|
return int((tx.Size() + txSlotSize - 1) / txSlotSize)
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"github.com/ethereum/go-ethereum/core/txpool"
|
"github.com/ethereum/go-ethereum/core/txpool"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/event"
|
"github.com/ethereum/go-ethereum/event"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
@ -79,8 +80,9 @@ func (bc *testBlockChain) Config() *params.ChainConfig {
|
||||||
|
|
||||||
func (bc *testBlockChain) CurrentBlock() *types.Header {
|
func (bc *testBlockChain) CurrentBlock() *types.Header {
|
||||||
return &types.Header{
|
return &types.Header{
|
||||||
Number: new(big.Int),
|
Number: new(big.Int),
|
||||||
GasLimit: bc.gasLimit.Load(),
|
Difficulty: common.Big0,
|
||||||
|
GasLimit: bc.gasLimit.Load(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,6 +130,39 @@ func dynamicFeeTx(nonce uint64, gaslimit uint64, gasFee *big.Int, tip *big.Int,
|
||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type unsignedAuth struct {
|
||||||
|
nonce uint64
|
||||||
|
key *ecdsa.PrivateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func setCodeTx(nonce uint64, key *ecdsa.PrivateKey, unsigned []unsignedAuth) *types.Transaction {
|
||||||
|
return pricedSetCodeTx(nonce, 250000, uint256.NewInt(1000), uint256.NewInt(1), key, unsigned)
|
||||||
|
}
|
||||||
|
|
||||||
|
func pricedSetCodeTx(nonce uint64, gaslimit uint64, gasFee, tip *uint256.Int, key *ecdsa.PrivateKey, unsigned []unsignedAuth) *types.Transaction {
|
||||||
|
var authList []types.SetCodeAuthorization
|
||||||
|
for _, u := range unsigned {
|
||||||
|
auth, _ := types.SignSetCode(u.key, types.SetCodeAuthorization{
|
||||||
|
ChainID: *uint256.MustFromBig(params.TestChainConfig.ChainID),
|
||||||
|
Address: common.Address{0x42},
|
||||||
|
Nonce: u.nonce,
|
||||||
|
})
|
||||||
|
authList = append(authList, auth)
|
||||||
|
}
|
||||||
|
return types.MustSignNewTx(key, types.LatestSignerForChainID(params.TestChainConfig.ChainID), &types.SetCodeTx{
|
||||||
|
ChainID: uint256.MustFromBig(params.TestChainConfig.ChainID),
|
||||||
|
Nonce: nonce,
|
||||||
|
GasTipCap: tip,
|
||||||
|
GasFeeCap: gasFee,
|
||||||
|
Gas: gaslimit,
|
||||||
|
To: common.Address{},
|
||||||
|
Value: uint256.NewInt(100),
|
||||||
|
Data: nil,
|
||||||
|
AccessList: nil,
|
||||||
|
AuthList: authList,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func makeAddressReserver() txpool.AddressReserver {
|
func makeAddressReserver() txpool.AddressReserver {
|
||||||
var (
|
var (
|
||||||
reserved = make(map[common.Address]struct{})
|
reserved = make(map[common.Address]struct{})
|
||||||
|
|
@ -2163,6 +2198,201 @@ func TestSlotCount(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestSetCodeTransactions tests a few scenarios regarding the EIP-7702
|
||||||
|
// SetCodeTx.
|
||||||
|
func TestSetCodeTransactions(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
// Create the pool to test the status retrievals with
|
||||||
|
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
|
blockchain := newTestBlockChain(params.MergedTestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver())
|
||||||
|
defer pool.Close()
|
||||||
|
|
||||||
|
// Create the test accounts
|
||||||
|
var (
|
||||||
|
keyA, _ = crypto.GenerateKey()
|
||||||
|
keyB, _ = crypto.GenerateKey()
|
||||||
|
keyC, _ = crypto.GenerateKey()
|
||||||
|
addrA = crypto.PubkeyToAddress(keyA.PublicKey)
|
||||||
|
addrB = crypto.PubkeyToAddress(keyB.PublicKey)
|
||||||
|
addrC = crypto.PubkeyToAddress(keyC.PublicKey)
|
||||||
|
)
|
||||||
|
testAddBalance(pool, addrA, big.NewInt(params.Ether))
|
||||||
|
testAddBalance(pool, addrB, big.NewInt(params.Ether))
|
||||||
|
testAddBalance(pool, addrC, big.NewInt(params.Ether))
|
||||||
|
|
||||||
|
for _, tt := range []struct {
|
||||||
|
name string
|
||||||
|
pending int
|
||||||
|
queued int
|
||||||
|
run func(string)
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
// Check that only one in-flight transaction is allowed for accounts
|
||||||
|
// with delegation set. Also verify the accepted transaction can be
|
||||||
|
// replaced by fee.
|
||||||
|
name: "only-one-in-flight",
|
||||||
|
pending: 1,
|
||||||
|
run: func(name string) {
|
||||||
|
aa := common.Address{0xaa, 0xaa}
|
||||||
|
statedb.SetCode(addrA, append(types.DelegationPrefix, aa.Bytes()...))
|
||||||
|
statedb.SetCode(aa, []byte{byte(vm.ADDRESS), byte(vm.PUSH0), byte(vm.SSTORE)})
|
||||||
|
// Send transactions. First is accepted, second is rejected.
|
||||||
|
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keyA)); err != nil {
|
||||||
|
t.Fatalf("%s: failed to add remote transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyA)); !errors.Is(err, txpool.ErrAccountLimitExceeded) {
|
||||||
|
t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrAccountLimitExceeded, err)
|
||||||
|
}
|
||||||
|
// Also check gapped transaction.
|
||||||
|
if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1), keyA)); !errors.Is(err, txpool.ErrAccountLimitExceeded) {
|
||||||
|
t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrAccountLimitExceeded, err)
|
||||||
|
}
|
||||||
|
// Replace by fee.
|
||||||
|
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(10), keyA)); err != nil {
|
||||||
|
t.Fatalf("%s: failed to replace with remote transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "allow-setcode-tx-with-pending-authority-tx",
|
||||||
|
pending: 2,
|
||||||
|
run: func(name string) {
|
||||||
|
// Send two transactions where the first has no conflicting delegations and
|
||||||
|
// the second should be allowed despite conflicting with the authorities in 1).
|
||||||
|
if err := pool.addRemoteSync(setCodeTx(0, keyA, []unsignedAuth{{1, keyC}})); err != nil {
|
||||||
|
t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
if err := pool.addRemoteSync(setCodeTx(0, keyB, []unsignedAuth{{1, keyC}})); err != nil {
|
||||||
|
t.Fatalf("%s: failed to add conflicting delegation: %v", name, err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "allow-one-tx-from-pooled-delegation",
|
||||||
|
pending: 2,
|
||||||
|
run: func(name string) {
|
||||||
|
// Verify C cannot originate another transaction when it has a pooled delegation.
|
||||||
|
if err := pool.addRemoteSync(setCodeTx(0, keyA, []unsignedAuth{{0, keyC}})); err != nil {
|
||||||
|
t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1), keyC)); err != nil {
|
||||||
|
t.Fatalf("%s: failed to add with pending delegatio: %v", name, err)
|
||||||
|
}
|
||||||
|
// Also check gapped transaction is rejected.
|
||||||
|
if err := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1), keyC)); !errors.Is(err, txpool.ErrAccountLimitExceeded) {
|
||||||
|
t.Fatalf("%s: error mismatch: want %v, have %v", name, txpool.ErrAccountLimitExceeded, err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "replace-by-fee-setcode-tx",
|
||||||
|
pending: 1,
|
||||||
|
run: func(name string) {
|
||||||
|
// 4. Fee bump the setcode tx send.
|
||||||
|
if err := pool.addRemoteSync(setCodeTx(0, keyB, []unsignedAuth{{1, keyC}})); err != nil {
|
||||||
|
t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(2000), uint256.NewInt(2), keyB, []unsignedAuth{{0, keyC}})); err != nil {
|
||||||
|
t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "allow-tx-from-replaced-authority",
|
||||||
|
pending: 2,
|
||||||
|
run: func(name string) {
|
||||||
|
// Fee bump with a different auth list. Make sure that unlocks the authorities.
|
||||||
|
if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(10), uint256.NewInt(3), keyA, []unsignedAuth{{0, keyB}})); err != nil {
|
||||||
|
t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(3000), uint256.NewInt(300), keyA, []unsignedAuth{{0, keyC}})); err != nil {
|
||||||
|
t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
// Now send a regular tx from B.
|
||||||
|
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(10), keyB)); err != nil {
|
||||||
|
t.Fatalf("%s: failed to replace with remote transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "allow-tx-from-replaced-self-sponsor-authority",
|
||||||
|
pending: 2,
|
||||||
|
run: func(name string) {
|
||||||
|
//
|
||||||
|
if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(10), uint256.NewInt(3), keyA, []unsignedAuth{{0, keyA}})); err != nil {
|
||||||
|
t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(30), uint256.NewInt(30), keyA, []unsignedAuth{{0, keyB}})); err != nil {
|
||||||
|
t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
// Now send a regular tx from keyA.
|
||||||
|
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyA)); err != nil {
|
||||||
|
t.Fatalf("%s: failed to replace with remote transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
// Make sure we can still send from keyB.
|
||||||
|
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyB)); err != nil {
|
||||||
|
t.Fatalf("%s: failed to replace with remote transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "track-multiple-conflicting-delegations",
|
||||||
|
pending: 3,
|
||||||
|
run: func(name string) {
|
||||||
|
// Send two setcode txs both with C as an authority.
|
||||||
|
if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(10), uint256.NewInt(3), keyA, []unsignedAuth{{0, keyC}})); err != nil {
|
||||||
|
t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
if err := pool.addRemoteSync(pricedSetCodeTx(0, 250000, uint256.NewInt(30), uint256.NewInt(30), keyB, []unsignedAuth{{0, keyC}})); err != nil {
|
||||||
|
t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
// Replace the tx from A with a non-setcode tx.
|
||||||
|
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyA)); err != nil {
|
||||||
|
t.Fatalf("%s: failed to replace with remote transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
// Make sure we can only pool one tx from keyC since it is still a
|
||||||
|
// pending authority.
|
||||||
|
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyC)); err != nil {
|
||||||
|
t.Fatalf("%s: failed to added single pooled for account with pending delegation: %v", name, err)
|
||||||
|
}
|
||||||
|
if err, want := pool.addRemoteSync(pricedTransaction(1, 100000, big.NewInt(1000), keyC)), txpool.ErrAccountLimitExceeded; !errors.Is(err, want) {
|
||||||
|
t.Fatalf("%s: error mismatch: want %v, have %v", name, want, err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "reject-delegation-from-pending-account",
|
||||||
|
pending: 1,
|
||||||
|
run: func(name string) {
|
||||||
|
// Attempt to submit a delegation from an account with a pending tx.
|
||||||
|
if err := pool.addRemoteSync(pricedTransaction(0, 100000, big.NewInt(1000), keyC)); err != nil {
|
||||||
|
t.Fatalf("%s: failed to add with remote setcode transaction: %v", name, err)
|
||||||
|
}
|
||||||
|
if err, want := pool.addRemoteSync(setCodeTx(0, keyA, []unsignedAuth{{1, keyC}})), txpool.ErrAuthorityReserved; !errors.Is(err, want) {
|
||||||
|
t.Fatalf("%s: error mismatch: want %v, have %v", name, want, err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
tt.run(tt.name)
|
||||||
|
pending, queued := pool.Stats()
|
||||||
|
if pending != tt.pending {
|
||||||
|
t.Fatalf("%s: pending transactions mismatched: have %d, want %d", tt.name, pending, tt.pending)
|
||||||
|
}
|
||||||
|
if queued != tt.queued {
|
||||||
|
t.Fatalf("%s: queued transactions mismatched: have %d, want %d", tt.name, queued, tt.queued)
|
||||||
|
}
|
||||||
|
if err := validatePoolInternals(pool); err != nil {
|
||||||
|
t.Fatalf("%s: pool internal state corrupted: %v", tt.name, err)
|
||||||
|
}
|
||||||
|
pool.Clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Benchmarks the speed of validating the contents of the pending queue of the
|
// Benchmarks the speed of validating the contents of the pending queue of the
|
||||||
// transaction pool.
|
// transaction pool.
|
||||||
func BenchmarkPendingDemotion100(b *testing.B) { benchmarkPendingDemotion(b, 100) }
|
func BenchmarkPendingDemotion100(b *testing.B) { benchmarkPendingDemotion(b, 100) }
|
||||||
|
|
|
||||||
|
|
@ -70,17 +70,21 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
|
||||||
return fmt.Errorf("%w: transaction size %v, limit %v", ErrOversizedData, tx.Size(), opts.MaxSize)
|
return fmt.Errorf("%w: transaction size %v, limit %v", ErrOversizedData, tx.Size(), opts.MaxSize)
|
||||||
}
|
}
|
||||||
// Ensure only transactions that have been enabled are accepted
|
// Ensure only transactions that have been enabled are accepted
|
||||||
if !opts.Config.IsBerlin(head.Number) && tx.Type() != types.LegacyTxType {
|
rules := opts.Config.Rules(head.Number, head.Difficulty.Sign() == 0, head.Time)
|
||||||
|
if !rules.IsBerlin && tx.Type() != types.LegacyTxType {
|
||||||
return fmt.Errorf("%w: type %d rejected, pool not yet in Berlin", core.ErrTxTypeNotSupported, tx.Type())
|
return fmt.Errorf("%w: type %d rejected, pool not yet in Berlin", core.ErrTxTypeNotSupported, tx.Type())
|
||||||
}
|
}
|
||||||
if !opts.Config.IsLondon(head.Number) && tx.Type() == types.DynamicFeeTxType {
|
if !rules.IsLondon && tx.Type() == types.DynamicFeeTxType {
|
||||||
return fmt.Errorf("%w: type %d rejected, pool not yet in London", core.ErrTxTypeNotSupported, tx.Type())
|
return fmt.Errorf("%w: type %d rejected, pool not yet in London", core.ErrTxTypeNotSupported, tx.Type())
|
||||||
}
|
}
|
||||||
if !opts.Config.IsCancun(head.Number, head.Time) && tx.Type() == types.BlobTxType {
|
if !rules.IsCancun && tx.Type() == types.BlobTxType {
|
||||||
return fmt.Errorf("%w: type %d rejected, pool not yet in Cancun", core.ErrTxTypeNotSupported, tx.Type())
|
return fmt.Errorf("%w: type %d rejected, pool not yet in Cancun", core.ErrTxTypeNotSupported, tx.Type())
|
||||||
}
|
}
|
||||||
|
if !rules.IsPrague && tx.Type() == types.SetCodeTxType {
|
||||||
|
return fmt.Errorf("%w: type %d rejected, pool not yet in Prague", core.ErrTxTypeNotSupported, tx.Type())
|
||||||
|
}
|
||||||
// Check whether the init code size has been exceeded
|
// Check whether the init code size has been exceeded
|
||||||
if opts.Config.IsShanghai(head.Number, head.Time) && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize {
|
if rules.IsShanghai && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize {
|
||||||
return fmt.Errorf("%w: code size %v, limit %v", core.ErrMaxInitCodeSizeExceeded, len(tx.Data()), params.MaxInitCodeSize)
|
return fmt.Errorf("%w: code size %v, limit %v", core.ErrMaxInitCodeSizeExceeded, len(tx.Data()), params.MaxInitCodeSize)
|
||||||
}
|
}
|
||||||
// Transactions can't be negative. This may never happen using RLP decoded
|
// Transactions can't be negative. This may never happen using RLP decoded
|
||||||
|
|
@ -109,7 +113,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
|
||||||
}
|
}
|
||||||
// Ensure the transaction has more gas than the bare minimum needed to cover
|
// Ensure the transaction has more gas than the bare minimum needed to cover
|
||||||
// the transaction metadata
|
// the transaction metadata
|
||||||
intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, true, opts.Config.IsIstanbul(head.Number), opts.Config.IsShanghai(head.Number, head.Time))
|
intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, true, rules.IsIstanbul, rules.IsShanghai)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -154,6 +158,11 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if tx.Type() == types.SetCodeTxType {
|
||||||
|
if len(tx.SetCodeAuthorizations()) == 0 {
|
||||||
|
return fmt.Errorf("set code tx must have at least one authorization tuple")
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -209,6 +218,11 @@ type ValidationOptionsWithState struct {
|
||||||
// ExistingCost is a mandatory callback to retrieve an already pooled
|
// ExistingCost is a mandatory callback to retrieve an already pooled
|
||||||
// transaction's cost with the given nonce to check for overdrafts.
|
// transaction's cost with the given nonce to check for overdrafts.
|
||||||
ExistingCost func(addr common.Address, nonce uint64) *big.Int
|
ExistingCost func(addr common.Address, nonce uint64) *big.Int
|
||||||
|
|
||||||
|
// KnownConflicts is an optional callback which iterates over the list of
|
||||||
|
// addresses and returns all addresses known to the pool with in-flight
|
||||||
|
// transactions.
|
||||||
|
KnownConflicts func(sender common.Address, authorizers []common.Address) []common.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateTransactionWithState is a helper method to check whether a transaction
|
// ValidateTransactionWithState is a helper method to check whether a transaction
|
||||||
|
|
@ -262,6 +276,14 @@ func ValidateTransactionWithState(tx *types.Transaction, signer types.Signer, op
|
||||||
if used, left := opts.UsedAndLeftSlots(from); left <= 0 {
|
if used, left := opts.UsedAndLeftSlots(from); left <= 0 {
|
||||||
return fmt.Errorf("%w: pooled %d txs", ErrAccountLimitExceeded, used)
|
return fmt.Errorf("%w: pooled %d txs", ErrAccountLimitExceeded, used)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify no authorizations will invalidate existing transactions known to
|
||||||
|
// the pool.
|
||||||
|
if opts.KnownConflicts != nil {
|
||||||
|
if conflicts := opts.KnownConflicts(from, tx.SetCodeAuthorities()); len(conflicts) > 0 {
|
||||||
|
return fmt.Errorf("%w: authorization conflicts with other known tx", ErrAuthorityReserved)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -483,6 +483,21 @@ func (tx *Transaction) SetCodeAuthorizations() []SetCodeAuthorization {
|
||||||
return setcodetx.AuthList
|
return setcodetx.AuthList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetCodeAuthorities returns a list of each authorization's corresponding authority.
|
||||||
|
func (tx *Transaction) SetCodeAuthorities() []common.Address {
|
||||||
|
setcodetx, ok := tx.inner.(*SetCodeTx)
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
auths := make([]common.Address, 0, len(setcodetx.AuthList))
|
||||||
|
for _, auth := range setcodetx.AuthList {
|
||||||
|
if addr, err := auth.Authority(); err == nil {
|
||||||
|
auths = append(auths, addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return auths
|
||||||
|
}
|
||||||
|
|
||||||
// SetTime sets the decoding time of a transaction. This is used by tests to set
|
// SetTime sets the decoding time of a transaction. This is used by tests to set
|
||||||
// arbitrary times and by persistent transaction pools when loading old txs from
|
// arbitrary times and by persistent transaction pools when loading old txs from
|
||||||
// disk.
|
// disk.
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,12 @@ func generateMergeChain(n int, merged bool) (*core.Genesis, []*types.Block) {
|
||||||
engine := beacon.New(ethash.NewFaker())
|
engine := beacon.New(ethash.NewFaker())
|
||||||
if merged {
|
if merged {
|
||||||
config.TerminalTotalDifficulty = common.Big0
|
config.TerminalTotalDifficulty = common.Big0
|
||||||
|
config.MergeNetsplitBlock = common.Big0
|
||||||
} else {
|
} else {
|
||||||
engine.TestingTTDBlock(uint64(n))
|
// When !merged, the tests expect the next block after the generated chain to be in PoS.
|
||||||
|
config.MergeNetsplitBlock = big.NewInt(int64(n + 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
genesis := &core.Genesis{
|
genesis := &core.Genesis{
|
||||||
Config: &config,
|
Config: &config,
|
||||||
Alloc: types.GenesisAlloc{
|
Alloc: types.GenesisAlloc{
|
||||||
|
|
|
||||||
|
|
@ -147,11 +147,11 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, cancunBlock *big.Int, pe
|
||||||
config.LondonBlock = londonBlock
|
config.LondonBlock = londonBlock
|
||||||
config.ArrowGlacierBlock = londonBlock
|
config.ArrowGlacierBlock = londonBlock
|
||||||
config.GrayGlacierBlock = londonBlock
|
config.GrayGlacierBlock = londonBlock
|
||||||
|
if cancunBlock != nil {
|
||||||
|
// Enable the merge with cancun fork.
|
||||||
|
config.MergeNetsplitBlock = cancunBlock
|
||||||
|
}
|
||||||
engine := beacon.New(ethash.NewFaker())
|
engine := beacon.New(ethash.NewFaker())
|
||||||
engine.TestingTTDBlock(testHead + 1)
|
|
||||||
|
|
||||||
td := params.GenesisDifficulty.Uint64()
|
|
||||||
|
|
||||||
if cancunBlock != nil {
|
if cancunBlock != nil {
|
||||||
ts := gspec.Timestamp + cancunBlock.Uint64()*10 // fixed 10 sec block time in blockgen
|
ts := gspec.Timestamp + cancunBlock.Uint64()*10 // fixed 10 sec block time in blockgen
|
||||||
|
|
@ -209,10 +209,9 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, cancunBlock *big.Int, pe
|
||||||
b.AddTx(types.MustSignNewTx(key, signer, blobTx))
|
b.AddTx(types.MustSignNewTx(key, signer, blobTx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
td += b.Difficulty().Uint64()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Construct testing chain
|
// Construct testing chain
|
||||||
gspec.Config.TerminalTotalDifficulty = new(big.Int).SetUint64(td)
|
|
||||||
chain, err := core.NewBlockChain(db, &core.CacheConfig{TrieCleanNoPrefetch: true}, gspec, nil, engine, vm.Config{}, nil)
|
chain, err := core.NewBlockChain(db, &core.CacheConfig{TrieCleanNoPrefetch: true}, gspec, nil, engine, vm.Config{}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create local chain, %v", err)
|
t.Fatalf("Failed to create local chain, %v", err)
|
||||||
|
|
|
||||||
|
|
@ -74,9 +74,7 @@ func newTestBackendWithGenerator(blocks int, shanghai bool, generator func(int,
|
||||||
config = params.TestChainConfig
|
config = params.TestChainConfig
|
||||||
engine = beacon.New(ethash.NewFaker())
|
engine = beacon.New(ethash.NewFaker())
|
||||||
)
|
)
|
||||||
if !shanghai {
|
if shanghai {
|
||||||
engine.TestingTTDBlock(math.MaxUint64)
|
|
||||||
} else {
|
|
||||||
config = ¶ms.ChainConfig{
|
config = ¶ms.ChainConfig{
|
||||||
ChainID: big.NewInt(1),
|
ChainID: big.NewInt(1),
|
||||||
HomesteadBlock: big.NewInt(0),
|
HomesteadBlock: big.NewInt(0),
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,6 @@ func TestSupplyOmittedFields(t *testing.T) {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
gspec.Config.TerminalTotalDifficulty = big.NewInt(0)
|
|
||||||
|
|
||||||
out, _, err := testSupplyTracer(t, gspec, func(b *core.BlockGen) {
|
out, _, err := testSupplyTracer(t, gspec, func(b *core.BlockGen) {
|
||||||
b.SetPoS()
|
b.SetPoS()
|
||||||
})
|
})
|
||||||
|
|
@ -546,7 +544,6 @@ func TestSupplySelfdestructItselfAndRevert(t *testing.T) {
|
||||||
|
|
||||||
func testSupplyTracer(t *testing.T, genesis *core.Genesis, gen func(*core.BlockGen)) ([]supplyInfo, *core.BlockChain, error) {
|
func testSupplyTracer(t *testing.T, genesis *core.Genesis, gen func(*core.BlockGen)) ([]supplyInfo, *core.BlockChain, error) {
|
||||||
engine := beacon.New(ethash.NewFaker())
|
engine := beacon.New(ethash.NewFaker())
|
||||||
engine.TestingTTDBlock(1)
|
|
||||||
|
|
||||||
traceOutputPath := filepath.ToSlash(t.TempDir())
|
traceOutputPath := filepath.ToSlash(t.TempDir())
|
||||||
traceOutputFilename := path.Join(traceOutputPath, "supply.jsonl")
|
traceOutputFilename := path.Join(traceOutputPath, "supply.jsonl")
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -59,7 +59,7 @@ require (
|
||||||
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible
|
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible
|
||||||
github.com/status-im/keycard-go v0.2.0
|
github.com/status-im/keycard-go v0.2.0
|
||||||
github.com/stretchr/testify v1.9.0
|
github.com/stretchr/testify v1.9.0
|
||||||
github.com/supranational/blst v0.3.13
|
github.com/supranational/blst v0.3.14
|
||||||
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
|
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7
|
||||||
github.com/urfave/cli/v2 v2.25.7
|
github.com/urfave/cli/v2 v2.25.7
|
||||||
go.uber.org/automaxprocs v1.5.2
|
go.uber.org/automaxprocs v1.5.2
|
||||||
|
|
|
||||||
4
go.sum
4
go.sum
|
|
@ -508,8 +508,8 @@ github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
|
||||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk=
|
github.com/supranational/blst v0.3.14 h1:xNMoHRJOTwMn63ip6qoWJ2Ymgvj7E2b9jY2FAwY+qRo=
|
||||||
github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
|
github.com/supranational/blst v0.3.14/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
|
||||||
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
|
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY=
|
||||||
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
|
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
|
||||||
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -459,15 +458,13 @@ func newGQLService(t *testing.T, stack *node.Node, shanghai bool, gspec *core.Ge
|
||||||
var engine = beacon.New(ethash.NewFaker())
|
var engine = beacon.New(ethash.NewFaker())
|
||||||
if shanghai {
|
if shanghai {
|
||||||
gspec.Config.TerminalTotalDifficulty = common.Big0
|
gspec.Config.TerminalTotalDifficulty = common.Big0
|
||||||
|
gspec.Config.MergeNetsplitBlock = common.Big0
|
||||||
// GenerateChain will increment timestamps by 10.
|
// GenerateChain will increment timestamps by 10.
|
||||||
// Shanghai upgrade at block 1.
|
// Shanghai upgrade at block 1.
|
||||||
shanghaiTime := uint64(5)
|
shanghaiTime := uint64(5)
|
||||||
gspec.Config.ShanghaiTime = &shanghaiTime
|
gspec.Config.ShanghaiTime = &shanghaiTime
|
||||||
} else {
|
|
||||||
// set an arbitrary large ttd as chains are required to be known to be merged
|
|
||||||
gspec.Config.TerminalTotalDifficulty = big.NewInt(math.MaxInt64)
|
|
||||||
engine.TestingTTDBlock(math.MaxUint64)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ethBackend, err := eth.New(stack, ethConf)
|
ethBackend, err := eth.New(stack, ethConf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("could not create eth backend: %v", err)
|
t.Fatalf("could not create eth backend: %v", err)
|
||||||
|
|
|
||||||
|
|
@ -1675,7 +1675,7 @@ func (api *DebugAPI) GetRawHeader(ctx context.Context, blockNrOrHash rpc.BlockNu
|
||||||
hash = h
|
hash = h
|
||||||
} else {
|
} else {
|
||||||
block, err := api.b.BlockByNumberOrHash(ctx, blockNrOrHash)
|
block, err := api.b.BlockByNumberOrHash(ctx, blockNrOrHash)
|
||||||
if err != nil {
|
if block == nil || err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
hash = block.Hash()
|
hash = block.Hash()
|
||||||
|
|
@ -1694,7 +1694,7 @@ func (api *DebugAPI) GetRawBlock(ctx context.Context, blockNrOrHash rpc.BlockNum
|
||||||
hash = h
|
hash = h
|
||||||
} else {
|
} else {
|
||||||
block, err := api.b.BlockByNumberOrHash(ctx, blockNrOrHash)
|
block, err := api.b.BlockByNumberOrHash(ctx, blockNrOrHash)
|
||||||
if err != nil {
|
if block == nil || err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
hash = block.Hash()
|
hash = block.Hash()
|
||||||
|
|
@ -1713,7 +1713,7 @@ func (api *DebugAPI) GetRawReceipts(ctx context.Context, blockNrOrHash rpc.Block
|
||||||
hash = h
|
hash = h
|
||||||
} else {
|
} else {
|
||||||
block, err := api.b.BlockByNumberOrHash(ctx, blockNrOrHash)
|
block, err := api.b.BlockByNumberOrHash(ctx, blockNrOrHash)
|
||||||
if err != nil {
|
if block == nil || err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
hash = block.Hash()
|
hash = block.Hash()
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,9 @@ type Config struct {
|
||||||
// All remaining settings are optional.
|
// All remaining settings are optional.
|
||||||
|
|
||||||
// Packet handling configuration:
|
// Packet handling configuration:
|
||||||
NetRestrict *netutil.Netlist // list of allowed IP networks
|
NetRestrict *netutil.Netlist // list of allowed IP networks
|
||||||
Unhandled chan<- ReadPacket // unhandled packets are sent on this channel
|
Unhandled chan<- ReadPacket // unhandled packets are sent on this channel
|
||||||
|
V5RespTimeout time.Duration // timeout for v5 queries
|
||||||
|
|
||||||
// Node table configuration:
|
// Node table configuration:
|
||||||
Bootnodes []*enode.Node // list of bootstrap nodes
|
Bootnodes []*enode.Node // list of bootstrap nodes
|
||||||
|
|
@ -73,6 +74,9 @@ func (cfg Config) withDefaults() Config {
|
||||||
if cfg.RefreshInterval == 0 {
|
if cfg.RefreshInterval == 0 {
|
||||||
cfg.RefreshInterval = 30 * time.Minute
|
cfg.RefreshInterval = 30 * time.Minute
|
||||||
}
|
}
|
||||||
|
if cfg.V5RespTimeout == 0 {
|
||||||
|
cfg.V5RespTimeout = 700 * time.Millisecond
|
||||||
|
}
|
||||||
|
|
||||||
// Debug/test settings:
|
// Debug/test settings:
|
||||||
if cfg.Log == nil {
|
if cfg.Log == nil {
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ func (tr *tableRevalidation) nodeEndpointChanged(tab *Table, n *tableNode) {
|
||||||
func (tr *tableRevalidation) run(tab *Table, now mclock.AbsTime) (nextTime mclock.AbsTime) {
|
func (tr *tableRevalidation) run(tab *Table, now mclock.AbsTime) (nextTime mclock.AbsTime) {
|
||||||
reval := func(list *revalidationList) {
|
reval := func(list *revalidationList) {
|
||||||
if list.nextTime <= now {
|
if list.nextTime <= now {
|
||||||
if n := list.get(now, &tab.rand, tr.activeReq); n != nil {
|
if n := list.get(&tab.rand, tr.activeReq); n != nil {
|
||||||
tr.startRequest(tab, n)
|
tr.startRequest(tab, n)
|
||||||
}
|
}
|
||||||
// Update nextTime regardless if any requests were started because
|
// Update nextTime regardless if any requests were started because
|
||||||
|
|
@ -203,7 +203,7 @@ type revalidationList struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// get returns a random node from the queue. Nodes in the 'exclude' map are not returned.
|
// get returns a random node from the queue. Nodes in the 'exclude' map are not returned.
|
||||||
func (list *revalidationList) get(now mclock.AbsTime, rand randomSource, exclude map[enode.ID]struct{}) *tableNode {
|
func (list *revalidationList) get(rand randomSource, exclude map[enode.ID]struct{}) *tableNode {
|
||||||
if len(list.nodes) == 0 {
|
if len(list.nodes) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,6 @@ const (
|
||||||
lookupRequestLimit = 3 // max requests against a single node during lookup
|
lookupRequestLimit = 3 // max requests against a single node during lookup
|
||||||
findnodeResultLimit = 16 // applies in FINDNODE handler
|
findnodeResultLimit = 16 // applies in FINDNODE handler
|
||||||
totalNodesResponseLimit = 5 // applies in waitForNodes
|
totalNodesResponseLimit = 5 // applies in waitForNodes
|
||||||
|
|
||||||
respTimeoutV5 = 700 * time.Millisecond
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// codecV5 is implemented by v5wire.Codec (and testCodec).
|
// codecV5 is implemented by v5wire.Codec (and testCodec).
|
||||||
|
|
@ -71,6 +69,7 @@ type UDPv5 struct {
|
||||||
log log.Logger
|
log log.Logger
|
||||||
clock mclock.Clock
|
clock mclock.Clock
|
||||||
validSchemes enr.IdentityScheme
|
validSchemes enr.IdentityScheme
|
||||||
|
respTimeout time.Duration
|
||||||
|
|
||||||
// misc buffers used during message handling
|
// misc buffers used during message handling
|
||||||
logcontext []interface{}
|
logcontext []interface{}
|
||||||
|
|
@ -158,6 +157,7 @@ func newUDPv5(conn UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv5, error) {
|
||||||
log: cfg.Log,
|
log: cfg.Log,
|
||||||
validSchemes: cfg.ValidSchemes,
|
validSchemes: cfg.ValidSchemes,
|
||||||
clock: cfg.Clock,
|
clock: cfg.Clock,
|
||||||
|
respTimeout: cfg.V5RespTimeout,
|
||||||
// channels into dispatch
|
// channels into dispatch
|
||||||
packetInCh: make(chan ReadPacket, 1),
|
packetInCh: make(chan ReadPacket, 1),
|
||||||
readNextCh: make(chan struct{}, 1),
|
readNextCh: make(chan struct{}, 1),
|
||||||
|
|
@ -576,7 +576,7 @@ func (t *UDPv5) startResponseTimeout(c *callV5) {
|
||||||
timer mclock.Timer
|
timer mclock.Timer
|
||||||
done = make(chan struct{})
|
done = make(chan struct{})
|
||||||
)
|
)
|
||||||
timer = t.clock.AfterFunc(respTimeoutV5, func() {
|
timer = t.clock.AfterFunc(t.respTimeout, func() {
|
||||||
<-done
|
<-done
|
||||||
select {
|
select {
|
||||||
case t.respTimeoutCh <- &callTimeout{c, timer}:
|
case t.respTimeoutCh <- &callTimeout{c, timer}:
|
||||||
|
|
|
||||||
|
|
@ -87,9 +87,11 @@ var (
|
||||||
MergeNetsplitBlock: nil,
|
MergeNetsplitBlock: nil,
|
||||||
ShanghaiTime: newUint64(1696000704),
|
ShanghaiTime: newUint64(1696000704),
|
||||||
CancunTime: newUint64(1707305664),
|
CancunTime: newUint64(1707305664),
|
||||||
|
PragueTime: newUint64(1740434112),
|
||||||
Ethash: new(EthashConfig),
|
Ethash: new(EthashConfig),
|
||||||
BlobScheduleConfig: &BlobScheduleConfig{
|
BlobScheduleConfig: &BlobScheduleConfig{
|
||||||
Cancun: DefaultCancunBlobConfig,
|
Cancun: DefaultCancunBlobConfig,
|
||||||
|
Prague: DefaultPragueBlobConfig,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
// SepoliaChainConfig contains the chain parameters to run a node on the Sepolia test network.
|
// SepoliaChainConfig contains the chain parameters to run a node on the Sepolia test network.
|
||||||
|
|
@ -114,9 +116,11 @@ var (
|
||||||
MergeNetsplitBlock: big.NewInt(1735371),
|
MergeNetsplitBlock: big.NewInt(1735371),
|
||||||
ShanghaiTime: newUint64(1677557088),
|
ShanghaiTime: newUint64(1677557088),
|
||||||
CancunTime: newUint64(1706655072),
|
CancunTime: newUint64(1706655072),
|
||||||
|
PragueTime: newUint64(1741159776),
|
||||||
Ethash: new(EthashConfig),
|
Ethash: new(EthashConfig),
|
||||||
BlobScheduleConfig: &BlobScheduleConfig{
|
BlobScheduleConfig: &BlobScheduleConfig{
|
||||||
Cancun: DefaultCancunBlobConfig,
|
Cancun: DefaultCancunBlobConfig,
|
||||||
|
Prague: DefaultPragueBlobConfig,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
|
// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
|
||||||
|
|
|
||||||
|
|
@ -275,6 +275,7 @@ func (t *StateTrie) Copy() *StateTrie {
|
||||||
trie: *t.trie.Copy(),
|
trie: *t.trie.Copy(),
|
||||||
db: t.db,
|
db: t.db,
|
||||||
secKeyCache: t.secKeyCache,
|
secKeyCache: t.secKeyCache,
|
||||||
|
preimages: t.preimages,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue