@@ -83,10 +83,7 @@ HerderImpl::SCPMetrics::SCPMetrics(Application& app)
83
83
}
84
84
85
85
HerderImpl::HerderImpl (Application& app)
86
- : mTransactionQueue (app, TRANSACTION_QUEUE_TIMEOUT_LEDGERS,
87
- TRANSACTION_QUEUE_BAN_LEDGERS,
88
- TRANSACTION_QUEUE_SIZE_MULTIPLIER)
89
- , mPendingEnvelopes (app, *this )
86
+ : mPendingEnvelopes (app, *this )
90
87
, mHerderSCPDriver (app, *this , mUpgrades , mPendingEnvelopes )
91
88
, mLastSlotSaved (0 )
92
89
, mTrackingTimer (app)
@@ -275,7 +272,10 @@ HerderImpl::shutdown()
275
272
" Shutdown interrupting quorum transitive closure analysis." );
276
273
mLastQuorumMapIntersectionState .mInterruptFlag = true ;
277
274
}
278
- mTransactionQueue .shutdown ();
275
+ if (mTransactionQueue )
276
+ {
277
+ mTransactionQueue ->shutdown ();
278
+ }
279
279
if (mSorobanTransactionQueue )
280
280
{
281
281
mSorobanTransactionQueue ->shutdown ();
@@ -603,7 +603,7 @@ HerderImpl::recvTransaction(TransactionFrameBasePtr tx, bool submittedFromSelf)
603
603
mSorobanTransactionQueue ->sourceAccountPending (tx->getSourceID ()) &&
604
604
!tx->isSoroban ();
605
605
bool hasClassic =
606
- mTransactionQueue . sourceAccountPending (tx->getSourceID ()) &&
606
+ mTransactionQueue -> sourceAccountPending (tx->getSourceID ()) &&
607
607
tx->isSoroban ();
608
608
if (hasSoroban || hasClassic)
609
609
{
@@ -617,11 +617,31 @@ HerderImpl::recvTransaction(TransactionFrameBasePtr tx, bool submittedFromSelf)
617
617
}
618
618
else if (!tx->isSoroban ())
619
619
{
620
- result = mTransactionQueue .tryAdd (tx, submittedFromSelf);
620
+ if (mApp .getConfig ().BACKGROUND_TX_QUEUE && !submittedFromSelf)
621
+ {
622
+ mApp .postOnOverlayThread (
623
+ [this , tx]() { mTransactionQueue ->tryAdd (tx, false ); },
624
+ " try add tx" );
625
+ result.code = TransactionQueue::AddResultCode::ADD_STATUS_UNKNOWN;
626
+ }
627
+ else
628
+ {
629
+ result = mTransactionQueue ->tryAdd (tx, submittedFromSelf);
630
+ }
621
631
}
622
632
else if (mSorobanTransactionQueue )
623
633
{
624
- result = mSorobanTransactionQueue ->tryAdd (tx, submittedFromSelf);
634
+ if (mApp .getConfig ().BACKGROUND_TX_QUEUE && !submittedFromSelf)
635
+ {
636
+ mApp .postOnOverlayThread (
637
+ [this , tx]() { mSorobanTransactionQueue ->tryAdd (tx, false ); },
638
+ " try add tx" );
639
+ result.code = TransactionQueue::AddResultCode::ADD_STATUS_UNKNOWN;
640
+ }
641
+ else
642
+ {
643
+ result = mSorobanTransactionQueue ->tryAdd (tx, submittedFromSelf);
644
+ }
625
645
}
626
646
else
627
647
{
@@ -923,7 +943,7 @@ HerderImpl::externalizeValue(TxSetXDRFrameConstPtr txSet, uint32_t ledgerSeq,
923
943
bool
924
944
HerderImpl::sourceAccountPending (AccountID const & accountID) const
925
945
{
926
- bool accPending = mTransactionQueue . sourceAccountPending (accountID);
946
+ bool accPending = mTransactionQueue -> sourceAccountPending (accountID);
927
947
if (mSorobanTransactionQueue )
928
948
{
929
949
accPending = accPending ||
@@ -1092,7 +1112,7 @@ HerderImpl::getPendingEnvelopes()
1092
1112
ClassicTransactionQueue&
1093
1113
HerderImpl::getTransactionQueue ()
1094
1114
{
1095
- return mTransactionQueue ;
1115
+ return * mTransactionQueue ;
1096
1116
}
1097
1117
SorobanTransactionQueue&
1098
1118
HerderImpl::getSorobanTransactionQueue ()
@@ -1391,7 +1411,7 @@ HerderImpl::triggerNextLedger(uint32_t ledgerSeqToTrigger,
1391
1411
// it's guaranteed to be up-to-date
1392
1412
auto const & lcl = mLedgerManager .getLastClosedLedgerHeader ();
1393
1413
PerPhaseTransactionList txPhases;
1394
- txPhases.emplace_back (mTransactionQueue . getTransactions (lcl.header ));
1414
+ txPhases.emplace_back (mTransactionQueue -> getTransactions (lcl.header ));
1395
1415
1396
1416
if (protocolVersionStartsFrom (lcl.header .ledgerVersion ,
1397
1417
SOROBAN_PROTOCOL_VERSION))
@@ -1470,7 +1490,7 @@ HerderImpl::triggerNextLedger(uint32_t ledgerSeqToTrigger,
1470
1490
invalidTxPhases[static_cast <size_t >(TxSetPhase::SOROBAN)]);
1471
1491
}
1472
1492
1473
- mTransactionQueue . ban (
1493
+ mTransactionQueue -> ban (
1474
1494
invalidTxPhases[static_cast <size_t >(TxSetPhase::CLASSIC)]);
1475
1495
1476
1496
auto txSetHash = proposedSet->getContentsHash ();
@@ -2172,9 +2192,11 @@ HerderImpl::maybeSetupSorobanQueue(uint32_t protocolVersion)
2172
2192
{
2173
2193
if (!mSorobanTransactionQueue )
2174
2194
{
2195
+ releaseAssert (mTxQueueBucketSnapshot );
2175
2196
mSorobanTransactionQueue =
2176
2197
std::make_unique<SorobanTransactionQueue>(
2177
- mApp , TRANSACTION_QUEUE_TIMEOUT_LEDGERS,
2198
+ mApp , mTxQueueBucketSnapshot ,
2199
+ TRANSACTION_QUEUE_TIMEOUT_LEDGERS,
2178
2200
TRANSACTION_QUEUE_BAN_LEDGERS,
2179
2201
SOROBAN_TRANSACTION_QUEUE_SIZE_MULTIPLIER);
2180
2202
}
@@ -2189,6 +2211,15 @@ HerderImpl::maybeSetupSorobanQueue(uint32_t protocolVersion)
2189
2211
void
2190
2212
HerderImpl::start ()
2191
2213
{
2214
+ releaseAssert (!mTxQueueBucketSnapshot );
2215
+ mTxQueueBucketSnapshot = mApp .getBucketManager ()
2216
+ .getBucketSnapshotManager ()
2217
+ .copySearchableLiveBucketListSnapshot ();
2218
+ releaseAssert (!mTransactionQueue );
2219
+ mTransactionQueue = std::make_unique<ClassicTransactionQueue>(
2220
+ mApp , mTxQueueBucketSnapshot , TRANSACTION_QUEUE_TIMEOUT_LEDGERS,
2221
+ TRANSACTION_QUEUE_BAN_LEDGERS, TRANSACTION_QUEUE_SIZE_MULTIPLIER);
2222
+
2192
2223
mMaxTxSize = mApp .getHerder ().getMaxClassicTxSize ();
2193
2224
{
2194
2225
uint32_t version = mApp .getLedgerManager ()
@@ -2333,23 +2364,23 @@ HerderImpl::updateTransactionQueue(TxSetXDRFrameConstPtr externalizedTxSet)
2333
2364
2334
2365
auto lhhe = mLedgerManager .getLastClosedLedgerHeader ();
2335
2366
2336
- auto updateQueue = [&](auto & queue, auto const & applied) {
2337
- queue.removeApplied (applied);
2338
- queue.shift ();
2339
-
2340
- auto txs = queue.getTransactions (lhhe.header );
2341
-
2342
- auto invalidTxs = TxSetUtils::getInvalidTxList (
2367
+ auto filterInvalidTxs = [&](TxFrameList const & txs) {
2368
+ return TxSetUtils::getInvalidTxList (
2343
2369
txs, mApp , 0 ,
2344
- getUpperBoundCloseTimeOffset (mApp , lhhe.header .scpValue .closeTime ));
2345
- queue.ban (invalidTxs);
2346
-
2347
- queue.rebroadcast ();
2370
+ getUpperBoundCloseTimeOffset (mApp .getAppConnector (),
2371
+ lhhe.header .scpValue .closeTime ));
2348
2372
};
2373
+ // Update bucket list snapshot, if needed. Note that this modifies the
2374
+ // pointer itself on update, so we need to pass the potentially new pointer
2375
+ // to the tx queues.
2376
+ mApp .getBucketManager ()
2377
+ .getBucketSnapshotManager ()
2378
+ .maybeCopySearchableBucketListSnapshot (mTxQueueBucketSnapshot );
2349
2379
if (txsPerPhase.size () > static_cast <size_t >(TxSetPhase::CLASSIC))
2350
2380
{
2351
- updateQueue (mTransactionQueue ,
2352
- txsPerPhase[static_cast <size_t >(TxSetPhase::CLASSIC)]);
2381
+ mTransactionQueue ->update (
2382
+ txsPerPhase[static_cast <size_t >(TxSetPhase::CLASSIC)], lhhe.header ,
2383
+ mTxQueueBucketSnapshot , filterInvalidTxs);
2353
2384
}
2354
2385
2355
2386
// Even if we're in protocol 20, still check for number of phases, in case
@@ -2358,8 +2389,9 @@ HerderImpl::updateTransactionQueue(TxSetXDRFrameConstPtr externalizedTxSet)
2358
2389
if (mSorobanTransactionQueue != nullptr &&
2359
2390
txsPerPhase.size () > static_cast <size_t >(TxSetPhase::SOROBAN))
2360
2391
{
2361
- updateQueue (*mSorobanTransactionQueue ,
2362
- txsPerPhase[static_cast <size_t >(TxSetPhase::SOROBAN)]);
2392
+ mSorobanTransactionQueue ->update (
2393
+ txsPerPhase[static_cast <size_t >(TxSetPhase::SOROBAN)], lhhe.header ,
2394
+ mTxQueueBucketSnapshot , filterInvalidTxs);
2363
2395
}
2364
2396
}
2365
2397
@@ -2476,7 +2508,7 @@ HerderImpl::isNewerNominationOrBallotSt(SCPStatement const& oldSt,
2476
2508
size_t
2477
2509
HerderImpl::getMaxQueueSizeOps () const
2478
2510
{
2479
- return mTransactionQueue . getMaxQueueSizeOps ();
2511
+ return mTransactionQueue -> getMaxQueueSizeOps ();
2480
2512
}
2481
2513
2482
2514
size_t
@@ -2490,7 +2522,7 @@ HerderImpl::getMaxQueueSizeSorobanOps() const
2490
2522
bool
2491
2523
HerderImpl::isBannedTx (Hash const & hash) const
2492
2524
{
2493
- auto banned = mTransactionQueue . isBanned (hash);
2525
+ auto banned = mTransactionQueue -> isBanned (hash);
2494
2526
if (mSorobanTransactionQueue )
2495
2527
{
2496
2528
banned = banned || mSorobanTransactionQueue ->isBanned (hash);
@@ -2501,7 +2533,7 @@ HerderImpl::isBannedTx(Hash const& hash) const
2501
2533
TransactionFrameBaseConstPtr
2502
2534
HerderImpl::getTx (Hash const & hash) const
2503
2535
{
2504
- auto classic = mTransactionQueue . getTx (hash);
2536
+ auto classic = mTransactionQueue -> getTx (hash);
2505
2537
if (!classic && mSorobanTransactionQueue )
2506
2538
{
2507
2539
return mSorobanTransactionQueue ->getTx (hash);
0 commit comments