@@ -1432,16 +1432,54 @@ NetworkOPsImp::apply(std::unique_lock<std::mutex>& batchLock)
1432
1432
e.transaction ->setQueued ();
1433
1433
e.transaction ->setKept ();
1434
1434
}
1435
- else if (isTerRetry (e.result ))
1435
+ else if (
1436
+ isTerRetry (e.result ) || isTelLocal (e.result ) ||
1437
+ isTefFailure (e.result ))
1436
1438
{
1437
1439
if (e.failType != FailHard::yes)
1438
1440
{
1439
- // transaction should be held
1440
- JLOG (m_journal.debug ())
1441
- << " Transaction should be held: " << e.result ;
1442
- e.transaction ->setStatus (HELD);
1443
- m_ledgerMaster.addHeldTransaction (e.transaction );
1444
- e.transaction ->setKept ();
1441
+ auto const lastLedgerSeq =
1442
+ e.transaction ->getSTransaction ()->at (
1443
+ ~sfLastLedgerSequence);
1444
+ auto const ledgersLeft = lastLedgerSeq
1445
+ ? *lastLedgerSeq -
1446
+ m_ledgerMaster.getCurrentLedgerIndex ()
1447
+ : std::optional<LedgerIndex>{};
1448
+ // If any of these conditions are met, the transaction can
1449
+ // be held:
1450
+ // 1. It was submitted locally. (Note that this flag is only
1451
+ // true on the initial submission.)
1452
+ // 2. The transaction has a LastLedgerSequence, and the
1453
+ // LastLedgerSequence is fewer than LocalTxs::holdLedgers
1454
+ // (5) ledgers into the future. (Remember that an
1455
+ // unseated optional compares as less than all seated
1456
+ // values, so it has to be checked explicitly first.)
1457
+ // 3. The SF_HELD flag is not set on the txID. (setFlags
1458
+ // checks before setting. If the flag is set, it returns
1459
+ // false, which means it's been held once without one of
1460
+ // the other conditions, so don't hold it again. Time's
1461
+ // up!)
1462
+ //
1463
+ if (e.local ||
1464
+ (ledgersLeft && ledgersLeft <= LocalTxs::holdLedgers) ||
1465
+ app_.getHashRouter ().setFlags (
1466
+ e.transaction ->getID (), SF_HELD))
1467
+ {
1468
+ // transaction should be held
1469
+ JLOG (m_journal.debug ())
1470
+ << " Transaction should be held: " << e.result ;
1471
+ e.transaction ->setStatus (HELD);
1472
+ m_ledgerMaster.addHeldTransaction (e.transaction );
1473
+ e.transaction ->setKept ();
1474
+ }
1475
+ else
1476
+ JLOG (m_journal.debug ())
1477
+ << " Not holding transaction "
1478
+ << e.transaction ->getID () << " : "
1479
+ << (e.local ? " local" : " network" ) << " , "
1480
+ << " result: " << e.result << " ledgers left: "
1481
+ << (ledgersLeft ? to_string (*ledgersLeft)
1482
+ : " unspecified" );
1445
1483
}
1446
1484
}
1447
1485
else
0 commit comments