mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 02:55:50 +00:00
Add support for incrementally updating owner count.
This commit is contained in:
@@ -486,6 +486,35 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, TER result, uint32 index)
|
||||
cLog(lsTRACE) << "Metadata:" << mSet.getJson(0);
|
||||
}
|
||||
|
||||
TER LedgerEntrySet::dirCount(const uint256& uRootIndex, uint32& uCount)
|
||||
{
|
||||
uint64 uNodeDir = 0;
|
||||
|
||||
uCount = 0;
|
||||
|
||||
do
|
||||
{
|
||||
SLE::pointer sleNode = entryCache(ltDIR_NODE, Ledger::getDirNodeIndex(uRootIndex, uNodeDir));
|
||||
|
||||
if (sleNode)
|
||||
{
|
||||
uCount += sleNode->getFieldV256(sfIndexes).peekValue().size();
|
||||
|
||||
uNodeDir = sleNode->getFieldU64(sfIndexNext); // Get next node.
|
||||
}
|
||||
else if (uNodeDir)
|
||||
{
|
||||
cLog(lsWARNING) << "dirCount: no such node";
|
||||
|
||||
assert(false);
|
||||
|
||||
return tefBAD_LEDGER;
|
||||
}
|
||||
} while (uNodeDir);
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
// <-- uNodeDir: For deletion, present to make dirDelete efficient.
|
||||
// --> uRootIndex: The index of the base of the directory. Nodes are based off of this.
|
||||
// --> uLedgerIndex: Value to add to directory.
|
||||
@@ -814,11 +843,53 @@ bool LedgerEntrySet::dirNext(
|
||||
return true;
|
||||
}
|
||||
|
||||
// If there is a count, adjust the owner count by iAmount. Otherwise, compute the owner count and store it.
|
||||
TER LedgerEntrySet::ownerCountAdjust(const uint160& uOwnerID, int iAmount, SLE::ref sleAccountRoot)
|
||||
{
|
||||
SLE::pointer sleHold = sleAccountRoot
|
||||
? SLE::pointer()
|
||||
: entryCache(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uOwnerID));
|
||||
|
||||
SLE::ref sleRoot = sleAccountRoot
|
||||
? sleAccountRoot
|
||||
: sleHold;
|
||||
|
||||
const bool bHaveOwnerCount = sleRoot->isFieldPresent(sfOwnerCount);
|
||||
TER terResult;
|
||||
|
||||
if (bHaveOwnerCount)
|
||||
{
|
||||
const uint32 uOwnerCount = sleRoot->getFieldU32(sfOwnerCount);
|
||||
|
||||
sleRoot->setFieldU32(sfOwnerCount, uOwnerCount+iAmount);
|
||||
|
||||
terResult = tesSUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 uActualCount;
|
||||
|
||||
terResult = dirCount(Ledger::getOwnerDirIndex(uOwnerID), uActualCount);
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
sleRoot->setFieldU32(sfOwnerCount, uActualCount);
|
||||
}
|
||||
}
|
||||
|
||||
return terResult;
|
||||
}
|
||||
|
||||
TER LedgerEntrySet::offerDelete(const SLE::pointer& sleOffer, const uint256& uOfferIndex, const uint160& uOwnerID)
|
||||
{
|
||||
uint64 uOwnerNode = sleOffer->getFieldU64(sfOwnerNode);
|
||||
TER terResult = dirDelete(false, uOwnerNode, Ledger::getOwnerDirIndex(uOwnerID), uOfferIndex, false);
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
terResult = ownerCountAdjust(uOwnerID, -1);
|
||||
}
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
uint256 uDirectory = sleOffer->getFieldH256(sfBookDirectory);
|
||||
|
||||
@@ -99,8 +99,11 @@ public:
|
||||
const uint256& uLedgerIndex, // Item being deleted
|
||||
const bool bStable);
|
||||
|
||||
bool dirFirst(const uint256& uRootIndex, SLE::pointer& sleNode, unsigned int& uDirEntry, uint256& uEntryIndex);
|
||||
bool dirNext(const uint256& uRootIndex, SLE::pointer& sleNode, unsigned int& uDirEntry, uint256& uEntryIndex);
|
||||
bool dirFirst(const uint256& uRootIndex, SLE::pointer& sleNode, unsigned int& uDirEntry, uint256& uEntryIndex);
|
||||
bool dirNext(const uint256& uRootIndex, SLE::pointer& sleNode, unsigned int& uDirEntry, uint256& uEntryIndex);
|
||||
TER dirCount(const uint256& uDirIndex, uint32& uCount);
|
||||
|
||||
TER ownerCountAdjust(const uint160& uOwnerID, int iAmount, SLE::ref sleAccountRoot=SLE::pointer());
|
||||
|
||||
// Offer functions.
|
||||
TER offerDelete(const uint256& uOfferIndex);
|
||||
|
||||
@@ -38,4 +38,6 @@ TER OfferCancelTransactor::doApply()
|
||||
}
|
||||
|
||||
return terResult;
|
||||
}
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -399,6 +399,12 @@ TER OfferCreateTransactor::doApply()
|
||||
boost::bind(&Ledger::qualityDirDescriber, _1, saTakerPays.getCurrency(), uPaysIssuerID,
|
||||
saTakerGets.getCurrency(), uGetsIssuerID, uRate));
|
||||
|
||||
// Update owner count.
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
terResult = mEngine->getNodes().ownerCountAdjust(mTxnAccountID, 1, mTxnAccount);
|
||||
}
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
{
|
||||
uint256 uBookBase = Ledger::getBookBase(uPaysCurrency, uPaysIssuerID, uGetsCurrency, uGetsIssuerID);
|
||||
|
||||
@@ -9,25 +9,25 @@
|
||||
class Transactor
|
||||
{
|
||||
protected:
|
||||
const SerializedTransaction& mTxn;
|
||||
TransactionEngine* mEngine;
|
||||
TransactionEngineParams mParams;
|
||||
const SerializedTransaction& mTxn;
|
||||
TransactionEngine* mEngine;
|
||||
TransactionEngineParams mParams;
|
||||
|
||||
uint160 mTxnAccountID;
|
||||
STAmount mFeeDue;
|
||||
STAmount mSourceBalance;
|
||||
SLE::pointer mTxnAccount;
|
||||
bool mHasAuthKey;
|
||||
RippleAddress mSigningPubKey;
|
||||
|
||||
uint160 mTxnAccountID;
|
||||
STAmount mFeeDue;
|
||||
STAmount mSourceBalance;
|
||||
SLE::pointer mTxnAccount;
|
||||
bool mHasAuthKey;
|
||||
RippleAddress mSigningPubKey;
|
||||
|
||||
TER preCheck();
|
||||
TER checkSeq();
|
||||
TER payFee();
|
||||
|
||||
virtual void calculateFee();
|
||||
virtual TER checkSig();
|
||||
virtual TER doApply()=0;
|
||||
|
||||
|
||||
Transactor(const SerializedTransaction& txn, TransactionEngineParams params, TransactionEngine* engine);
|
||||
|
||||
public:
|
||||
@@ -38,4 +38,6 @@ public:
|
||||
TER apply();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -53,7 +53,12 @@ TER TrustSetTransactor::doApply()
|
||||
if (sleRippleState)
|
||||
{
|
||||
// A line exists in one or more directions.
|
||||
|
||||
#if 0
|
||||
// We might delete a ripple state node if everything is set to defaults.
|
||||
// However, this is problematic as it may make predicting reserve amounts harder for users.
|
||||
// The code here is incomplete.
|
||||
|
||||
if (!saLimitAmount)
|
||||
{
|
||||
// Zeroing line.
|
||||
@@ -135,7 +140,7 @@ TER TrustSetTransactor::doApply()
|
||||
if (uQualityOut)
|
||||
sleRippleState->setFieldU32(bFlipped ? sfHighQualityOut : sfLowQualityOut, uQualityOut);
|
||||
|
||||
uint64 uSrcRef; // Ignored, dirs never delete.
|
||||
uint64 uSrcRef; // <-- Ignored, dirs never delete.
|
||||
|
||||
terResult = mEngine->getNodes().dirAdd(
|
||||
uSrcRef,
|
||||
@@ -143,12 +148,18 @@ TER TrustSetTransactor::doApply()
|
||||
sleRippleState->getIndex(),
|
||||
boost::bind(&Ledger::ownerDirDescriber, _1, mTxnAccountID));
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
terResult = mEngine->getNodes().ownerCountAdjust(mTxnAccountID, 1, mTxnAccount);
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
terResult = mEngine->getNodes().dirAdd(
|
||||
uSrcRef,
|
||||
Ledger::getOwnerDirIndex(uDstAccountID),
|
||||
sleRippleState->getIndex(),
|
||||
boost::bind(&Ledger::ownerDirDescriber, _1, uDstAccountID));
|
||||
|
||||
if (tesSUCCESS == terResult)
|
||||
terResult = mEngine->getNodes().ownerCountAdjust(uDstAccountID, 1, sleDst);
|
||||
}
|
||||
|
||||
Log(lsINFO) << "doTrustSet<";
|
||||
|
||||
Reference in New Issue
Block a user