Change how fail_hard transactions are handled.

FIXES: #2847

* Transactions that are submitted with the fail_hard flag
  and that result in any TER code besides tesSUCCESS shall
  be neither queued nor held.

[FOLD] Keep tec results out of the open ledger when fail_hard:

* Improve TransactionStatus const correctness, and remove redundant
  `local` check
* Check open ledger tx count in fail_hard tests
* Fix some wrapping
* Remove duplicate test
This commit is contained in:
Devon White
2019-11-15 13:34:02 -05:00
committed by CJ Cobb
parent 7d867b806d
commit cd9732b47a
7 changed files with 120 additions and 24 deletions

View File

@@ -77,10 +77,10 @@ class NetworkOPsImp final
class TransactionStatus
{
public:
std::shared_ptr<Transaction> transaction;
bool admin;
bool local;
FailHard failType;
std::shared_ptr<Transaction> const transaction;
bool const admin;
bool const local;
FailHard const failType;
bool applied;
TER result;
@@ -93,7 +93,9 @@ class NetworkOPsImp final
, admin (a)
, local (l)
, failType (f)
{}
{
assert(local || failType == FailHard::no);
}
};
/**
@@ -1055,7 +1057,10 @@ void NetworkOPsImp::apply (std::unique_lock<std::mutex>& batchLock)
// we check before adding to the batch
ApplyFlags flags = tapNONE;
if (e.admin)
flags = flags | tapUNLIMITED;
flags |= tapUNLIMITED;
if (e.failType == FailHard::yes)
flags |= tapFAIL_HARD;
auto const result = app_.getTxQ().apply(
app_, view, e.transaction->getSTransaction(),
@@ -1133,8 +1138,9 @@ void NetworkOPsImp::apply (std::unique_lock<std::mutex>& batchLock)
}
else if (e.result == terQUEUED)
{
JLOG(m_journal.debug()) << "Transaction is likely to claim a " <<
"fee, but is queued until fee drops";
JLOG(m_journal.debug()) << "Transaction is likely to claim a"
<< " fee, but is queued until fee drops";
e.transaction->setStatus(HELD);
// Add to held transactions, because it could get
// kicked out of the queue, and this will try to
@@ -1145,11 +1151,7 @@ void NetworkOPsImp::apply (std::unique_lock<std::mutex>& batchLock)
}
else if (isTerRetry (e.result))
{
if (e.failType == FailHard::yes)
{
addLocal = false;
}
else
if (e.failType != FailHard::yes)
{
// transaction should be held
JLOG(m_journal.debug())
@@ -1166,7 +1168,10 @@ void NetworkOPsImp::apply (std::unique_lock<std::mutex>& batchLock)
e.transaction->setStatus (INVALID);
}
if (addLocal)
auto const enforceFailHard = e.failType == FailHard::yes &&
!isTesSuccess(e.result);
if (addLocal && !enforceFailHard)
{
m_localTX->push_back (
m_ledgerMaster.getCurrentLedgerIndex(),
@@ -1174,9 +1179,9 @@ void NetworkOPsImp::apply (std::unique_lock<std::mutex>& batchLock)
e.transaction->setKept();
}
if (e.applied || ((mMode != OperatingMode::FULL) &&
if ((e.applied || ((mMode != OperatingMode::FULL) &&
(e.failType != FailHard::yes) && e.local) ||
(e.result == terQUEUED))
(e.result == terQUEUED)) && !enforceFailHard)
{
auto const toSkip = app_.getHashRouter().shouldRelay(
e.transaction->getID());