From 433af5e0fe5044b5390fd433ddcf665d556bdf90 Mon Sep 17 00:00:00 2001 From: Svarog Date: Sat, 12 Mar 2022 11:07:10 +0200 Subject: [PATCH] Make findTransactionIndex return wasFound explicitly + fix crash caused by invalid handling of not found transaction (#1971) * Make findTransactionIndex return wasFound explicitly + fix crash caused by invalid handling of not found transaction * Add comment on findTransactionIndex --- .../model/ordered_transactions_by_fee_rate.go | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/domain/miningmanager/mempool/model/ordered_transactions_by_fee_rate.go b/domain/miningmanager/mempool/model/ordered_transactions_by_fee_rate.go index 5b23f1534..7202b98ee 100644 --- a/domain/miningmanager/mempool/model/ordered_transactions_by_fee_rate.go +++ b/domain/miningmanager/mempool/model/ordered_transactions_by_fee_rate.go @@ -18,7 +18,7 @@ func (tobf *TransactionsOrderedByFeeRate) GetByIndex(index int) *MempoolTransact // Push inserts a transaction into the set, placing it in the correct place to preserve order func (tobf *TransactionsOrderedByFeeRate) Push(transaction *MempoolTransaction) error { - index, err := tobf.findTransactionIndex(transaction) + index, _, err := tobf.findTransactionIndex(transaction) if err != nil { return err } @@ -33,14 +33,13 @@ func (tobf *TransactionsOrderedByFeeRate) Push(transaction *MempoolTransaction) // Returns an error if transaction does not exist in the set, or if the given transaction does not have mass // and fee filled in. func (tobf *TransactionsOrderedByFeeRate) Remove(transaction *MempoolTransaction) error { - index, err := tobf.findTransactionIndex(transaction) + index, wasFound, err := tobf.findTransactionIndex(transaction) if err != nil { return err } - txID := transaction.TransactionID() - if !tobf.slice[index].TransactionID().Equal(txID) { - return errors.Errorf("Couldn't find %s in mp.orderedTransactionsByFeeRate", txID) + if !wasFound { + return errors.Errorf("Couldn't find %s in mp.orderedTransactionsByFeeRate", transaction.TransactionID()) } return tobf.RemoveAtIndex(index) @@ -56,15 +55,18 @@ func (tobf *TransactionsOrderedByFeeRate) RemoveAtIndex(index int) error { return nil } -func (tobf *TransactionsOrderedByFeeRate) findTransactionIndex(transaction *MempoolTransaction) (int, error) { +// findTransactionIndex finds the given transaction inside the list of transactions ordered by fee rate. +// If the transaction was not found, will return wasFound=false and index=the index at which transaction can be inserted +// while preserving the order. +func (tobf *TransactionsOrderedByFeeRate) findTransactionIndex(transaction *MempoolTransaction) (index int, wasFound bool, err error) { if transaction.Transaction().Fee == 0 || transaction.Transaction().Mass == 0 { - return 0, errors.Errorf("findTxIndexInOrderedTransactionsByFeeRate expects a transaction with " + + return 0, false, errors.Errorf("findTxIndexInOrderedTransactionsByFeeRate expects a transaction with " + "populated fee and mass") } txID := transaction.TransactionID() txFeeRate := float64(transaction.Transaction().Fee) / float64(transaction.Transaction().Mass) - return sort.Search(len(tobf.slice), func(i int) bool { + index = sort.Search(len(tobf.slice), func(i int) bool { iElement := tobf.slice[i] elementFeeRate := float64(iElement.Transaction().Fee) / float64(iElement.Transaction().Mass) if elementFeeRate > txFeeRate { @@ -76,5 +78,10 @@ func (tobf *TransactionsOrderedByFeeRate) findTransactionIndex(transaction *Memp } return false - }), nil + }) + + wasFound = index != len(tobf.slice) && // sort.Search returns len(tobf.slice) if nothing was found + tobf.slice[index].TransactionID().Equal(transaction.TransactionID()) + + return index, wasFound, nil }