@@ -186,49 +186,53 @@ TransactionQueue::canAdd(TransactionFrameBasePtr tx,
186
186
TransactionFrameBasePtr currentTx;
187
187
if (stateIter != mAccountStates .end ())
188
188
{
189
- auto transaction = stateIter->second .mTransaction ;
189
+ auto const & transaction = stateIter->second .mTransaction ;
190
190
191
191
if (transaction)
192
192
{
193
193
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))
195
197
{
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
+ }
201
200
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
+ {
202
212
// If there's already a transaction in the queue, we reject
203
213
// any new transaction
204
214
return TransactionQueue::AddResult::ADD_STATUS_TRY_AGAIN_LATER;
205
215
}
206
216
else
207
217
{
208
- if (tx->getSeqNum () != transaction-> mTx ->getSeqNum ())
218
+ if (tx->getSeqNum () != currentTx ->getSeqNum ())
209
219
{
210
220
// New fee-bump transaction is rejected
211
221
return TransactionQueue::AddResult::
212
222
ADD_STATUS_TRY_AGAIN_LATER;
213
223
}
214
224
215
- // Replace-by-fee logic
216
- if (isDuplicateTx (transaction->mTx , tx))
217
- {
218
- return TransactionQueue::AddResult::ADD_STATUS_DUPLICATE;
219
- }
220
-
221
225
int64_t minFee;
222
- if (!canReplaceByFee (tx, transaction-> mTx , minFee))
226
+ if (!canReplaceByFee (tx, currentTx , minFee))
223
227
{
224
228
tx->getResult ().result .code (txINSUFFICIENT_FEE);
225
229
tx->getResult ().feeCharged = minFee;
226
230
return TransactionQueue::AddResult::ADD_STATUS_ERROR;
227
231
}
228
232
229
- if (transaction-> mTx ->getFeeSourceID () == tx->getFeeSourceID ())
233
+ if (currentTx ->getFeeSourceID () == tx->getFeeSourceID ())
230
234
{
231
- newFullFee -= transaction-> mTx ->getFullFee ();
235
+ newFullFee -= currentTx ->getFullFee ();
232
236
}
233
237
}
234
238
}
@@ -485,7 +489,7 @@ TransactionQueue::tryAdd(TransactionFrameBasePtr tx, bool submittedFromSelf)
485
489
}
486
490
487
491
void
488
- TransactionQueue::dropTransactions (AccountStates::iterator stateIter)
492
+ TransactionQueue::dropTransaction (AccountStates::iterator stateIter)
489
493
{
490
494
ZoneScoped;
491
495
// Remove fees and update queue size for each transaction to be dropped.
@@ -526,7 +530,7 @@ TransactionQueue::removeApplied(Transactions const& appliedTxs)
526
530
{
527
531
// If there are no transactions in the queue for this source
528
532
// account, then there is nothing to do
529
- auto transaction = stateIter->second .mTransaction ;
533
+ auto const & transaction = stateIter->second .mTransaction ;
530
534
if (transaction)
531
535
{
532
536
// We care about matching the sequence number rather than
@@ -555,7 +559,7 @@ TransactionQueue::removeApplied(Transactions const& appliedTxs)
555
559
556
560
// WARNING: stateIter and everything that references it may
557
561
// be invalid from this point onward and should not be used.
558
- dropTransactions (stateIter);
562
+ dropTransaction (stateIter);
559
563
}
560
564
}
561
565
}
@@ -599,15 +603,17 @@ TransactionQueue::ban(Transactions const& banTxs)
599
603
auto stateIter = mAccountStates .find (kv.first );
600
604
if (stateIter != mAccountStates .end ())
601
605
{
602
- auto transaction = stateIter->second .mTransaction ;
606
+ auto const & transaction = stateIter->second .mTransaction ;
603
607
// Only ban transactions that are actually present in the queue.
604
608
// Transactions with higher sequence numbers than banned
605
609
// transactions remain in the queue.
606
610
if (transaction &&
607
611
transaction->mTx ->getFullHash () == kv.second ->getFullHash ())
608
612
{
609
613
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);
611
617
}
612
618
}
613
619
}
0 commit comments