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)