diff --git a/newcoin.vcxproj b/newcoin.vcxproj index fbd79cb56..dfaccea23 100644 --- a/newcoin.vcxproj +++ b/newcoin.vcxproj @@ -175,6 +175,7 @@ + diff --git a/newcoin.vcxproj.filters b/newcoin.vcxproj.filters index 961347ae6..2ccbac5b4 100644 --- a/newcoin.vcxproj.filters +++ b/newcoin.vcxproj.filters @@ -249,6 +249,9 @@ Source Files + + Source Files + Source Files diff --git a/ripple2010.vcxproj b/ripple2010.vcxproj index 843c6f9dc..d3e9aff5c 100644 --- a/ripple2010.vcxproj +++ b/ripple2010.vcxproj @@ -175,6 +175,7 @@ + diff --git a/ripple2010.vcxproj.filters b/ripple2010.vcxproj.filters index 0ef380379..bbdf82255 100644 --- a/ripple2010.vcxproj.filters +++ b/ripple2010.vcxproj.filters @@ -243,6 +243,9 @@ Source Files + + Source Files + Source Files diff --git a/src/cpp/ripple/TransactionCheck.cpp b/src/cpp/ripple/TransactionCheck.cpp new file mode 100644 index 000000000..50b1a7f7c --- /dev/null +++ b/src/cpp/ripple/TransactionCheck.cpp @@ -0,0 +1,11 @@ + +#include "TransactionErr.h" +#include "TransactionEngine.h" + +// Double check a transaction's metadata to make sure no system invariants were broken +// Call right before 'calcRawMeta' + +bool TransactionEngine::checkInvariants(TER result, const SerializedTransaction& txn, TransactionEngineParams params) +{ + return true; +} diff --git a/src/cpp/ripple/TransactionEngine.cpp b/src/cpp/ripple/TransactionEngine.cpp index 1e0beac41..79ce67c1f 100644 --- a/src/cpp/ripple/TransactionEngine.cpp +++ b/src/cpp/ripple/TransactionEngine.cpp @@ -93,7 +93,7 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa } #endif - UPTR_T transactor = Transactor::makeTransactor(txn,params,this); + UPTR_T transactor = Transactor::makeTransactor(txn, params, this); if (transactor.get() != NULL) { uint256 txID = txn.getTransactionID(); @@ -153,28 +153,39 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa if (didApply) { - // Transaction succeeded fully or (retries are not allowed and the transaction could claim a fee) - Serializer m; - mNodes.calcRawMeta(m, terResult, mTxnSeq++); - - txnWrite(); - - Serializer s; - txn.add(s); - - if (isSetBit(params, tapOPEN_LEDGER)) + if (!checkInvariants(terResult, txn, params)) { - if (!mLedger->addTransaction(txID, s)) - assert(false); + cLog(lsFATAL) << "Transaction violates invariants"; + cLog(lsFATAL) << txn.getJson(0); + cLog(lsFATAL) << transToken(terResult) << ": " << transHuman(terResult); + cLog(lsFATAL) << mNodes.getJson(0); + didApply = false; } else { - if (!mLedger->addTransaction(txID, s, m)) + // Transaction succeeded fully or (retries are not allowed and the transaction could claim a fee) + Serializer m; + mNodes.calcRawMeta(m, terResult, mTxnSeq++); + + txnWrite(); + + Serializer s; + txn.add(s); + + if (isSetBit(params, tapOPEN_LEDGER)) + { + if (!mLedger->addTransaction(txID, s)) + assert(false); + } + else + { + if (!mLedger->addTransaction(txID, s, m)) assert(false); - // Charge whatever fee they specified. - STAmount saPaid = txn.getTransactionFee(); - mLedger->destroyCoins(saPaid.getNValue()); + // Charge whatever fee they specified. + STAmount saPaid = txn.getTransactionFee(); + mLedger->destroyCoins(saPaid.getNValue()); + } } } diff --git a/src/cpp/ripple/TransactionEngine.h b/src/cpp/ripple/TransactionEngine.h index 2ad074efb..17e1e02f9 100644 --- a/src/cpp/ripple/TransactionEngine.h +++ b/src/cpp/ripple/TransactionEngine.h @@ -65,6 +65,7 @@ public: void entryModify(SLE::ref sleEntry) { mNodes.entryModify(sleEntry); } TER applyTransaction(const SerializedTransaction&, TransactionEngineParams, bool& didApply); + bool checkInvariants(TER result, const SerializedTransaction& txn, TransactionEngineParams params); }; inline TransactionEngineParams operator|(const TransactionEngineParams& l1, const TransactionEngineParams& l2)