Skip to content

Commit

Permalink
bugfix: prevent zero fee txs from getting included in the worker and …
Browse files Browse the repository at this point in the history
…state processor
  • Loading branch information
gameofpointers committed Oct 9, 2024
1 parent 98962d9 commit 8e9689d
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 5 deletions.
17 changes: 12 additions & 5 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty
totalQiProcessTimes := make(map[string]time.Duration)
firstQiTx := true

nonEtxExists := false

primeTerminus := p.hc.GetHeaderByHash(header.PrimeTerminusHash())
if primeTerminus == nil {
return nil, nil, nil, nil, 0, 0, nil, fmt.Errorf("could not find prime terminus header %032x", header.PrimeTerminusHash())
Expand All @@ -322,7 +324,7 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty
// value is not the basefee mentioned in the block, the block is invalid In
// the case of the Qi transactions, its converted into Quai at the rate
// defined in the prime terminus
minGasPrice := big.NewInt(0)
var minGasPrice *big.Int
for i, tx := range block.Transactions() {
startProcess := time.Now()

Expand Down Expand Up @@ -350,7 +352,7 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty
qiTxFeeInQuai := misc.QiToQuai(primeTerminus.WorkObjectHeader(), qiTxFee)
// get the gas price by dividing the fee by qiTxGas
qiGasPrice := new(big.Int).Div(qiTxFeeInQuai, big.NewInt(int64(types.CalculateBlockQiTxGas(tx, p.hc.NodeLocation()))))
if minGasPrice.Cmp(big.NewInt(0)) == 0 {
if minGasPrice == nil {
minGasPrice = new(big.Int).Set(qiGasPrice)
} else {
if minGasPrice.Cmp(qiGasPrice) > 0 {
Expand All @@ -366,6 +368,8 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty
totalQiProcessTimes["Fee Verification"] += timing["Fee Verification"]
totalQiProcessTimes["Signature Check"] += timing["Signature Check"]

nonEtxExists = true

continue
}

Expand Down Expand Up @@ -573,7 +577,7 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty

// update the min gas price if the gas price in the tx is less than
// the min gas price
if minGasPrice.Cmp(big.NewInt(0)) == 0 {
if minGasPrice == nil {
minGasPrice = new(big.Int).Set(tx.GasPrice())
} else {
if minGasPrice.Cmp(tx.GasPrice()) > 0 {
Expand All @@ -596,8 +600,11 @@ func (p *StateProcessor) Process(block *types.WorkObject, batch ethdb.Batch) (ty
i++
}

if block.BaseFee().Cmp(minGasPrice) != 0 {
log.Global.Error("length of transactions", len(block.Transactions()))
if nonEtxExists && block.BaseFee().Cmp(big.NewInt(0)) == 0 {
return nil, nil, nil, nil, 0, 0, nil, fmt.Errorf("block base fee is nil though non etx transactions exist")
}

if minGasPrice != nil && block.BaseFee().Cmp(minGasPrice) != 0 {
return nil, nil, nil, nil, 0, 0, nil, fmt.Errorf("invalid base fee used (remote: %d local: %d)", block.BaseFee(), minGasPrice)
}

Expand Down
15 changes: 15 additions & 0 deletions core/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -740,6 +740,10 @@ func (w *worker) OrderTransactionSet(txs []*types.Transaction, gasUsedAfterTrans
} else {
gasPrice = new(big.Int).Set(tx.GasPrice())
}
if gasPrice.Cmp(big.NewInt(0)) == 0 {
w.logger.Error("found tx with zero gas price in order transaction set")
continue
}
txInfos = append(txInfos, TransactionInfo{
Tx: tx,
GasPrice: gasPrice,
Expand Down Expand Up @@ -1674,6 +1678,10 @@ func (w *worker) fillTransactions(env *environment, primeTerminus *types.WorkObj
txByPriceAndNonce := types.TransactionsByPriceAndNonce{}
txByPriceAndNonce.SetHead(orderedTxs)

if baseFee.Cmp(big.NewInt(0)) == 0 {
return errors.New("ordered txs had min gas price of zero")
}

env.wo.Header().SetBaseFee(baseFee)
err := w.commitTransactions(env, primeTerminus, block, &txByPriceAndNonce, false)
if err != nil {
Expand Down Expand Up @@ -1708,6 +1716,10 @@ func (w *worker) fillTransactions(env *environment, primeTerminus *types.WorkObj
// update the fee
qiFeeInQuai := misc.QiToQuai(primeTerminus, tx.MinerFee())
minerFeeInQuai := new(big.Int).Div(qiFeeInQuai, big.NewInt(int64(types.CalculateBlockQiTxGas(tx.Tx(), w.hc.NodeLocation()))))
if minerFeeInQuai.Cmp(big.NewInt(0)) == 0 {
w.logger.Error("rejecting qi tx that has zero gas price")
continue
}
qiTx, err := types.NewTxWithMinerFee(tx.Tx(), minerFeeInQuai, time.Now())
if err != nil {
w.logger.WithField("err", err).Error("Error created new tx with miner Fee for Qi TX", tx.Tx().Hash())
Expand All @@ -1732,6 +1744,9 @@ func (w *worker) fillTransactions(env *environment, primeTerminus *types.WorkObj
// read the gas price of the lowest fee transaction and set the base
// fee for the pending header on each iteration
baseFee = lowestFeeTx.PeekAndGetFee().MinerFee()
if baseFee.Cmp(big.NewInt(0)) == 0 {
continue
}
env.wo.Header().SetBaseFee(baseFee)
w.commitTransactions(env, primeTerminus, block, lowestFeeTx, etxIncluded)
// After the first run the etxs are included
Expand Down

0 comments on commit 8e9689d

Please sign in to comment.