txpool to consider available gas in Best call (#755)

This commit is contained in:
hexoscott 2022-12-02 15:32:56 +00:00 committed by GitHub
parent 0613545530
commit 6ec0a1ba7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 11 deletions

View File

@ -34,6 +34,9 @@ import (
"github.com/google/btree"
"github.com/hashicorp/golang-lru/simplelru"
"github.com/holiman/uint256"
"github.com/ledgerwatch/log/v3"
"go.uber.org/atomic"
"github.com/ledgerwatch/erigon-lib/chain"
"github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/common/cmp"
@ -47,8 +50,6 @@ import (
"github.com/ledgerwatch/erigon-lib/kv/kvcache"
"github.com/ledgerwatch/erigon-lib/kv/mdbx"
"github.com/ledgerwatch/erigon-lib/types"
"github.com/ledgerwatch/log/v3"
"go.uber.org/atomic"
)
var (
@ -599,7 +600,7 @@ func (p *TxPool) Started() bool { return p.started.Load() }
// Best - returns top `n` elements of pending queue
// id doesn't perform full copy of txs, however underlying elements are immutable
func (p *TxPool) Best(n uint16, txs *types.TxsRlp, tx kv.Tx, onTopOf uint64) (bool, error) {
func (p *TxPool) Best(n uint16, txs *types.TxsRlp, tx kv.Tx, onTopOf, availableGas uint64) (bool, error) {
// First wait for the corresponding block to arrive
if p.lastSeenBlock.Load() < onTopOf {
return false, nil // Too early
@ -615,6 +616,12 @@ func (p *TxPool) Best(n uint16, txs *types.TxsRlp, tx kv.Tx, onTopOf uint64) (bo
best := p.pending.best
for i := 0; j < int(n) && i < len(best.ms); i++ {
// if we wouldn't have enough gas for a standard transaction then quit out early
if availableGas < fixedgas.TxGas {
break
}
mt := best.ms[i]
if mt.Tx.Gas >= p.blockGasLimit.Load() {
// Skip transactions with very large gas limit
@ -628,6 +635,20 @@ func (p *TxPool) Best(n uint16, txs *types.TxsRlp, tx kv.Tx, onTopOf uint64) (bo
toRemove = append(toRemove, mt)
continue
}
// 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)
if intrinsicGas > availableGas {
// we might find another TX with a low enough intrinsic gas to include so carry on
continue
}
if intrinsicGas <= availableGas { // check for potential underflow
availableGas -= intrinsicGas
}
txs.Txs[j] = rlpTx
copy(txs.Senders.At(j), sender)
txs.IsLocal[j] = isLocal

View File

@ -28,12 +28,6 @@ import (
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
grpc_recovery "github.com/grpc-ecosystem/go-grpc-middleware/recovery"
"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/gointerfaces"
txpool_proto "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool"
types2 "github.com/ledgerwatch/erigon-lib/gointerfaces/types"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon-lib/types"
"github.com/ledgerwatch/log/v3"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
@ -42,6 +36,13 @@ import (
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/reflection"
"google.golang.org/protobuf/types/known/emptypb"
"github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/gointerfaces"
txpool_proto "github.com/ledgerwatch/erigon-lib/gointerfaces/txpool"
types2 "github.com/ledgerwatch/erigon-lib/gointerfaces/types"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon-lib/types"
)
// TxPoolAPIVersion
@ -50,7 +51,7 @@ var TxPoolAPIVersion = &types2.VersionReply{Major: 1, Minor: 0, Patch: 0}
type txPool interface {
ValidateSerializedTxn(serializedTxn []byte) error
Best(n uint16, txs *types.TxsRlp, tx kv.Tx, onTopOf uint64) (bool, error)
Best(n uint16, txs *types.TxsRlp, tx kv.Tx, onTopOf, availableGas uint64) (bool, error)
GetRlp(tx kv.Tx, hash []byte) ([]byte, error)
AddLocalTxs(ctx context.Context, newTxs types.TxSlots, tx kv.Tx) ([]DiscardReason, error)
deprecatedForEach(_ context.Context, f func(rlp, sender []byte, t SubPoolType), tx kv.Tx)
@ -154,7 +155,7 @@ func (s *GrpcServer) Pending(ctx context.Context, _ *emptypb.Empty) (*txpool_pro
reply := &txpool_proto.PendingReply{}
reply.Txs = make([]*txpool_proto.PendingReply_Tx, 0, 32)
txSlots := types.TxsRlp{}
if _, err := s.txPool.Best(math.MaxInt16, &txSlots, tx, 0 /* onTopOf */); err != nil {
if _, err := s.txPool.Best(math.MaxInt16, &txSlots, tx, 0 /* onTopOf */, math.MaxUint64 /* available gas */); err != nil {
return nil, err
}
var senderArr [20]byte