Rework caching of SLEs during transaction processing.

This commit is contained in:
Arthur Britto
2012-07-18 14:49:50 -07:00
parent af92bb5347
commit d0db6e4476
5 changed files with 132 additions and 71 deletions

View File

@@ -45,11 +45,16 @@ bool STAmount::currencyFromString(uint160& uDstCurrency, const std::string& sCur
} }
// XXX Broken for custom currencies? // XXX Broken for custom currencies?
std::string STAmount::getCurrencyHuman() const std::string STAmount::getHumanCurrency() const
{
return createHumanCurrency(mCurrency);
}
std::string STAmount::createHumanCurrency(const uint160& uCurrency)
{ {
std::string sCurrency; std::string sCurrency;
if (mIsNative) if (uCurrency.isZero())
{ {
return SYSTEM_CURRENCY_CODE; return SYSTEM_CURRENCY_CODE;
} }
@@ -57,7 +62,7 @@ std::string STAmount::getCurrencyHuman() const
{ {
Serializer s(160/8); Serializer s(160/8);
s.add160(mCurrency); s.add160(uCurrency);
SerializerIterator sit(s); SerializerIterator sit(s);
@@ -836,13 +841,15 @@ Json::Value STAmount::getJson(int) const
{ {
Json::Value elem(Json::objectValue); Json::Value elem(Json::objectValue);
// This is a hack, many places don't specify a currency. STAmount is used just as a value. // This is a hack, many places don't specify a currency. STAmount is used just as a value.
if (!mIsNative) if (!mIsNative)
{ {
elem["value"] = getText(); elem["value"] = getText();
elem["currency"] = getCurrencyHuman(); elem["currency"] = getHumanCurrency();
if (!mIssuer.isZero())
elem["issuer"] = NewcoinAddress::createHumanAccountID(mIssuer);
}else }else
{ {
elem=getText(); elem=getText();

View File

@@ -271,7 +271,7 @@ public:
int64 getSNValue() const; int64 getSNValue() const;
void setSNValue(int64); void setSNValue(int64);
std::string getCurrencyHuman() const; std::string getHumanCurrency() const;
bool isNative() const { return mIsNative; } bool isNative() const { return mIsNative; }
bool isZero() const { return mValue == 0; } bool isZero() const { return mValue == 0; }
@@ -344,6 +344,7 @@ public:
static STAmount convertToInternalAmount(uint64 displayAmount, uint64 totalNow, uint64 totalInit, static STAmount convertToInternalAmount(uint64 displayAmount, uint64 totalNow, uint64 totalInit,
const char* name = NULL); const char* name = NULL);
static std::string createHumanCurrency(const uint160& uCurrency);
static STAmount deserialize(SerializerIterator&); static STAmount deserialize(SerializerIterator&);
static bool currencyFromString(uint160& uDstCurrency, const std::string& sCurrency); static bool currencyFromString(uint160& uDstCurrency, const std::string& sCurrency);

View File

@@ -70,6 +70,7 @@ Transaction::Transaction(
Log(lsINFO) << str(boost::format("Transaction: account: %s") % naSourceAccount.humanAccountID()); Log(lsINFO) << str(boost::format("Transaction: account: %s") % naSourceAccount.humanAccountID());
Log(lsINFO) << str(boost::format("Transaction: mAccountFrom: %s") % mAccountFrom.humanAccountID()); Log(lsINFO) << str(boost::format("Transaction: mAccountFrom: %s") % mAccountFrom.humanAccountID());
mTransaction->setSigningPubKey(mFromPubKey); mTransaction->setSigningPubKey(mFromPubKey);
mTransaction->setSourceAccount(mAccountFrom); mTransaction->setSourceAccount(mAccountFrom);
mTransaction->setSequence(uSeq); mTransaction->setSequence(uSeq);

View File

@@ -98,7 +98,7 @@ bool transResultInfo(TransactionEngineResult terCode, std::string& strToken, std
STAmount TransactionEngine::rippleHolds(const uint160& uAccountID, const uint160& uCurrency, const uint160& uIssuerID) STAmount TransactionEngine::rippleHolds(const uint160& uAccountID, const uint160& uCurrency, const uint160& uIssuerID)
{ {
STAmount saBalance; STAmount saBalance;
SLE::pointer sleRippleState = mLedger->getRippleState(Ledger::getRippleStateIndex(uAccountID, uIssuerID, uCurrency)); SLE::pointer sleRippleState = entryCache(ltRIPPLE_STATE, Ledger::getRippleStateIndex(uAccountID, uIssuerID, uCurrency));
if (sleRippleState) if (sleRippleState)
{ {
@@ -117,13 +117,22 @@ STAmount TransactionEngine::accountHolds(const uint160& uAccountID, const uint16
if (uCurrency.isZero()) if (uCurrency.isZero())
{ {
SLE::pointer sleAccount = mLedger->getAccountRoot(uAccountID); SLE::pointer sleAccount = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uAccountID));
saAmount = sleAccount->getIValueFieldAmount(sfBalance); saAmount = sleAccount->getIValueFieldAmount(sfBalance);
Log(lsINFO) << "accountHolds: stamps: " << saAmount.getText();
} }
else else
{ {
saAmount = rippleHolds(uAccountID, uCurrency, uIssuerID); saAmount = rippleHolds(uAccountID, uCurrency, uIssuerID);
Log(lsINFO) << "accountHolds: "
<< saAmount.getText()
<< " : "
<< STAmount::createHumanCurrency(uCurrency)
<< "/"
<< NewcoinAddress::createHumanAccountID(uIssuerID);
} }
return saAmount; return saAmount;
@@ -134,6 +143,12 @@ STAmount TransactionEngine::accountFunds(const uint160& uAccountID, const STAmou
{ {
STAmount saFunds; STAmount saFunds;
Log(lsINFO) << "accountFunds: uAccountID="
<< NewcoinAddress::createHumanAccountID(uAccountID);
Log(lsINFO) << "accountFunds: saDefault.isNative()=" << saDefault.isNative();
Log(lsINFO) << "accountFunds: saDefault.getIssuer()="
<< NewcoinAddress::createHumanAccountID(saDefault.getIssuer());
if (!saDefault.isNative() && saDefault.getIssuer() == uAccountID) if (!saDefault.isNative() && saDefault.getIssuer() == uAccountID)
{ {
saFunds = saDefault; saFunds = saDefault;
@@ -144,7 +159,14 @@ STAmount TransactionEngine::accountFunds(const uint160& uAccountID, const STAmou
{ {
saFunds = accountHolds(uAccountID, saDefault.getCurrency(), saDefault.getIssuer()); saFunds = accountHolds(uAccountID, saDefault.getCurrency(), saDefault.getIssuer());
Log(lsINFO) << "accountFunds: offer funds: " << saFunds.getText(); Log(lsINFO) << "accountFunds: offer funds: uAccountID ="
<< NewcoinAddress::createHumanAccountID(uAccountID)
<< " : "
<< saFunds.getText()
<< "/"
<< saDefault.getHumanCurrency()
<< "/"
<< NewcoinAddress::createHumanAccountID(saDefault.getIssuer());
} }
return saFunds; return saFunds;
@@ -157,7 +179,7 @@ STAmount TransactionEngine::rippleTransit(const uint160& uSenderID, const uint16
if (uSenderID != uIssuerID && uReceiverID != uIssuerID) if (uSenderID != uIssuerID && uReceiverID != uIssuerID)
{ {
SLE::pointer sleIssuerAccount = mLedger->getAccountRoot(uIssuerID); SLE::pointer sleIssuerAccount = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uIssuerID));
uint32 uTransitRate; uint32 uTransitRate;
if (sleIssuerAccount->getIFieldPresent(sfTransferRate)) if (sleIssuerAccount->getIFieldPresent(sfTransferRate))
@@ -189,7 +211,7 @@ STAmount TransactionEngine::rippleSend(const uint160& uSenderID, const uint160&
bool bFlipped = uSenderID > uReceiverID; bool bFlipped = uSenderID > uReceiverID;
uint256 uIndex = Ledger::getRippleStateIndex(uSenderID, uReceiverID, saAmount.getCurrency()); uint256 uIndex = Ledger::getRippleStateIndex(uSenderID, uReceiverID, saAmount.getCurrency());
SLE::pointer sleRippleState = mLedger->getRippleState(uIndex); SLE::pointer sleRippleState = entryCache(ltRIPPLE_STATE, uIndex);
if (!sleRippleState) if (!sleRippleState)
{ {
@@ -248,8 +270,8 @@ STAmount TransactionEngine::accountSend(const uint160& uSenderID, const uint160&
if (saAmount.isNative()) if (saAmount.isNative())
{ {
SLE::pointer sleSender = mLedger->getAccountRoot(uSenderID); SLE::pointer sleSender = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uSenderID));
SLE::pointer sleReceiver = mLedger->getAccountRoot(uReceiverID); SLE::pointer sleReceiver = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uReceiverID));
sleSender->setIFieldAmount(sfBalance, sleSender->getIValueFieldAmount(sfBalance) - saAmount); sleSender->setIFieldAmount(sfBalance, sleSender->getIValueFieldAmount(sfBalance) - saAmount);
sleReceiver->setIFieldAmount(sfBalance, sleReceiver->getIValueFieldAmount(sfBalance) + saAmount); sleReceiver->setIFieldAmount(sfBalance, sleReceiver->getIValueFieldAmount(sfBalance) + saAmount);
@@ -294,8 +316,7 @@ TransactionEngineResult TransactionEngine::dirAdd(
{ {
SLE::pointer sleNode; SLE::pointer sleNode;
STVector256 svIndexes; STVector256 svIndexes;
LedgerStateParms lspRoot = lepNONE; SLE::pointer sleRoot = entryCache(ltDIR_NODE, uRootIndex);
SLE::pointer sleRoot = mLedger->getDirNode(lspRoot, uRootIndex);
if (!sleRoot) if (!sleRoot)
{ {
@@ -312,8 +333,7 @@ TransactionEngineResult TransactionEngine::dirAdd(
if (uNodeDir) if (uNodeDir)
{ {
// Try adding to last node. // Try adding to last node.
lspRoot = lepNONE; sleNode = entryCache(ltDIR_NODE, Ledger::getDirNodeIndex(uRootIndex, uNodeDir));
sleNode = mLedger->getDirNode(lspRoot, Ledger::getDirNodeIndex(uRootIndex, uNodeDir));
assert(sleNode); assert(sleNode);
} }
@@ -348,8 +368,7 @@ TransactionEngineResult TransactionEngine::dirAdd(
{ {
// Previous node is not root node. // Previous node is not root node.
lspRoot = lepNONE; SLE::pointer slePrevious = entryCache(ltDIR_NODE, Ledger::getDirNodeIndex(uRootIndex, uNodeDir-1));
SLE::pointer slePrevious = mLedger->getDirNode(lspRoot, Ledger::getDirNodeIndex(uRootIndex, uNodeDir-1));
slePrevious->setIFieldU64(sfIndexNext, uNodeDir); slePrevious->setIFieldU64(sfIndexNext, uNodeDir);
entryModify(slePrevious); entryModify(slePrevious);
@@ -390,8 +409,7 @@ TransactionEngineResult TransactionEngine::dirDelete(
const uint256& uLedgerIndex) const uint256& uLedgerIndex)
{ {
uint64 uNodeCur = uNodeDir; uint64 uNodeCur = uNodeDir;
LedgerStateParms lspNode = lepNONE; SLE::pointer sleNode = entryCache(ltDIR_NODE, uNodeCur ? Ledger::getDirNodeIndex(uRootIndex, uNodeCur) : uRootIndex);
SLE::pointer sleNode = mLedger->getDirNode(lspNode, uNodeCur ? Ledger::getDirNodeIndex(uRootIndex, uNodeCur) : uRootIndex);
assert(sleNode); assert(sleNode);
@@ -458,8 +476,7 @@ TransactionEngineResult TransactionEngine::dirDelete(
else else
{ {
// Have only a root node and a last node. // Have only a root node and a last node.
LedgerStateParms lspLast = lepNONE; SLE::pointer sleLast = entryCache(ltDIR_NODE, Ledger::getDirNodeIndex(uRootIndex, uNodeNext));
SLE::pointer sleLast = mLedger->getDirNode(lspLast, Ledger::getDirNodeIndex(uRootIndex, uNodeNext));
assert(sleLast); assert(sleLast);
@@ -483,13 +500,11 @@ TransactionEngineResult TransactionEngine::dirDelete(
{ {
// Not root and not last node. Can delete node. // Not root and not last node. Can delete node.
LedgerStateParms lspPrevious = lepNONE; SLE::pointer slePrevious = entryCache(ltDIR_NODE, uNodePrevious ? Ledger::getDirNodeIndex(uRootIndex, uNodePrevious) : uRootIndex);
SLE::pointer slePrevious = mLedger->getDirNode(lspPrevious, uNodePrevious ? Ledger::getDirNodeIndex(uRootIndex, uNodePrevious) : uRootIndex);
assert(slePrevious); assert(slePrevious);
LedgerStateParms lspNext = lepNONE; SLE::pointer sleNext = entryCache(ltDIR_NODE, uNodeNext ? Ledger::getDirNodeIndex(uRootIndex, uNodeNext) : uRootIndex);
SLE::pointer sleNext = mLedger->getDirNode(lspNext, uNodeNext ? Ledger::getDirNodeIndex(uRootIndex, uNodeNext) : uRootIndex);
assert(slePrevious); assert(slePrevious);
assert(sleNext); assert(sleNext);
@@ -527,8 +542,7 @@ TransactionEngineResult TransactionEngine::dirDelete(
else else
{ {
// Last and only node besides the root. // Last and only node besides the root.
LedgerStateParms lspRoot = lepNONE; SLE::pointer sleRoot = entryCache(ltDIR_NODE, uRootIndex);
SLE::pointer sleRoot = mLedger->getDirNode(lspRoot, uRootIndex);
assert(sleRoot); assert(sleRoot);
@@ -556,8 +570,7 @@ TransactionEngineResult TransactionEngine::dirDelete(
// <-- uEntryNode // <-- uEntryNode
void TransactionEngine::dirFirst(const uint256& uRootIndex, uint256& uEntryIndex, uint64& uEntryNode) void TransactionEngine::dirFirst(const uint256& uRootIndex, uint256& uEntryIndex, uint64& uEntryNode)
{ {
LedgerStateParms lspRoot = lepNONE; SLE::pointer sleRoot = entryCache(ltDIR_NODE, uRootIndex);
SLE::pointer sleRoot = mLedger->getDirNode(lspRoot, uRootIndex);
STVector256 svIndexes = sleRoot->getIFieldV256(sfIndexes); STVector256 svIndexes = sleRoot->getIFieldV256(sfIndexes);
std::vector<uint256>& vuiIndexes = svIndexes.peekValue(); std::vector<uint256>& vuiIndexes = svIndexes.peekValue();
@@ -566,8 +579,7 @@ void TransactionEngine::dirFirst(const uint256& uRootIndex, uint256& uEntryIndex
{ {
uEntryNode = sleRoot->getIFieldU64(sfIndexNext); uEntryNode = sleRoot->getIFieldU64(sfIndexNext);
LedgerStateParms lspNext = lepNONE; SLE::pointer sleNext = entryCache(ltDIR_NODE, Ledger::getDirNodeIndex(uRootIndex, uEntryNode));
SLE::pointer sleNext = mLedger->getDirNode(lspNext, Ledger::getDirNodeIndex(uRootIndex, uEntryNode));
uEntryIndex = sleNext->getIFieldV256(sfIndexes).peekValue()[0]; uEntryIndex = sleNext->getIFieldV256(sfIndexes).peekValue()[0];
} }
else else
@@ -600,8 +612,7 @@ TransactionEngineResult TransactionEngine::setAuthorized(const SerializedTransac
// Create generator. // Create generator.
uint160 hGeneratorID = naAccountPublic.getAccountID(); uint160 hGeneratorID = naAccountPublic.getAccountID();
LedgerStateParms qry = lepNONE; SLE::pointer sleGen = entryCache(ltGENERATOR_MAP, Ledger::getGeneratorIndex(hGeneratorID));
SLE::pointer sleGen = mLedger->getGenerator(qry, hGeneratorID);
if (!sleGen) if (!sleGen)
{ {
// Create the generator. // Create the generator.
@@ -630,6 +641,37 @@ TransactionEngineResult TransactionEngine::setAuthorized(const SerializedTransac
return terSUCCESS; return terSUCCESS;
} }
SLE::pointer TransactionEngine::entryCache(LedgerEntryType letType, const uint256& uIndex)
{
SLE::pointer sleEntry;
if (!uIndex.isZero())
{
entryMap::const_iterator it = mEntries.find(uIndex);
switch (it == mEntries.end() ? taaNONE : it->second.second)
{
case taaNONE:
sleEntry = mLedger->getSLE(uIndex);
if (sleEntry)
mEntries[uIndex] = std::make_pair(sleEntry, taaCACHED); // Add to cache.
break;
case taaCREATE:
case taaCACHED:
case taaMODIFY:
sleEntry = it->second.first; // Get from cache.
break;
case taaDELETE:
assert(false); // Unexpected case.
break;
}
}
return sleEntry;
}
SLE::pointer TransactionEngine::entryCreate(LedgerEntryType letType, const uint256& uIndex) SLE::pointer TransactionEngine::entryCreate(LedgerEntryType letType, const uint256& uIndex)
{ {
assert(!uIndex.isZero()); assert(!uIndex.isZero());
@@ -653,16 +695,17 @@ void TransactionEngine::entryDelete(SLE::pointer sleEntry)
switch (it == mEntries.end() ? taaNONE : it->second.second) switch (it == mEntries.end() ? taaNONE : it->second.second)
{ {
case taaCREATE: case taaCREATE:
assert(false); // Unexpected case. assert(false); // Unexpected case.
break; break;
case taaCACHED:
case taaMODIFY: case taaMODIFY:
case taaNONE: case taaNONE:
mEntries[uIndex] = std::make_pair(sleEntry, taaDELETE); // Upgrade. mEntries[uIndex] = std::make_pair(sleEntry, taaDELETE); // Upgrade.
break; break;
case taaDELETE: case taaDELETE:
nothing(); // No change. nothing(); // No change.
break; break;
} }
} }
@@ -676,16 +719,17 @@ void TransactionEngine::entryModify(SLE::pointer sleEntry)
switch (it == mEntries.end() ? taaNONE : it->second.second) switch (it == mEntries.end() ? taaNONE : it->second.second)
{ {
case taaDELETE: case taaDELETE:
assert(false); // Unexpected case. assert(false); // Unexpected case.
break; break;
case taaCACHED:
case taaNONE: case taaNONE:
mEntries[uIndex] = std::make_pair(sleEntry, taaMODIFY); // Upgrade. mEntries[uIndex] = std::make_pair(sleEntry, taaMODIFY); // Upgrade.
break; break;
case taaCREATE: case taaCREATE:
case taaMODIFY: case taaMODIFY:
nothing(); // No change. nothing(); // No change.
break; break;
} }
} }
@@ -703,6 +747,9 @@ void TransactionEngine::txnWrite()
assert(false); assert(false);
break; break;
case taaCACHED:
break;
case taaCREATE: case taaCREATE:
{ {
Log(lsINFO) << "applyTransaction: taaCREATE: " << sleEntry->getText(); Log(lsINFO) << "applyTransaction: taaCREATE: " << sleEntry->getText();
@@ -737,8 +784,8 @@ void TransactionEngine::txnWrite()
// actions can be applied to the ledger. // actions can be applied to the ledger.
void TransactionEngine::entryReset(const SerializedTransaction& txn) void TransactionEngine::entryReset(const SerializedTransaction& txn)
{ {
mEntries.clear(); // Lose old SLE modifications. mEntries.clear(); // Lose old SLE modifications.
mTxnAccount = mLedger->getAccountRoot(mTxnAccountID); // Get new SLE. mTxnAccount = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(mTxnAccountID)); // Get new SLE.
entryModify(mTxnAccount); entryModify(mTxnAccount);
@@ -826,8 +873,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
case ttNICKNAME_SET: case ttNICKNAME_SET:
{ {
LedgerStateParms qry = lepNONE; SLE::pointer sleNickname = entryCache(ltNICKNAME, txn.getITFieldH256(sfNickname));
SLE::pointer sleNickname = mLedger->getNickname(qry, txn.getITFieldH256(sfNickname));
if (!sleNickname) if (!sleNickname)
saCost = theConfig.FEE_NICKNAME_CREATE; saCost = theConfig.FEE_NICKNAME_CREATE;
@@ -895,7 +941,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
boost::recursive_mutex::scoped_lock sl(mLedger->mLock); boost::recursive_mutex::scoped_lock sl(mLedger->mLock);
mTxnAccount = mLedger->getAccountRoot(mTxnAccountID); mTxnAccount = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(mTxnAccountID));
// Find source account // Find source account
// If are only forwarding, due to resource limitations, we might verifying only some transactions, this would be probablistic. // If are only forwarding, due to resource limitations, we might verifying only some transactions, this would be probablistic.
@@ -1256,7 +1302,7 @@ TransactionEngineResult TransactionEngine::doCreditSet(const SerializedTransacti
return tenDST_IS_SRC; return tenDST_IS_SRC;
} }
SLE::pointer sleDst = mLedger->getAccountRoot(uDstAccountID); SLE::pointer sleDst = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uDstAccountID));
if (!sleDst) if (!sleDst)
{ {
Log(lsINFO) << "doCreditSet: Delay transaction: Destination account does not exist."; Log(lsINFO) << "doCreditSet: Delay transaction: Destination account does not exist.";
@@ -1272,7 +1318,7 @@ TransactionEngineResult TransactionEngine::doCreditSet(const SerializedTransacti
bool bAddIndex = false; bool bAddIndex = false;
bool bDelIndex = false; bool bDelIndex = false;
SLE::pointer sleRippleState = mLedger->getRippleState(mTxnAccountID, uDstAccountID, uCurrency); SLE::pointer sleRippleState = entryCache(ltRIPPLE_STATE, Ledger::getRippleStateIndex(mTxnAccountID, uDstAccountID, uCurrency));
if (sleRippleState) if (sleRippleState)
{ {
// A line exists in one or more directions. // A line exists in one or more directions.
@@ -1359,8 +1405,7 @@ TransactionEngineResult TransactionEngine::doNicknameSet(const SerializedTransac
bool bMinOffer = txn.getITFieldPresent(sfMinimumOffer); bool bMinOffer = txn.getITFieldPresent(sfMinimumOffer);
STAmount saMinOffer = bMinOffer ? txn.getITFieldAmount(sfAmount) : STAmount(); STAmount saMinOffer = bMinOffer ? txn.getITFieldAmount(sfAmount) : STAmount();
LedgerStateParms qry = lepNONE; SLE::pointer sleNickname = entryCache(ltNICKNAME, uNickname);
SLE::pointer sleNickname = mLedger->getNickname(qry, uNickname);
if (sleNickname) if (sleNickname)
{ {
@@ -1405,7 +1450,7 @@ TransactionEngineResult TransactionEngine::doPasswordFund(const SerializedTransa
uint160 uDstAccountID = txn.getITFieldAccount(sfDestination); uint160 uDstAccountID = txn.getITFieldAccount(sfDestination);
SLE::pointer sleDst = mTxnAccountID == uDstAccountID SLE::pointer sleDst = mTxnAccountID == uDstAccountID
? mTxnAccount ? mTxnAccount
: mLedger->getAccountRoot(uDstAccountID); : entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uDstAccountID));
if (!sleDst) if (!sleDst)
{ {
// Destination account does not exist. // Destination account does not exist.
@@ -1615,7 +1660,7 @@ TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction
} }
else if (!saDstAmount.isPositive()) else if (!saDstAmount.isPositive())
{ {
Log(lsINFO) << "doPayment: Invalid transaction: bad amount: " << saDstAmount.getCurrencyHuman() << " " << saDstAmount.getText(); Log(lsINFO) << "doPayment: Invalid transaction: bad amount: " << saDstAmount.getHumanCurrency() << " " << saDstAmount.getText();
return tenBAD_AMOUNT; return tenBAD_AMOUNT;
} }
@@ -1630,7 +1675,7 @@ TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction
return tenREDUNDANT; return tenREDUNDANT;
} }
SLE::pointer sleDst = mLedger->getAccountRoot(uDstAccountID); SLE::pointer sleDst = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uDstAccountID));
if (!sleDst) if (!sleDst)
{ {
// Destination account does not exist. // Destination account does not exist.
@@ -1696,7 +1741,7 @@ TransactionEngineResult TransactionEngine::doPayment(const SerializedTransaction
// Try direct ripple first. // Try direct ripple first.
if (!bNoRippleDirect && mTxnAccountID != uDstAccountID && uSrcCurrency == uDstCurrency) if (!bNoRippleDirect && mTxnAccountID != uDstAccountID && uSrcCurrency == uDstCurrency)
{ {
SLE::pointer sleRippleState = mLedger->getRippleState(mTxnAccountID, uDstAccountID, uDstCurrency); SLE::pointer sleRippleState = entryCache(ltRIPPLE_STATE, Ledger::getRippleStateIndex(mTxnAccountID, uDstAccountID, uDstCurrency));
if (sleRippleState) if (sleRippleState)
{ {
@@ -1841,7 +1886,7 @@ TransactionEngineResult TransactionEngine::doWalletAdd(const SerializedTransacti
return tenBAD_ADD_AUTH; return tenBAD_ADD_AUTH;
} }
SLE::pointer sleDst = mLedger->getAccountRoot(uDstAccountID); SLE::pointer sleDst = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uDstAccountID));
if (sleDst) if (sleDst)
{ {
@@ -1930,7 +1975,7 @@ TransactionEngineResult TransactionEngine::takeOffers(
{ {
// Taker has needs. // Taker has needs.
sleOfferDir = mLedger->getNextSLE(uTipIndex, uBookEnd); sleOfferDir = entryCache(ltDIR_NODE, mLedger->getNextLedgerIndex(uTipIndex, uBookEnd));
if (sleOfferDir) if (sleOfferDir)
{ {
Log(lsINFO) << "takeOffers: possible counter offer found"; Log(lsINFO) << "takeOffers: possible counter offer found";
@@ -1964,7 +2009,7 @@ TransactionEngineResult TransactionEngine::takeOffers(
dirFirst(uTipIndex, uOfferIndex, uOfferNode); dirFirst(uTipIndex, uOfferIndex, uOfferNode);
SLE::pointer sleOffer = mLedger->getSLE(uOfferIndex); SLE::pointer sleOffer = entryCache(ltOFFER, uOfferIndex);
Log(lsINFO) << "takeOffers: considering offer : " << sleOffer->getJson(0); Log(lsINFO) << "takeOffers: considering offer : " << sleOffer->getJson(0);
@@ -1991,9 +2036,9 @@ TransactionEngineResult TransactionEngine::takeOffers(
else else
{ {
// Get offer funds available. // Get offer funds available.
uint160 uPaysIssuerID = sleOffer->getIValueFieldAccount(sfPaysIssuer).getAccountID();
saOfferPays.setIssuer(uPaysIssuerID); if (sleOffer->getIFieldPresent(sfPaysIssuer))
saOfferPays.setIssuer(sleOffer->getIValueFieldAccount(sfPaysIssuer).getAccountID());
STAmount saOfferFunds = accountFunds(uOfferOwnerID, saOfferPays); STAmount saOfferFunds = accountFunds(uOfferOwnerID, saOfferPays);
STAmount saTakerFunds = accountFunds(uTakerAccountID, saTakerPays); STAmount saTakerFunds = accountFunds(uTakerAccountID, saTakerPays);
@@ -2063,12 +2108,17 @@ TransactionEngineResult TransactionEngine::takeOffers(
TransactionEngineResult TransactionEngine::doOfferCreate(const SerializedTransaction& txn) TransactionEngineResult TransactionEngine::doOfferCreate(const SerializedTransaction& txn)
{ {
Log(lsWARNING) << "doOfferCreate> " << txn.getJson(0);
uint32 txFlags = txn.getFlags(); uint32 txFlags = txn.getFlags();
bool bPassive = !!(txFlags & tfPassive); bool bPassive = !!(txFlags & tfPassive);
STAmount saTakerPays = txn.getITFieldAmount(sfTakerPays);
STAmount saTakerGets = txn.getITFieldAmount(sfTakerGets);
uint160 uPaysIssuerID = txn.getITFieldAccount(sfPaysIssuer); uint160 uPaysIssuerID = txn.getITFieldAccount(sfPaysIssuer);
uint160 uGetsIssuerID = txn.getITFieldAccount(sfGetsIssuer); uint160 uGetsIssuerID = txn.getITFieldAccount(sfGetsIssuer);
STAmount saTakerPays = txn.getITFieldAmount(sfTakerPays);
saTakerPays.setIssuer(uPaysIssuerID);
Log(lsWARNING) << "doOfferCreate: saTakerPays=" << saTakerPays.getJson(0);
STAmount saTakerGets = txn.getITFieldAmount(sfTakerGets);
saTakerGets.setIssuer(uGetsIssuerID);
Log(lsWARNING) << "doOfferCreate: saTakerGets=" << saTakerGets.getJson(0);
uint32 uExpiration = txn.getITFieldU32(sfExpiration); uint32 uExpiration = txn.getITFieldU32(sfExpiration);
bool bHaveExpiration = txn.getITFieldPresent(sfExpiration); bool bHaveExpiration = txn.getITFieldPresent(sfExpiration);
uint32 uSequence = txn.getSequence(); uint32 uSequence = txn.getSequence();
@@ -2132,7 +2182,7 @@ TransactionEngineResult TransactionEngine::doOfferCreate(const SerializedTransac
if (terSUCCESS == terResult && !saTakerPays.isNative()) if (terSUCCESS == terResult && !saTakerPays.isNative())
{ {
SLE::pointer sleTakerPays = mLedger->getAccountRoot(uPaysIssuerID); SLE::pointer sleTakerPays = entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uPaysIssuerID));
if (!sleTakerPays) if (!sleTakerPays)
{ {
@@ -2150,9 +2200,9 @@ TransactionEngineResult TransactionEngine::doOfferCreate(const SerializedTransac
Log(lsINFO) << str(boost::format("doOfferCreate: take against book: %s : %s/%s -> %s/%s") Log(lsINFO) << str(boost::format("doOfferCreate: take against book: %s : %s/%s -> %s/%s")
% uTakeBookBase.ToString() % uTakeBookBase.ToString()
% saTakerGets.getCurrencyHuman() % saTakerGets.getHumanCurrency()
% NewcoinAddress::createHumanAccountID(saTakerGets.getIssuer()) % NewcoinAddress::createHumanAccountID(saTakerGets.getIssuer())
% saTakerPays.getCurrencyHuman() % saTakerPays.getHumanCurrency()
% NewcoinAddress::createHumanAccountID(saTakerPays.getIssuer())); % NewcoinAddress::createHumanAccountID(saTakerPays.getIssuer()));
// Take using the parameters of the offer. // Take using the parameters of the offer.
@@ -2203,9 +2253,9 @@ TransactionEngineResult TransactionEngine::doOfferCreate(const SerializedTransac
Log(lsINFO) << str(boost::format("doOfferCreate: adding to book: %s : %s/%s -> %s/%s") Log(lsINFO) << str(boost::format("doOfferCreate: adding to book: %s : %s/%s -> %s/%s")
% uBookBase.ToString() % uBookBase.ToString()
% saTakerPays.getCurrencyHuman() % saTakerPays.getHumanCurrency()
% NewcoinAddress::createHumanAccountID(saTakerPays.getIssuer()) % NewcoinAddress::createHumanAccountID(saTakerPays.getIssuer())
% saTakerGets.getCurrencyHuman() % saTakerGets.getHumanCurrency()
% NewcoinAddress::createHumanAccountID(saTakerGets.getIssuer())); % NewcoinAddress::createHumanAccountID(saTakerGets.getIssuer()));
uDirectory = Ledger::getQualityIndex(uBookBase, uRate); // Use original rate. uDirectory = Ledger::getQualityIndex(uBookBase, uRate); // Use original rate.
@@ -2220,8 +2270,8 @@ TransactionEngineResult TransactionEngine::doOfferCreate(const SerializedTransac
// Log(lsWARNING) << "doOfferCreate: uGetsIssuerID=" << NewcoinAddress::createHumanAccountID(uGetsIssuerID); // Log(lsWARNING) << "doOfferCreate: uGetsIssuerID=" << NewcoinAddress::createHumanAccountID(uGetsIssuerID);
// Log(lsWARNING) << "doOfferCreate: saTakerPays.isNative()=" << saTakerPays.isNative(); // Log(lsWARNING) << "doOfferCreate: saTakerPays.isNative()=" << saTakerPays.isNative();
// Log(lsWARNING) << "doOfferCreate: saTakerGets.isNative()=" << saTakerGets.isNative(); // Log(lsWARNING) << "doOfferCreate: saTakerGets.isNative()=" << saTakerGets.isNative();
// Log(lsWARNING) << "doOfferCreate: uPaysCurrency=" << saTakerPays.getCurrencyHuman(); // Log(lsWARNING) << "doOfferCreate: uPaysCurrency=" << saTakerPays.getHumanCurrency();
// Log(lsWARNING) << "doOfferCreate: uGetsCurrency=" << saTakerGets.getCurrencyHuman(); // Log(lsWARNING) << "doOfferCreate: uGetsCurrency=" << saTakerGets.getHumanCurrency();
sleOffer->setIFieldAccount(sfAccount, mTxnAccountID); sleOffer->setIFieldAccount(sfAccount, mTxnAccountID);
sleOffer->setIFieldU32(sfSequence, uSequence); sleOffer->setIFieldU32(sfSequence, uSequence);
@@ -2253,7 +2303,7 @@ TransactionEngineResult TransactionEngine::doOfferCancel(const SerializedTransac
TransactionEngineResult terResult; TransactionEngineResult terResult;
uint32 uSequence = txn.getITFieldU32(sfOfferSequence); uint32 uSequence = txn.getITFieldU32(sfOfferSequence);
uint256 uOfferIndex = Ledger::getOfferIndex(mTxnAccountID, uSequence); uint256 uOfferIndex = Ledger::getOfferIndex(mTxnAccountID, uSequence);
SLE::pointer sleOffer = mLedger->getOffer(uOfferIndex); SLE::pointer sleOffer = entryCache(ltOFFER, uOfferIndex);
if (sleOffer) if (sleOffer)
{ {

View File

@@ -93,9 +93,10 @@ enum TransactionEngineParams
enum TransactionAccountAction enum TransactionAccountAction
{ {
taaNONE, taaNONE,
taaCREATE, taaCACHED, // Unmodified.
taaMODIFY, taaMODIFY, // Modifed, must have previously been taaCACHED.
taaDELETE, taaDELETE, // Delete, must have previously been taaDELETE or taaMODIFY.
taaCREATE, // Newly created.
}; };
typedef std::pair<TransactionAccountAction, SerializedLedgerEntry::pointer> AffectedAccount; typedef std::pair<TransactionAccountAction, SerializedLedgerEntry::pointer> AffectedAccount;
@@ -167,6 +168,7 @@ protected:
boost::unordered_set<uint256> mUnfunded; // Indexes that were found unfunded. boost::unordered_set<uint256> mUnfunded; // Indexes that were found unfunded.
SLE::pointer entryCreate(LedgerEntryType letType, const uint256& uIndex); SLE::pointer entryCreate(LedgerEntryType letType, const uint256& uIndex);
SLE::pointer entryCache(LedgerEntryType letType, const uint256& uIndex);
void entryDelete(SLE::pointer sleEntry); void entryDelete(SLE::pointer sleEntry);
void entryModify(SLE::pointer sleEntry); void entryModify(SLE::pointer sleEntry);