mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 21:31:37 +00:00
Switch LazyTransaction gas caps from *big.Int to *uint256.Int and convert once at pending retrieval time. In miner ordering, keep fee comparisons on uint256 and precompute TRC21 gas price in uint256 form to avoid repeated big-int conversions in heap comparisons. Also update affected tests and call sites in legacypool/worker/helper paths. Compatibility: LazyTransaction exported field types changed (GasFeeCap/GasTipCap).
This commit is contained in:
parent
b5eec529d0
commit
8850835f6b
7 changed files with 45 additions and 35 deletions
|
|
@ -618,8 +618,8 @@ func (pool *LegacyPool) Pending(minTip *uint256.Int, baseFee *uint256.Int) map[c
|
|||
Hash: txs[i].Hash(),
|
||||
Tx: txs[i],
|
||||
Time: txs[i].Time(),
|
||||
GasFeeCap: txs[i].GasFeeCap(),
|
||||
GasTipCap: txs[i].GasTipCap(),
|
||||
GasFeeCap: uint256.MustFromBig(txs[i].GasFeeCap()),
|
||||
GasTipCap: uint256.MustFromBig(txs[i].GasTipCap()),
|
||||
Gas: txs[i].Gas(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ type LazyTransaction struct {
|
|||
Hash common.Hash // Transaction hash to pull up if needed
|
||||
Tx *types.Transaction // Transaction if already resolved
|
||||
|
||||
Time time.Time // Time when the transaction was first seen
|
||||
GasFeeCap *big.Int // Maximum fee per gas the transaction may consume
|
||||
GasTipCap *big.Int // Maximum miner tip per gas the transaction can pay
|
||||
Time time.Time // Time when the transaction was first seen
|
||||
GasFeeCap *uint256.Int // Maximum fee per gas the transaction may consume
|
||||
GasTipCap *uint256.Int // Maximum miner tip per gas the transaction can pay
|
||||
|
||||
Gas uint64 // Amount of gas required by the transaction
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,8 +166,8 @@ func (p *testTxPool) Pending(minTip *uint256.Int, baseFee *uint256.Int) map[comm
|
|||
Hash: tx.Hash(),
|
||||
Tx: tx,
|
||||
Time: tx.Time(),
|
||||
GasFeeCap: tx.GasFeeCap(),
|
||||
GasTipCap: tx.GasTipCap(),
|
||||
GasFeeCap: uint256.MustFromBig(tx.GasFeeCap()),
|
||||
GasTipCap: uint256.MustFromBig(tx.GasTipCap()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,27 +23,30 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/txpool"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
var trc21GasPriceUint = uint256.MustFromBig(common.TRC21GasPrice)
|
||||
|
||||
// txWithMinerFee wraps a transaction with its gas price or effective miner gasTipCap
|
||||
type txWithMinerFee struct {
|
||||
tx *txpool.LazyTransaction
|
||||
from common.Address
|
||||
fees *big.Int
|
||||
fees *uint256.Int
|
||||
}
|
||||
|
||||
// newTxWithMinerFee creates a wrapped transaction, calculating the effective
|
||||
// miner gasTipCap if a base fee is provided.
|
||||
// Returns error in case of a negative effective miner gasTipCap.
|
||||
func newTxWithMinerFee(tx *txpool.LazyTransaction, from common.Address, baseFee *big.Int) (*txWithMinerFee, error) {
|
||||
tip := new(big.Int).Set(tx.GasTipCap)
|
||||
func newTxWithMinerFee(tx *txpool.LazyTransaction, from common.Address, baseFee *uint256.Int) (*txWithMinerFee, error) {
|
||||
tip := new(uint256.Int).Set(tx.GasTipCap)
|
||||
if baseFee != nil {
|
||||
if tx.GasFeeCap.Cmp(baseFee) < 0 {
|
||||
return nil, types.ErrGasFeeCapTooLow
|
||||
}
|
||||
effectiveTip := new(big.Int).Sub(tx.GasFeeCap, baseFee)
|
||||
if tip.Cmp(effectiveTip) > 0 {
|
||||
tip = effectiveTip
|
||||
tip = new(uint256.Int).Sub(tx.GasFeeCap, baseFee)
|
||||
if tip.Gt(tx.GasTipCap) {
|
||||
tip = tx.GasTipCap
|
||||
}
|
||||
}
|
||||
return &txWithMinerFee{
|
||||
|
|
@ -68,14 +71,14 @@ func (s txByPriceAndTime) Less(i, j int) bool {
|
|||
i_price := s.txs[i].fees
|
||||
if tx := s.txs[i].tx.Resolve(); tx != nil && tx.To() != nil {
|
||||
if _, ok := s.payersSwap[*tx.To()]; ok {
|
||||
i_price = common.TRC21GasPrice
|
||||
i_price = trc21GasPriceUint
|
||||
}
|
||||
}
|
||||
|
||||
j_price := s.txs[j].fees
|
||||
if tx := s.txs[j].tx.Resolve(); tx != nil && tx.To() != nil {
|
||||
if _, ok := s.payersSwap[*tx.To()]; ok {
|
||||
j_price = common.TRC21GasPrice
|
||||
j_price = trc21GasPriceUint
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -112,7 +115,7 @@ type transactionsByPriceAndNonce struct {
|
|||
txs map[common.Address][]*txpool.LazyTransaction // Per account nonce-sorted list of transactions
|
||||
heads txByPriceAndTime // Next transaction for each unique account (price heap)
|
||||
signer types.Signer // Signer for the set of transactions
|
||||
baseFee *big.Int // Current base fee
|
||||
baseFee *uint256.Int // Current base fee
|
||||
}
|
||||
|
||||
// newTransactionsByPriceAndNonce creates a transaction set that can retrieve
|
||||
|
|
@ -121,6 +124,11 @@ type transactionsByPriceAndNonce struct {
|
|||
// Note, the input map is reowned so the caller should not interact any more with
|
||||
// if after providing it to the constructor.
|
||||
func newTransactionsByPriceAndNonce(signer types.Signer, txs map[common.Address][]*txpool.LazyTransaction, payersSwap map[common.Address]*big.Int, baseFee *big.Int) (*transactionsByPriceAndNonce, types.Transactions) {
|
||||
// Convert the basefee from header format to uint256 format
|
||||
var baseFeeUint *uint256.Int
|
||||
if baseFee != nil {
|
||||
baseFeeUint = uint256.MustFromBig(baseFee)
|
||||
}
|
||||
// Initialize a price and received time based heap with the head transactions
|
||||
heads := txByPriceAndTime{
|
||||
txs: make([]*txWithMinerFee, 0, len(txs)),
|
||||
|
|
@ -137,7 +145,7 @@ func newTransactionsByPriceAndNonce(signer types.Signer, txs map[common.Address]
|
|||
}
|
||||
}
|
||||
if len(normalTxs) > 0 {
|
||||
wrapped, err := newTxWithMinerFee(normalTxs[0], from, baseFee)
|
||||
wrapped, err := newTxWithMinerFee(normalTxs[0], from, baseFeeUint)
|
||||
if err != nil {
|
||||
delete(txs, from)
|
||||
continue
|
||||
|
|
@ -157,7 +165,7 @@ func newTransactionsByPriceAndNonce(signer types.Signer, txs map[common.Address]
|
|||
txs: txs,
|
||||
heads: heads,
|
||||
signer: signer,
|
||||
baseFee: baseFee,
|
||||
baseFee: baseFeeUint,
|
||||
}, specialTxs
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/core/txpool"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
func TestTransactionPriceNonceSortLegacy(t *testing.T) {
|
||||
|
|
@ -90,8 +91,8 @@ func testTransactionPriceNonceSort(t *testing.T, baseFee *big.Int) {
|
|||
Hash: tx.Hash(),
|
||||
Tx: tx,
|
||||
Time: tx.Time(),
|
||||
GasFeeCap: tx.GasFeeCap(),
|
||||
GasTipCap: tx.GasTipCap(),
|
||||
GasFeeCap: uint256.MustFromBig(tx.GasFeeCap()),
|
||||
GasTipCap: uint256.MustFromBig(tx.GasTipCap()),
|
||||
})
|
||||
}
|
||||
expectedCount += count
|
||||
|
|
@ -155,8 +156,8 @@ func TestTransactionTimeSort(t *testing.T) {
|
|||
Hash: tx.Hash(),
|
||||
Tx: tx,
|
||||
Time: tx.Time(),
|
||||
GasFeeCap: tx.GasFeeCap(),
|
||||
GasTipCap: tx.GasTipCap(),
|
||||
GasFeeCap: uint256.MustFromBig(tx.GasFeeCap()),
|
||||
GasTipCap: uint256.MustFromBig(tx.GasTipCap()),
|
||||
})
|
||||
}
|
||||
// Sort the transactions and cross check the nonce ordering
|
||||
|
|
@ -193,11 +194,11 @@ func TestNewTransactionsByPriceAndNonce_SpecialSeparation(t *testing.T) {
|
|||
|
||||
genNormalTx := func(nonce uint64, key *ecdsa.PrivateKey) *txpool.LazyTransaction {
|
||||
tx, _ := types.SignTx(types.NewTransaction(nonce, common.HexToAddress("0x1234567890123456789012345678901234567890"), big.NewInt(1), 21000, big.NewInt(1), nil), signer, key)
|
||||
return &txpool.LazyTransaction{Tx: tx, Hash: tx.Hash(), Time: tx.Time(), GasFeeCap: tx.GasFeeCap(), GasTipCap: tx.GasTipCap()}
|
||||
return &txpool.LazyTransaction{Tx: tx, Hash: tx.Hash(), Time: tx.Time(), GasFeeCap: uint256.MustFromBig(tx.GasFeeCap()), GasTipCap: uint256.MustFromBig(tx.GasTipCap())}
|
||||
}
|
||||
genSpecialTx := func(nonce uint64, key *ecdsa.PrivateKey) *txpool.LazyTransaction {
|
||||
tx, _ := types.SignTx(types.NewTransaction(nonce, common.BlockSignersBinary, big.NewInt(1), 21000, big.NewInt(1), nil), signer, key)
|
||||
return &txpool.LazyTransaction{Tx: tx, Hash: tx.Hash(), Time: tx.Time(), GasFeeCap: tx.GasFeeCap(), GasTipCap: tx.GasTipCap()}
|
||||
return &txpool.LazyTransaction{Tx: tx, Hash: tx.Hash(), Time: tx.Time(), GasFeeCap: uint256.MustFromBig(tx.GasFeeCap()), GasTipCap: uint256.MustFromBig(tx.GasTipCap())}
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ type worker struct {
|
|||
mu sync.Mutex
|
||||
coinbase common.Address
|
||||
extra []byte
|
||||
tip *big.Int // Minimum tip needed for non-local transaction to include them
|
||||
tip *uint256.Int // Minimum tip needed for non-local transaction to include them
|
||||
|
||||
snapshotMu sync.RWMutex // The lock used to protect the block snapshot and state snapshot
|
||||
snapshotBlock *types.Block
|
||||
|
|
@ -176,7 +176,7 @@ func newWorker(config *Config, chainConfig *params.ChainConfig, engine consensus
|
|||
mux: mux,
|
||||
coinbase: config.Etherbase,
|
||||
extra: config.ExtraData,
|
||||
tip: config.GasPrice,
|
||||
tip: uint256.MustFromBig(config.GasPrice),
|
||||
txsCh: make(chan core.NewTxsEvent, txChanSize),
|
||||
chainHeadCh: make(chan core.ChainHeadEvent, chainHeadChanSize),
|
||||
chainSideCh: make(chan core.ChainSideEvent, chainSideChanSize),
|
||||
|
|
@ -233,7 +233,7 @@ func (w *worker) setGasTip(tip *big.Int) error {
|
|||
}
|
||||
|
||||
// Copy the value to avoid external mutation through shared pointers.
|
||||
w.tip = new(big.Int).Set(tip)
|
||||
w.tip = uint256.MustFromBig(tip)
|
||||
log.Info("Worker tip updated", "tip", w.tip)
|
||||
return nil
|
||||
}
|
||||
|
|
@ -404,8 +404,8 @@ func (w *worker) update() {
|
|||
Hash: tx.Hash(),
|
||||
Tx: tx,
|
||||
Time: tx.Time(),
|
||||
GasFeeCap: tx.GasFeeCap(),
|
||||
GasTipCap: tx.GasTipCap(),
|
||||
GasFeeCap: uint256.MustFromBig(tx.GasFeeCap()),
|
||||
GasTipCap: uint256.MustFromBig(tx.GasTipCap()),
|
||||
})
|
||||
}
|
||||
feeCapacity := w.current.state.GetTRC21FeeCapacityFromState()
|
||||
|
|
@ -866,7 +866,7 @@ func (w *worker) commitNewWork() {
|
|||
if header.BaseFee != nil {
|
||||
baseFee = uint256.MustFromBig(header.BaseFee)
|
||||
}
|
||||
pending := w.eth.TxPool().Pending(uint256.MustFromBig(w.tip), baseFee)
|
||||
pending := w.eth.TxPool().Pending(w.tip, baseFee)
|
||||
txs, specialTxs = newTransactionsByPriceAndNonce(w.current.signer, pending, feeCapacity, header.BaseFee)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/core/vm"
|
||||
"github.com/XinFinOrg/XDPoSChain/event"
|
||||
"github.com/XinFinOrg/XDPoSChain/params"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
func newBlockingSubscription() event.Subscription {
|
||||
|
|
@ -132,8 +133,8 @@ func TestWorkerCheckPreCommitXDPoSMismatch(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestWorkerSetGasTipValidation(t *testing.T) {
|
||||
w := &worker{tip: big.NewInt(1)}
|
||||
old := new(big.Int).Set(w.tip)
|
||||
w := &worker{tip: uint256.NewInt(1)}
|
||||
old := new(uint256.Int).Set(w.tip)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
@ -163,12 +164,12 @@ func TestWorkerSetGasTipCopiesValue(t *testing.T) {
|
|||
if err := w.setGasTip(input); err != nil {
|
||||
t.Fatalf("setGasTip failed: %v", err)
|
||||
}
|
||||
if w.tip == input {
|
||||
t.Fatal("worker tip shares pointer with input")
|
||||
if w.tip == nil {
|
||||
t.Fatal("worker tip was not set")
|
||||
}
|
||||
|
||||
input.Add(input, big.NewInt(1))
|
||||
if w.tip.Cmp(big.NewInt(2*params.GWei)) != 0 {
|
||||
if w.tip.Cmp(uint256.NewInt(2*params.GWei)) != 0 {
|
||||
t.Fatalf("worker tip mutated via input pointer: have %v", w.tip)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue