Add some basic sanity checks.

This commit is contained in:
JoelKatz
2013-05-06 17:26:43 -07:00
parent 9d03da73c4
commit c3666feafd

View File

@@ -3,14 +3,61 @@
#include "TransactionEngine.h"
// Double check a transaction's metadata to make sure no system invariants were broken
// Call right before 'calcRawMeta'
SETUP_LOG();
bool TransactionEngine::checkInvariants(TER result, const SerializedTransaction& txn, TransactionEngineParams params)
{
const RippleAddress& srcAccount = txn.getFieldAccount(sfAccount);
uint32 txnSeq = txn.getFieldU32(sfSequence);
// 1) Make sure transaction changed account sequence number to correct value
LedgerEntryAction leaAction;
// 2) Make sure transaction didn't create XRP
uint256 srcActId = Ledger::getAccountRootIndex(srcAccount.getAccountID());
SLE::pointer origSrcAct = mLedger->getSLE(srcActId);
SLE::pointer newSrcAct = mNodes.getEntry(srcActId, leaAction);
if (!newSrcAct || !origSrcAct)
{
cLog(lsFATAL) << "Transaction created or destroyed its issuing account";
assert(false);
return tefINTERNAL;
}
if ((newSrcAct->getFieldU32(sfSequence) != (txnSeq + 1)) ||
(origSrcAct->getFieldU32(sfSequence) != txnSeq))
{
cLog(lsFATAL) << "Transaction mangles sequence numbers";
cLog(lsFATAL) << "t:" << txnSeq << " o: " << origSrcAct->getFieldU32(sfSequence)
<< " n: " << newSrcAct->getFieldU32(sfSequence);
assert(false);
return tefINTERNAL;
}
int64 xrpChange = txn.getFieldAmount(sfFee).getSNValue();
for (LedgerEntrySet::const_iterator it = mNodes.begin(), end = mNodes.end(); it != end; ++it)
{
const LedgerEntrySetEntry& entry = it->second;
if (entry.mAction == taaMODIFY)
{
if (entry.mEntry->getType() == ltACCOUNT_ROOT)
{ // account modified
xrpChange += entry.mEntry->getFieldAmount(sfBalance).getSNValue();
xrpChange -= mLedger->getSLE(it->first)->getFieldAmount(sfBalance).getSNValue();
}
}
else if (entry.mAction == taaCREATE)
{
if (entry.mEntry->getType() == ltACCOUNT_ROOT) // account created
xrpChange += entry.mEntry->getFieldAmount(sfBalance).getSNValue();
}
}
if (xrpChange != 0)
{
cLog(lsFATAL) << "Transaction creates/destroys XRP";
assert(false);
return tefINTERNAL;
}
return true;
}