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.
This commit is contained in:
JoelKatz
2012-09-13 01:01:40 -07:00
parent d2336e3eea
commit 953f0ad63f
4 changed files with 40 additions and 15 deletions

View File

@@ -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<unsigned char> 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);

View File

@@ -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)

View File

@@ -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(); }

View File

@@ -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();