Skip to content

Commit b30ca00

Browse files
committed
Give a transaction more chances to be retried:
* Hold if the transaction gets a ter, tel, or tef result. * Use the new SF_HELD flag to ultimately prevent the transaction from being held and retried too many times.
1 parent 57bcf28 commit b30ca00

File tree

4 files changed

+52
-13
lines changed

4 files changed

+52
-13
lines changed

src/ripple/app/ledger/LocalTxs.h

+5
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ namespace ripple {
3333
class LocalTxs
3434
{
3535
public:
36+
// The number of ledgers to hold a transaction is essentially
37+
// arbitrary. It should be sufficient to allow the transaction to
38+
// get into a fully-validated ledger.
39+
static constexpr int holdLedgers = 5;
40+
3641
virtual ~LocalTxs() = default;
3742

3843
// Add a new local transaction

src/ripple/app/ledger/impl/LocalTxs.cpp

+1-6
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,9 @@ namespace ripple {
5353
class LocalTx
5454
{
5555
public:
56-
// The number of ledgers to hold a transaction is essentially
57-
// arbitrary. It should be sufficient to allow the transaction to
58-
// get into a fully-validated ledger.
59-
static int const holdLedgers = 5;
60-
6156
LocalTx(LedgerIndex index, std::shared_ptr<STTx const> const& txn)
6257
: m_txn(txn)
63-
, m_expire(index + holdLedgers)
58+
, m_expire(index + LocalTxs::holdLedgers)
6459
, m_id(txn->getTransactionID())
6560
, m_account(txn->getAccountID(sfAccount))
6661
, m_seqProxy(txn->getSeqProxy())

src/ripple/app/misc/HashRouter.h

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ namespace ripple {
3333
// TODO convert these macros to int constants or an enum
3434
#define SF_BAD 0x02 // Temporarily bad
3535
#define SF_SAVED 0x04
36+
#define SF_HELD 0x08 // Held by LedgerMaster after potential processing failure
3637
#define SF_TRUSTED 0x10 // comes from trusted source
3738

3839
// Private flags, used internally in apply.cpp.

src/ripple/app/misc/NetworkOPs.cpp

+45-7
Original file line numberDiff line numberDiff line change
@@ -1432,16 +1432,54 @@ NetworkOPsImp::apply(std::unique_lock<std::mutex>& batchLock)
14321432
e.transaction->setQueued();
14331433
e.transaction->setKept();
14341434
}
1435-
else if (isTerRetry(e.result))
1435+
else if (
1436+
isTerRetry(e.result) || isTelLocal(e.result) ||
1437+
isTefFailure(e.result))
14361438
{
14371439
if (e.failType != FailHard::yes)
14381440
{
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");
14451483
}
14461484
}
14471485
else

0 commit comments

Comments
 (0)