Skip to content

Commit 5b79014

Browse files
committed
Address feedback
1 parent aabd7a6 commit 5b79014

File tree

3 files changed

+40
-31
lines changed

3 files changed

+40
-31
lines changed

Diff for: src/herder/TransactionQueue.cpp

+28-22
Original file line numberDiff line numberDiff line change
@@ -186,49 +186,53 @@ TransactionQueue::canAdd(TransactionFrameBasePtr tx,
186186
TransactionFrameBasePtr currentTx;
187187
if (stateIter != mAccountStates.end())
188188
{
189-
auto transaction = stateIter->second.mTransaction;
189+
auto const& transaction = stateIter->second.mTransaction;
190190

191191
if (transaction)
192192
{
193193
currentTx = transaction->mTx;
194-
if (tx->getEnvelope().type() != ENVELOPE_TYPE_TX_FEE_BUMP)
194+
195+
// Check if the tx is a duplicate
196+
if (isDuplicateTx(currentTx, tx))
195197
{
196-
if (tx->getSeqNum() == transaction->mTx->getSeqNum() &&
197-
isDuplicateTx(transaction->mTx, tx))
198-
{
199-
return TransactionQueue::AddResult::ADD_STATUS_DUPLICATE;
200-
}
198+
return TransactionQueue::AddResult::ADD_STATUS_DUPLICATE;
199+
}
201200

201+
// Any transaction older than the current one is invalid
202+
if (tx->getSeqNum() < currentTx->getSeqNum())
203+
{
204+
// If the transaction is older than the one in the queue, we
205+
// reject it
206+
tx->getResult().result.code(txBAD_SEQ);
207+
return TransactionQueue::AddResult::ADD_STATUS_ERROR;
208+
}
209+
210+
if (tx->getEnvelope().type() != ENVELOPE_TYPE_TX_FEE_BUMP)
211+
{
202212
// If there's already a transaction in the queue, we reject
203213
// any new transaction
204214
return TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER;
205215
}
206216
else
207217
{
208-
if (tx->getSeqNum() != transaction->mTx->getSeqNum())
218+
if (tx->getSeqNum() != currentTx->getSeqNum())
209219
{
210220
// New fee-bump transaction is rejected
211221
return TransactionQueue::AddResult::
212222
ADD_STATUS_TRY_AGAIN_LATER;
213223
}
214224

215-
// Replace-by-fee logic
216-
if (isDuplicateTx(transaction->mTx, tx))
217-
{
218-
return TransactionQueue::AddResult::ADD_STATUS_DUPLICATE;
219-
}
220-
221225
int64_t minFee;
222-
if (!canReplaceByFee(tx, transaction->mTx, minFee))
226+
if (!canReplaceByFee(tx, currentTx, minFee))
223227
{
224228
tx->getResult().result.code(txINSUFFICIENT_FEE);
225229
tx->getResult().feeCharged = minFee;
226230
return TransactionQueue::AddResult::ADD_STATUS_ERROR;
227231
}
228232

229-
if (transaction->mTx->getFeeSourceID() == tx->getFeeSourceID())
233+
if (currentTx->getFeeSourceID() == tx->getFeeSourceID())
230234
{
231-
newFullFee -= transaction->mTx->getFullFee();
235+
newFullFee -= currentTx->getFullFee();
232236
}
233237
}
234238
}
@@ -485,7 +489,7 @@ TransactionQueue::tryAdd(TransactionFrameBasePtr tx, bool submittedFromSelf)
485489
}
486490

487491
void
488-
TransactionQueue::dropTransactions(AccountStates::iterator stateIter)
492+
TransactionQueue::dropTransaction(AccountStates::iterator stateIter)
489493
{
490494
ZoneScoped;
491495
// Remove fees and update queue size for each transaction to be dropped.
@@ -526,7 +530,7 @@ TransactionQueue::removeApplied(Transactions const& appliedTxs)
526530
{
527531
// If there are no transactions in the queue for this source
528532
// account, then there is nothing to do
529-
auto transaction = stateIter->second.mTransaction;
533+
auto const& transaction = stateIter->second.mTransaction;
530534
if (transaction)
531535
{
532536
// We care about matching the sequence number rather than
@@ -555,7 +559,7 @@ TransactionQueue::removeApplied(Transactions const& appliedTxs)
555559

556560
// WARNING: stateIter and everything that references it may
557561
// be invalid from this point onward and should not be used.
558-
dropTransactions(stateIter);
562+
dropTransaction(stateIter);
559563
}
560564
}
561565
}
@@ -599,15 +603,17 @@ TransactionQueue::ban(Transactions const& banTxs)
599603
auto stateIter = mAccountStates.find(kv.first);
600604
if (stateIter != mAccountStates.end())
601605
{
602-
auto transaction = stateIter->second.mTransaction;
606+
auto const& transaction = stateIter->second.mTransaction;
603607
// Only ban transactions that are actually present in the queue.
604608
// Transactions with higher sequence numbers than banned
605609
// transactions remain in the queue.
606610
if (transaction &&
607611
transaction->mTx->getFullHash() == kv.second->getFullHash())
608612
{
609613
mSizeByAge[stateIter->second.mAge]->dec();
610-
dropTransactions(stateIter);
614+
// WARNING: stateIter and everything that references it may
615+
// be invalid from this point onward and should not be used.
616+
dropTransaction(stateIter);
611617
}
612618
}
613619
}

Diff for: src/herder/TransactionQueue.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,9 @@ class TransactionQueue
109109

110110
AddResult tryAdd(TransactionFrameBasePtr tx, bool submittedFromSelf);
111111
void removeApplied(Transactions const& txs);
112-
// Ban transactions that are no longer valid; transaction per account limit
113-
// applies here, so `txs` should have no duplicate source accounts
112+
// Ban transactions that are no longer valid or have insufficient fee;
113+
// transaction per account limit applies here, so `txs` should have no
114+
// duplicate source accounts
114115
void ban(Transactions const& txs);
115116

116117
/**
@@ -192,7 +193,7 @@ class TransactionQueue
192193
void releaseFeeMaybeEraseAccountState(TransactionFrameBasePtr tx);
193194

194195
void prepareDropTransaction(AccountState& as);
195-
void dropTransactions(AccountStates::iterator stateIter);
196+
void dropTransaction(AccountStates::iterator stateIter);
196197

197198
void clearAll();
198199

Diff for: src/herder/test/TransactionQueueTests.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -556,19 +556,21 @@ testTransactionQueueBasicScenarios()
556556
test.add(txSeqA1T1, TransactionQueue::AddResult::ADD_STATUS_DUPLICATE);
557557
test.check(state);
558558

559-
auto status = TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER;
560-
test.add(txSeqA1T2, status);
559+
test.add(txSeqA1T2,
560+
TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER);
561561
test.check(state);
562562

563-
// Regardless of seqnum validity, tx is rejected due to limit
563+
// Tx is rejected due to limit or bad seqnum
564564
// too low
565-
test.add(txSeqA1T0, status);
565+
test.add(txSeqA1T0, TransactionQueue::AddResult::ADD_STATUS_ERROR);
566566
test.check(state);
567567
// too high
568-
test.add(txSeqA1T4, status);
568+
test.add(txSeqA1T4,
569+
TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER);
569570
test.check(state);
570571
// just right
571-
test.add(txSeqA1T3, status);
572+
test.add(txSeqA1T3,
573+
TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER);
572574
test.check(state);
573575
}
574576

0 commit comments

Comments
 (0)