Make the transaction engine report whether it added the transaction.

This commit is contained in:
JoelKatz
2012-12-23 17:42:04 -08:00
parent adb9561c2c
commit 2c535940ac
4 changed files with 34 additions and 27 deletions

View File

@@ -1090,14 +1090,15 @@ void LedgerConsensus::playbackProposals()
void LedgerConsensus::applyTransaction(TransactionEngine& engine, SerializedTransaction::ref txn, void LedgerConsensus::applyTransaction(TransactionEngine& engine, SerializedTransaction::ref txn,
Ledger::ref ledger, CanonicalTXSet& failedTransactions, bool openLedger) Ledger::ref ledger, CanonicalTXSet& failedTransactions, bool openLedger)
{ { // FIXME: Needs to handle partial success
TransactionEngineParams parms = openLedger ? tapOPEN_LEDGER : tapNONE; TransactionEngineParams parms = openLedger ? tapOPEN_LEDGER : tapNONE;
#ifndef TRUST_NETWORK #ifndef TRUST_NETWORK
try try
{ {
#endif #endif
TER result = engine.applyTransaction(*txn, parms); bool didApply;
if (isTerRetry(result)) TER result = engine.applyTransaction(*txn, parms, didApply);
if (!didApply && !isTefFailure(result) && !isTemMalformed(result))
{ {
cLog(lsINFO) << " retry"; cLog(lsINFO) << " retry";
assert(!ledger->hasTransaction(txn->getTransactionID())); assert(!ledger->hasTransaction(txn->getTransactionID()));
@@ -1108,12 +1109,6 @@ void LedgerConsensus::applyTransaction(TransactionEngine& engine, SerializedTran
cLog(lsTRACE) << " success"; cLog(lsTRACE) << " success";
assert(ledger->hasTransaction(txn->getTransactionID())); assert(ledger->hasTransaction(txn->getTransactionID()));
} }
else if (isTemMalformed(result) || isTefFailure(result))
{
cLog(lsINFO) << " hard fail";
}
else
assert(false);
#ifndef TRUST_NETWORK #ifndef TRUST_NETWORK
} }
catch (...) catch (...)
@@ -1160,14 +1155,24 @@ void LedgerConsensus::applyTransactions(SHAMap::ref set, Ledger::ref applyLedger
{ {
try try
{ {
TER result = engine.applyTransaction(*it->second, parms); bool didApply;
if (result <= 0) TER result = engine.applyTransaction(*it->second, parms, didApply);
{ if (isTelLocal(result))
if (result == 0) ++successes; { // should never happen
assert(false);
it = failedTransactions.erase(it);
}
else if (didApply)
{ // transaction was applied, remove from set
++successes;
it = failedTransactions.erase(it);
}
else if (isTefFailure(result) || isTemMalformed(result))
{ // transaction cannot apply. tef is expected, tem should never happen
it = failedTransactions.erase(it); it = failedTransactions.erase(it);
} }
else else
{ { // try again
++it; ++it;
} }
} }

View File

@@ -91,8 +91,9 @@ Ledger::pointer LedgerMaster::closeLedger(bool recover)
{ {
try try
{ {
TER result = mEngine.applyTransaction(*it->second, tapOPEN_LEDGER); bool didApply;
if (isTepSuccess(result)) mEngine.applyTransaction(*it->second, tapOPEN_LEDGER, didApply);
if (didApply)
++recovers; ++recovers;
} }
catch (...) catch (...)
@@ -112,7 +113,9 @@ Ledger::pointer LedgerMaster::closeLedger(bool recover)
TER LedgerMaster::doTransaction(const SerializedTransaction& txn, TransactionEngineParams params) TER LedgerMaster::doTransaction(const SerializedTransaction& txn, TransactionEngineParams params)
{ {
TER result = mEngine.applyTransaction(txn, params); bool didApply;
TER result = mEngine.applyTransaction(txn, params, didApply);
// CHECKME: Should we call this even on gross failures?
theApp->getOPs().pubProposedTransaction(mEngine.getLedger(), txn, result); theApp->getOPs().pubProposedTransaction(mEngine.getLedger(), txn, result);
return result; return result;
} }

View File

@@ -67,9 +67,11 @@ void TransactionEngine::txnWrite()
} }
} }
TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, TransactionEngineParams params) TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, TransactionEngineParams params,
bool& didApply)
{ {
cLog(lsTRACE) << "applyTransaction>"; cLog(lsTRACE) << "applyTransaction>";
didApply = false;
assert(mLedger); assert(mLedger);
mNodes.init(mLedger, txn.getTransactionID(), mLedger->getLedgerSeq()); mNodes.init(mLedger, txn.getTransactionID(), mLedger->getLedgerSeq());
@@ -110,12 +112,10 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
cLog(lsINFO) << "applyTransaction: terResult=" << strToken << " : " << terResult << " : " << strHuman; cLog(lsINFO) << "applyTransaction: terResult=" << strToken << " : " << terResult << " : " << strHuman;
bool applyTransaction = false;
if (terResult == tesSUCCESS) if (terResult == tesSUCCESS)
applyTransaction = true; didApply = true;
else if (isTepPartial(terResult) && !isSetBit(params, tapRETRY)) else if (isTepPartial(terResult) && !isSetBit(params, tapRETRY))
applyTransaction = true; didApply = true;
else if (isTecClaim(terResult) && !isSetBit(params, tapRETRY)) else if (isTecClaim(terResult) && !isSetBit(params, tapRETRY))
{ // only claim the transaction fee { // only claim the transaction fee
mNodes.clear(); mNodes.clear();
@@ -146,14 +146,14 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
{ {
txnAcct->setFieldAmount(sfBalance, balance - fee); txnAcct->setFieldAmount(sfBalance, balance - fee);
txnAcct->setFieldU32(sfSequence, t_seq + 1); txnAcct->setFieldU32(sfSequence, t_seq + 1);
applyTransaction = true; didApply = true;
entryModify(txnAcct); entryModify(txnAcct);
} }
} }
} }
} }
if (applyTransaction) if (didApply)
{ {
// Transaction succeeded fully or (retries are not allowed and the transaction succeeded partially). // Transaction succeeded fully or (retries are not allowed and the transaction succeeded partially).
Serializer m; Serializer m;
@@ -183,8 +183,7 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa
mTxnAccount.reset(); mTxnAccount.reset();
mNodes.clear(); mNodes.clear();
if (!isSetBit(params, tapOPEN_LEDGER) if (!isSetBit(params, tapOPEN_LEDGER) && isTemMalformed(terResult))
&& (isTemMalformed(terResult) || isTefFailure(terResult)))
{ {
// XXX Malformed or failed transaction in closed ledger must bow out. // XXX Malformed or failed transaction in closed ledger must bow out.
} }

View File

@@ -78,7 +78,7 @@ public:
void entryDelete(SLE::ref sleEntry) { mNodes.entryDelete(sleEntry); } void entryDelete(SLE::ref sleEntry) { mNodes.entryDelete(sleEntry); }
void entryModify(SLE::ref sleEntry) { mNodes.entryModify(sleEntry); } void entryModify(SLE::ref sleEntry) { mNodes.entryModify(sleEntry); }
TER applyTransaction(const SerializedTransaction&, TransactionEngineParams); TER applyTransaction(const SerializedTransaction&, TransactionEngineParams, bool& didApply);
}; };
inline TransactionEngineParams operator|(const TransactionEngineParams& l1, const TransactionEngineParams& l2) inline TransactionEngineParams operator|(const TransactionEngineParams& l1, const TransactionEngineParams& l2)