mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-25 04:57:17 +00:00
txpool changes for eip-3860 (#820)
shanghai changes to txpool. intrinsic gas updated to match the new version in Erigon. unsure if the `isShanghai` check is robust enough or there would be a better way to approach this.
This commit is contained in:
parent
61706714c3
commit
8969b9c58f
@ -154,4 +154,8 @@ const (
|
||||
// up to half the consumed gas could be refunded. Redefined as 1/5th in EIP-3529
|
||||
RefundQuotient uint64 = 2
|
||||
RefundQuotientEIP3529 uint64 = 5
|
||||
|
||||
// EIP-3860 to limit size of initcode
|
||||
MaxInitCodeSize = 2 * MaxCodeSize // Maximum initcode to permit in a creation transaction and create instructions
|
||||
InitCodeWordGas = 2
|
||||
)
|
||||
|
17
common/math/integer.go
Normal file
17
common/math/integer.go
Normal file
@ -0,0 +1,17 @@
|
||||
package math
|
||||
|
||||
import (
|
||||
"math/bits"
|
||||
)
|
||||
|
||||
// SafeMul returns x*y and checks for overflow.
|
||||
func SafeMul(x, y uint64) (uint64, bool) {
|
||||
hi, lo := bits.Mul64(x, y)
|
||||
return lo, hi != 0
|
||||
}
|
||||
|
||||
// SafeAdd returns x+y and checks for overflow.
|
||||
func SafeAdd(x, y uint64) (uint64, bool) {
|
||||
sum, carryOut := bits.Add64(x, y, 0)
|
||||
return sum, carryOut != 0
|
||||
}
|
115
txpool/pool.go
115
txpool/pool.go
@ -25,6 +25,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"runtime"
|
||||
"sort"
|
||||
"sync"
|
||||
@ -44,6 +45,7 @@ import (
|
||||
"github.com/ledgerwatch/erigon-lib/common/cmp"
|
||||
"github.com/ledgerwatch/erigon-lib/common/dbg"
|
||||
"github.com/ledgerwatch/erigon-lib/common/fixedgas"
|
||||
emath "github.com/ledgerwatch/erigon-lib/common/math"
|
||||
"github.com/ledgerwatch/erigon-lib/common/u256"
|
||||
"github.com/ledgerwatch/erigon-lib/gointerfaces"
|
||||
"github.com/ledgerwatch/erigon-lib/gointerfaces/grpcutil"
|
||||
@ -83,6 +85,7 @@ type Config struct {
|
||||
MinFeeCap uint64
|
||||
AccountSlots uint64 // Number of executable transaction slots guaranteed per account
|
||||
PriceBump uint64 // Price bump percentage to replace an already existing transaction
|
||||
OverrideShanghaiTime *big.Int
|
||||
}
|
||||
|
||||
var DefaultConfig = Config{
|
||||
@ -95,9 +98,10 @@ var DefaultConfig = Config{
|
||||
BaseFeeSubPoolLimit: 10_000,
|
||||
QueuedSubPoolLimit: 10_000,
|
||||
|
||||
MinFeeCap: 1,
|
||||
AccountSlots: 16, //TODO: to choose right value (16 to be compatible with Geth)
|
||||
PriceBump: 10, // Price bump percentage to replace an already existing transaction
|
||||
MinFeeCap: 1,
|
||||
AccountSlots: 16, //TODO: to choose right value (16 to be compatible with Geth)
|
||||
PriceBump: 10, // Price bump percentage to replace an already existing transaction
|
||||
OverrideShanghaiTime: nil,
|
||||
}
|
||||
|
||||
// Pool is interface for the transaction pool
|
||||
@ -166,6 +170,7 @@ const (
|
||||
InsufficientFunds DiscardReason = 19
|
||||
NotReplaced DiscardReason = 20 // There was an existing transaction with the same sender and nonce, not enough price bump to replace
|
||||
DuplicateHash DiscardReason = 21 // There was an existing transaction with the same hash
|
||||
InitCodeTooLarge DiscardReason = 22 // EIP-3860 - transaction init code is too large
|
||||
)
|
||||
|
||||
func (r DiscardReason) String() string {
|
||||
@ -214,6 +219,8 @@ func (r DiscardReason) String() string {
|
||||
return "could not replace existing tx"
|
||||
case DuplicateHash:
|
||||
return "existing tx with same hash"
|
||||
case InitCodeTooLarge:
|
||||
return "initcode too large"
|
||||
default:
|
||||
panic(fmt.Sprintf("discard reason: %d", r))
|
||||
}
|
||||
@ -320,9 +327,11 @@ type TxPool struct {
|
||||
started atomic.Bool
|
||||
pendingBaseFee atomic.Uint64
|
||||
blockGasLimit atomic.Uint64
|
||||
shanghaiTime *big.Int
|
||||
isPostShanghai atomic.Bool
|
||||
}
|
||||
|
||||
func New(newTxs chan types.Hashes, coreDB kv.RoDB, cfg Config, cache kvcache.Cache, chainID uint256.Int) (*TxPool, error) {
|
||||
func New(newTxs chan types.Hashes, coreDB kv.RoDB, cfg Config, cache kvcache.Cache, chainID uint256.Int, shanghaiTime *big.Int) (*TxPool, error) {
|
||||
localsHistory, err := simplelru.NewLRU(10_000, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -360,6 +369,7 @@ func New(newTxs chan types.Hashes, coreDB kv.RoDB, cfg Config, cache kvcache.Cac
|
||||
unprocessedRemoteTxs: &types.TxSlots{},
|
||||
unprocessedRemoteByHash: map[string]int{},
|
||||
promoted: make(types.Hashes, 0, 32*1024),
|
||||
shanghaiTime: shanghaiTime,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -608,6 +618,8 @@ func (p *TxPool) best(n uint16, txs *types.TxsRlp, tx kv.Tx, onTopOf, availableG
|
||||
return false, 0, nil // Too early
|
||||
}
|
||||
|
||||
isShanghai := p.isShanghai()
|
||||
|
||||
txs.Resize(uint(cmp.Min(int(n), len(p.pending.best.ms))))
|
||||
var toRemove []*metaTx
|
||||
count := 0
|
||||
@ -645,7 +657,7 @@ func (p *TxPool) best(n uint16, txs *types.TxsRlp, tx kv.Tx, onTopOf, availableG
|
||||
// make sure we have enough gas in the caller to add this transaction.
|
||||
// not an exact science using intrinsic gas but as close as we could hope for at
|
||||
// this stage
|
||||
intrinsicGas, _ := CalcIntrinsicGas(uint64(mt.Tx.DataLen), uint64(mt.Tx.DataNonZeroLen), nil, mt.Tx.Creation, true, true)
|
||||
intrinsicGas, _ := CalcIntrinsicGas(uint64(mt.Tx.DataLen), uint64(mt.Tx.DataNonZeroLen), nil, mt.Tx.Creation, true, true, isShanghai)
|
||||
if intrinsicGas > availableGas {
|
||||
// we might find another TX with a low enough intrinsic gas to include so carry on
|
||||
continue
|
||||
@ -712,6 +724,13 @@ func (p *TxPool) AddRemoteTxs(_ context.Context, newTxs types.TxSlots) {
|
||||
}
|
||||
|
||||
func (p *TxPool) validateTx(txn *types.TxSlot, isLocal bool, stateCache kvcache.CacheView) DiscardReason {
|
||||
isShanghai := p.isShanghai()
|
||||
if isShanghai {
|
||||
if txn.DataLen > fixedgas.MaxInitCodeSize {
|
||||
return InitCodeTooLarge
|
||||
}
|
||||
}
|
||||
|
||||
// Drop non-local transactions under our own minimal accepted gas price or tip
|
||||
if !isLocal && uint256.NewInt(p.cfg.MinFeeCap).Cmp(&txn.FeeCap) == 1 {
|
||||
if txn.Traced {
|
||||
@ -719,7 +738,7 @@ func (p *TxPool) validateTx(txn *types.TxSlot, isLocal bool, stateCache kvcache.
|
||||
}
|
||||
return UnderPriced
|
||||
}
|
||||
gas, reason := CalcIntrinsicGas(uint64(txn.DataLen), uint64(txn.DataNonZeroLen), nil, txn.Creation, true, true)
|
||||
gas, reason := CalcIntrinsicGas(uint64(txn.DataLen), uint64(txn.DataNonZeroLen), nil, txn.Creation, true, true, isShanghai)
|
||||
if txn.Traced {
|
||||
log.Info(fmt.Sprintf("TX TRACING: validateTx intrinsic gas idHash=%x gas=%d", txn.IDHash, gas))
|
||||
}
|
||||
@ -763,6 +782,31 @@ func (p *TxPool) validateTx(txn *types.TxSlot, isLocal bool, stateCache kvcache.
|
||||
return Success
|
||||
}
|
||||
|
||||
func (p *TxPool) isShanghai() bool {
|
||||
// once this flag has been set for the first time we no longer need to check the timestamp
|
||||
set := p.isPostShanghai.Load()
|
||||
if set {
|
||||
return true
|
||||
}
|
||||
if p.shanghaiTime == nil {
|
||||
return false
|
||||
}
|
||||
shanghaiTime := p.shanghaiTime.Uint64()
|
||||
|
||||
// a zero here means shanghai is always active
|
||||
if shanghaiTime == 0 {
|
||||
p.isPostShanghai.Swap(true)
|
||||
return true
|
||||
}
|
||||
|
||||
now := big.NewInt(time.Now().Unix())
|
||||
is := now.Uint64() >= shanghaiTime
|
||||
if is {
|
||||
p.isPostShanghai.Swap(true)
|
||||
}
|
||||
return is
|
||||
}
|
||||
|
||||
func (p *TxPool) ValidateSerializedTxn(serializedTxn []byte) error {
|
||||
const (
|
||||
// txSlotSize is used to calculate how many data slots a single transaction
|
||||
@ -1805,7 +1849,7 @@ func (p *TxPool) deprecatedForEach(_ context.Context, f func(rlp, sender []byte,
|
||||
}
|
||||
|
||||
// CalcIntrinsicGas computes the 'intrinsic gas' for a message with the given data.
|
||||
func CalcIntrinsicGas(dataLen, dataNonZeroLen uint64, accessList types.AccessList, isContractCreation, isHomestead, isEIP2028 bool) (uint64, DiscardReason) {
|
||||
func CalcIntrinsicGas(dataLen, dataNonZeroLen uint64, accessList types.AccessList, isContractCreation, isHomestead, isEIP2028, isShanghai bool) (uint64, DiscardReason) {
|
||||
// Set the starting gas for the raw transaction
|
||||
var gas uint64
|
||||
if isContractCreation && isHomestead {
|
||||
@ -1822,24 +1866,69 @@ func CalcIntrinsicGas(dataLen, dataNonZeroLen uint64, accessList types.AccessLis
|
||||
if isEIP2028 {
|
||||
nonZeroGas = fixedgas.TxDataNonZeroGasEIP2028
|
||||
}
|
||||
if (math.MaxUint64-gas)/nonZeroGas < nz {
|
||||
|
||||
product, overflow := emath.SafeMul(nz, nonZeroGas)
|
||||
if overflow {
|
||||
return 0, GasUintOverflow
|
||||
}
|
||||
gas, overflow = emath.SafeAdd(gas, product)
|
||||
if overflow {
|
||||
return 0, GasUintOverflow
|
||||
}
|
||||
gas += nz * nonZeroGas
|
||||
|
||||
z := dataLen - nz
|
||||
if (math.MaxUint64-gas)/fixedgas.TxDataZeroGas < z {
|
||||
|
||||
product, overflow = emath.SafeMul(z, fixedgas.TxDataZeroGas)
|
||||
if overflow {
|
||||
return 0, GasUintOverflow
|
||||
}
|
||||
gas += z * fixedgas.TxDataZeroGas
|
||||
gas, overflow = emath.SafeAdd(gas, product)
|
||||
if overflow {
|
||||
return 0, GasUintOverflow
|
||||
}
|
||||
|
||||
if isContractCreation && isShanghai {
|
||||
numWords := toWordSize(dataLen)
|
||||
product, overflow = emath.SafeMul(numWords, fixedgas.InitCodeWordGas)
|
||||
if overflow {
|
||||
return 0, GasUintOverflow
|
||||
}
|
||||
gas, overflow = emath.SafeAdd(gas, product)
|
||||
if overflow {
|
||||
return 0, GasUintOverflow
|
||||
}
|
||||
}
|
||||
}
|
||||
if accessList != nil {
|
||||
gas += uint64(len(accessList)) * fixedgas.TxAccessListAddressGas
|
||||
gas += uint64(accessList.StorageKeys()) * fixedgas.TxAccessListStorageKeyGas
|
||||
product, overflow := emath.SafeMul(uint64(len(accessList)), fixedgas.TxAccessListAddressGas)
|
||||
if overflow {
|
||||
return 0, GasUintOverflow
|
||||
}
|
||||
gas, overflow = emath.SafeAdd(gas, product)
|
||||
if overflow {
|
||||
return 0, GasUintOverflow
|
||||
}
|
||||
|
||||
product, overflow = emath.SafeMul(uint64(accessList.StorageKeys()), fixedgas.TxAccessListStorageKeyGas)
|
||||
if overflow {
|
||||
return 0, GasUintOverflow
|
||||
}
|
||||
gas, overflow = emath.SafeAdd(gas, product)
|
||||
if overflow {
|
||||
return 0, GasUintOverflow
|
||||
}
|
||||
}
|
||||
return gas, Success
|
||||
}
|
||||
|
||||
// toWordSize returns the ceiled word size required for memory expansion.
|
||||
func toWordSize(size uint64) uint64 {
|
||||
if size > math.MaxUint64-31 {
|
||||
return math.MaxUint64/32 + 1
|
||||
}
|
||||
return (size + 31) / 32
|
||||
}
|
||||
|
||||
var PoolChainConfigKey = []byte("chain_config")
|
||||
var PoolLastSeenBlockKey = []byte("last_seen_block")
|
||||
var PoolPendingBaseFeeKey = []byte("pending_base_fee")
|
||||
|
@ -9,6 +9,10 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/common/u256"
|
||||
"github.com/ledgerwatch/erigon-lib/gointerfaces"
|
||||
"github.com/ledgerwatch/erigon-lib/gointerfaces/remote"
|
||||
@ -17,9 +21,6 @@ import (
|
||||
"github.com/ledgerwatch/erigon-lib/kv/memdb"
|
||||
"github.com/ledgerwatch/erigon-lib/rlp"
|
||||
"github.com/ledgerwatch/erigon-lib/types"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// https://go.dev/doc/fuzz/
|
||||
@ -310,7 +311,7 @@ func FuzzOnNewBlocks(f *testing.F) {
|
||||
|
||||
cfg := DefaultConfig
|
||||
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
||||
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1)
|
||||
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, nil)
|
||||
assert.NoError(err)
|
||||
pool.senders.senderIDs = senderIDs
|
||||
for addr, id := range senderIDs {
|
||||
@ -542,7 +543,7 @@ func FuzzOnNewBlocks(f *testing.F) {
|
||||
check(p2pReceived, types.TxSlots{}, "after_flush")
|
||||
checkNotify(p2pReceived, types.TxSlots{}, "after_flush")
|
||||
|
||||
p2, err := New(ch, coreDB, DefaultConfig, sendersCache, *u256.N1)
|
||||
p2, err := New(ch, coreDB, DefaultConfig, sendersCache, *u256.N1, nil)
|
||||
assert.NoError(err)
|
||||
p2.senders = pool.senders // senders are not persisted
|
||||
err = coreDB.View(ctx, func(coreTx kv.Tx) error { return p2.fromDB(ctx, tx, coreTx) })
|
||||
|
@ -21,6 +21,8 @@ import (
|
||||
"container/heap"
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"testing"
|
||||
|
||||
@ -30,9 +32,11 @@ import (
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/common"
|
||||
"github.com/ledgerwatch/erigon-lib/common/cmp"
|
||||
"github.com/ledgerwatch/erigon-lib/common/fixedgas"
|
||||
"github.com/ledgerwatch/erigon-lib/common/u256"
|
||||
"github.com/ledgerwatch/erigon-lib/gointerfaces"
|
||||
"github.com/ledgerwatch/erigon-lib/gointerfaces/remote"
|
||||
"github.com/ledgerwatch/erigon-lib/kv"
|
||||
"github.com/ledgerwatch/erigon-lib/kv/kvcache"
|
||||
"github.com/ledgerwatch/erigon-lib/kv/memdb"
|
||||
"github.com/ledgerwatch/erigon-lib/types"
|
||||
@ -94,7 +98,7 @@ func TestNonceFromAddress(t *testing.T) {
|
||||
|
||||
cfg := DefaultConfig
|
||||
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
||||
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1)
|
||||
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, nil)
|
||||
assert.NoError(err)
|
||||
require.True(pool != nil)
|
||||
ctx := context.Background()
|
||||
@ -214,7 +218,7 @@ func TestReplaceWithHigherFee(t *testing.T) {
|
||||
|
||||
cfg := DefaultConfig
|
||||
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
||||
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1)
|
||||
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, nil)
|
||||
assert.NoError(err)
|
||||
require.True(pool != nil)
|
||||
ctx := context.Background()
|
||||
@ -331,7 +335,7 @@ func TestReverseNonces(t *testing.T) {
|
||||
|
||||
cfg := DefaultConfig
|
||||
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
||||
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1)
|
||||
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, nil)
|
||||
assert.NoError(err)
|
||||
require.True(pool != nil)
|
||||
ctx := context.Background()
|
||||
@ -455,7 +459,7 @@ func TestTxPoke(t *testing.T) {
|
||||
|
||||
cfg := DefaultConfig
|
||||
sendersCache := kvcache.New(kvcache.DefaultCoherentConfig)
|
||||
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1)
|
||||
pool, err := New(ch, coreDB, cfg, sendersCache, *u256.N1, nil)
|
||||
assert.NoError(err)
|
||||
require.True(pool != nil)
|
||||
ctx := context.Background()
|
||||
@ -618,3 +622,141 @@ func TestTxPoke(t *testing.T) {
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
func TestShanghaiIntrinsicGas(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
expected uint64
|
||||
dataLen uint64
|
||||
dataNonZeroLen uint64
|
||||
creation bool
|
||||
isShanghai bool
|
||||
}{
|
||||
"simple no data": {
|
||||
expected: 21000,
|
||||
dataLen: 0,
|
||||
dataNonZeroLen: 0,
|
||||
creation: false,
|
||||
isShanghai: false,
|
||||
},
|
||||
"simple with data": {
|
||||
expected: 21512,
|
||||
dataLen: 32,
|
||||
dataNonZeroLen: 32,
|
||||
creation: false,
|
||||
isShanghai: false,
|
||||
},
|
||||
"creation with data no shanghai": {
|
||||
expected: 53512,
|
||||
dataLen: 32,
|
||||
dataNonZeroLen: 32,
|
||||
creation: true,
|
||||
isShanghai: false,
|
||||
},
|
||||
"creation with single word and shanghai": {
|
||||
expected: 53514, // additional gas for single word
|
||||
dataLen: 32,
|
||||
dataNonZeroLen: 32,
|
||||
creation: true,
|
||||
isShanghai: true,
|
||||
},
|
||||
"creation between word 1 and 2 and shanghai": {
|
||||
expected: 53532, // additional gas for going into 2nd word although not filling it
|
||||
dataLen: 33,
|
||||
dataNonZeroLen: 33,
|
||||
creation: true,
|
||||
isShanghai: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, c := range cases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
gas, reason := CalcIntrinsicGas(c.dataLen, c.dataNonZeroLen, nil, c.creation, true, true, c.isShanghai)
|
||||
if reason != Success {
|
||||
t.Errorf("expected success but got reason %v", reason)
|
||||
}
|
||||
if gas != c.expected {
|
||||
t.Errorf("expected %v but got %v", c.expected, gas)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestShanghaiValidateTx(t *testing.T) {
|
||||
asrt := assert.New(t)
|
||||
tests := map[string]struct {
|
||||
expected DiscardReason
|
||||
dataLen int
|
||||
isShanghai bool
|
||||
}{
|
||||
"no shanghai": {
|
||||
expected: Success,
|
||||
dataLen: 32,
|
||||
isShanghai: false,
|
||||
},
|
||||
"shanghai within bounds": {
|
||||
expected: Success,
|
||||
dataLen: 32,
|
||||
isShanghai: true,
|
||||
},
|
||||
"shanghai exactly on bound": {
|
||||
expected: Success,
|
||||
dataLen: fixedgas.MaxInitCodeSize,
|
||||
isShanghai: true,
|
||||
},
|
||||
"shanghai one over bound": {
|
||||
expected: InitCodeTooLarge,
|
||||
dataLen: fixedgas.MaxInitCodeSize + 1,
|
||||
isShanghai: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
ch := make(chan types.Hashes, 100)
|
||||
_, coreDB := memdb.NewTestPoolDB(t), memdb.NewTestDB(t)
|
||||
cfg := DefaultConfig
|
||||
|
||||
var shanghaiTime *big.Int
|
||||
if test.isShanghai {
|
||||
shanghaiTime = big.NewInt(0)
|
||||
}
|
||||
|
||||
cache := &kvcache.DummyCache{}
|
||||
pool, err := New(ch, coreDB, cfg, cache, *u256.N1, shanghaiTime)
|
||||
asrt.NoError(err)
|
||||
ctx := context.Background()
|
||||
tx, err := coreDB.BeginRw(ctx)
|
||||
defer tx.Rollback()
|
||||
asrt.NoError(err)
|
||||
|
||||
sndr := sender{nonce: 0, balance: *uint256.NewInt(math.MaxUint64)}
|
||||
sndrBytes := make([]byte, types.EncodeSenderLengthForStorage(sndr.nonce, sndr.balance))
|
||||
types.EncodeSender(sndr.nonce, sndr.balance, sndrBytes)
|
||||
err = tx.Put(kv.PlainState, []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, sndrBytes)
|
||||
asrt.NoError(err)
|
||||
|
||||
txn := &types.TxSlot{
|
||||
DataLen: test.dataLen,
|
||||
FeeCap: *uint256.NewInt(21000),
|
||||
Gas: 500000,
|
||||
SenderID: 0,
|
||||
Creation: true,
|
||||
}
|
||||
|
||||
txns := types.TxSlots{
|
||||
Txs: append([]*types.TxSlot{}, txn),
|
||||
Senders: types.Addresses{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
}
|
||||
err = pool.senders.registerNewSenders(&txns)
|
||||
asrt.NoError(err)
|
||||
view, err := cache.View(ctx, tx)
|
||||
asrt.NoError(err)
|
||||
|
||||
reason := pool.validateTx(txn, false, view)
|
||||
|
||||
if reason != test.expected {
|
||||
t.Errorf("expected %v, got %v", test.expected, reason)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -240,7 +240,7 @@ func mapDiscardReasonToProto(reason DiscardReason) txpool_proto.ImportResult {
|
||||
return txpool_proto.ImportResult_ALREADY_EXISTS
|
||||
case UnderPriced, ReplaceUnderpriced, FeeTooLow:
|
||||
return txpool_proto.ImportResult_FEE_TOO_LOW
|
||||
case InvalidSender, NegativeValue, OversizedData:
|
||||
case InvalidSender, NegativeValue, OversizedData, InitCodeTooLarge:
|
||||
return txpool_proto.ImportResult_INVALID
|
||||
default:
|
||||
return txpool_proto.ImportResult_INTERNAL_ERROR
|
||||
|
@ -23,6 +23,9 @@ import (
|
||||
|
||||
"github.com/c2h5oh/datasize"
|
||||
"github.com/holiman/uint256"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
mdbx2 "github.com/torquem-ch/mdbx-go/mdbx"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/chain"
|
||||
"github.com/ledgerwatch/erigon-lib/direct"
|
||||
"github.com/ledgerwatch/erigon-lib/kv"
|
||||
@ -30,8 +33,6 @@ import (
|
||||
"github.com/ledgerwatch/erigon-lib/kv/mdbx"
|
||||
"github.com/ledgerwatch/erigon-lib/txpool"
|
||||
"github.com/ledgerwatch/erigon-lib/types"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
mdbx2 "github.com/torquem-ch/mdbx-go/mdbx"
|
||||
)
|
||||
|
||||
func SaveChainConfigIfNeed(ctx context.Context, coreDB kv.RoDB, txPoolDB kv.RwDB, force bool) (cc *chain.Config, blockNum uint64, err error) {
|
||||
@ -115,7 +116,13 @@ func AllComponents(ctx context.Context, cfg txpool.Config, cache kvcache.Cache,
|
||||
}
|
||||
|
||||
chainID, _ := uint256.FromBig(chainConfig.ChainID)
|
||||
txPool, err := txpool.New(newTxs, chainDB, cfg, cache, *chainID)
|
||||
|
||||
shanghaiTime := chainConfig.ShanghaiTime
|
||||
if cfg.OverrideShanghaiTime != nil {
|
||||
shanghaiTime = cfg.OverrideShanghaiTime
|
||||
}
|
||||
|
||||
txPool, err := txpool.New(newTxs, chainDB, cfg, cache, *chainID, shanghaiTime)
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, nil, err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user