From 953f0ad63faf2d2f7ee058a5638dfadfd0a6f7a0 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Thu, 13 Sep 2012 01:01:40 -0700 Subject: [PATCH] Don't charge for transactions twice. Have the "old" getTransaction handle metadata sanely. Fix calcRawMeta to fit the new model where an LES holds a reference to its ledger Don't put metadata in open ledger txn sets to avoid breaking the proposal mechanism. --- src/Ledger.cpp | 20 ++++++++++++++++++-- src/LedgerEntrySet.cpp | 10 +++++----- src/LedgerEntrySet.h | 2 +- src/TransactionEngine.cpp | 23 ++++++++++++++++------- 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/Ledger.cpp b/src/Ledger.cpp index 00b647c8b..f106297d4 100644 --- a/src/Ledger.cpp +++ b/src/Ledger.cpp @@ -232,14 +232,30 @@ bool Ledger::addTransaction(const uint256& txID, const Serializer& txn, const Se Transaction::pointer Ledger::getTransaction(const uint256& transID) const { - SHAMapItem::pointer item = mTransactionMap->peekItem(transID); + SHAMapTreeNode::TNType type; + SHAMapItem::pointer item = mTransactionMap->peekItem(transID, type); if (!item) return Transaction::pointer(); Transaction::pointer txn = theApp->getMasterTransaction().fetch(transID, false); if (txn) return txn; - txn = Transaction::sharedTransaction(item->getData(), true); + if (type == SHAMapTreeNode::tnTRANSACTION_NM) + txn = Transaction::sharedTransaction(item->getData(), true); + else if (type == SHAMapTreeNode::tnTRANSACTION_MD) + { + std::vector txnData; + int txnLength; + if (!item->peekSerializer().getVL(txnData, 0, txnLength)) + return Transaction::pointer(); + txn = Transaction::sharedTransaction(txnData, false); + } + else + { + assert(false); + return Transaction::pointer(); + } + if (txn->getStatus() == NEW) txn->setStatus(mClosed ? COMMITTED : INCLUDED, mLedgerSeq); diff --git a/src/LedgerEntrySet.cpp b/src/LedgerEntrySet.cpp index 6196a3a80..5c3f16f73 100644 --- a/src/LedgerEntrySet.cpp +++ b/src/LedgerEntrySet.cpp @@ -325,7 +325,7 @@ bool LedgerEntrySet::threadOwners(TransactionMetaNode& metaNode, SLE::ref node, return false; } -void LedgerEntrySet::calcRawMeta(Serializer& s, Ledger::ref origLedger) +void LedgerEntrySet::calcRawMeta(Serializer& s) { // calculate the raw meta data and return it. This must be called before the set is committed // Entries modified only as a result of building the transaction metadata @@ -357,7 +357,7 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, Ledger::ref origLedger) if (nType == TMNEndOfMetadata) continue; - SLE::pointer origNode = origLedger->getSLE(it->first); + SLE::pointer origNode = mLedger->getSLE(it->first); if (origNode->getType() == ltDIR_NODE) // No metadata for dir nodes continue; @@ -366,7 +366,7 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, Ledger::ref origLedger) if (nType == TMNDeletedNode) { - threadOwners(metaNode, origNode, origLedger, newMod); + threadOwners(metaNode, origNode, mLedger, newMod); if (origNode->getIFieldPresent(sfAmount)) { // node has an amount, covers ripple state nodes @@ -398,12 +398,12 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, Ledger::ref origLedger) } if (nType == TMNCreatedNode) // if created, thread to owner(s) - threadOwners(metaNode, curNode, origLedger, newMod); + threadOwners(metaNode, curNode, mLedger, newMod); if ((nType == TMNCreatedNode) || (nType == TMNModifiedNode)) { if (curNode->isThreadedType()) // always thread to self - threadTx(metaNode, curNode, origLedger, newMod); + threadTx(metaNode, curNode, mLedger, newMod); } if (nType == TMNModifiedNode) diff --git a/src/LedgerEntrySet.h b/src/LedgerEntrySet.h index 6abef7cab..92d96294e 100644 --- a/src/LedgerEntrySet.h +++ b/src/LedgerEntrySet.h @@ -120,7 +120,7 @@ public: STAmount accountFunds(const uint160& uAccountID, const STAmount& saDefault); Json::Value getJson(int) const; - void calcRawMeta(Serializer&, Ledger::ref originalLedger); + void calcRawMeta(Serializer&); // iterator functions bool isEmpty() const { return mEntries.empty(); } diff --git a/src/TransactionEngine.cpp b/src/TransactionEngine.cpp index 2e5e22bd8..1cf937975 100644 --- a/src/TransactionEngine.cpp +++ b/src/TransactionEngine.cpp @@ -430,10 +430,10 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa break; case ttCONTRACT: - terResult= doContractAdd(txn); + terResult = doContractAdd(txn); break; case ttCONTRACT_REMOVE: - terResult=doContractRemove(txn); + terResult = doContractRemove(txn); break; default: @@ -461,14 +461,23 @@ TER TransactionEngine::applyTransaction(const SerializedTransaction& txn, Transa txnWrite(); Serializer s; - txn.add(s); - if (!mLedger->addTransaction(txID, s)) - assert(false); + if (isSetBit(params, tapOPEN_LEDGER)) + { + if (!mLedger->addTransaction(txID, s)) + assert(false); + } + else + { + Serializer m; + mNodes.calcRawMeta(m); + if (!mLedger->addTransaction(txID, s, m)) + assert(false); - // Charge whatever fee they specified. - mLedger->destroyCoins(saPaid.getNValue()); + // Charge whatever fee they specified. + mLedger->destroyCoins(saPaid.getNValue()); + } } mTxnAccount = SLE::pointer();