mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
@@ -14,6 +14,10 @@ env = Environment(
|
||||
tools = ['default', 'protoc']
|
||||
)
|
||||
|
||||
# Use clang
|
||||
#env.Replace(CC = 'clang')
|
||||
#env.Replace(CXX = 'clang++')
|
||||
|
||||
#
|
||||
# Builder for CTags
|
||||
#
|
||||
|
||||
@@ -55,7 +55,6 @@ std::string STAmount::getCurrencyHuman() const
|
||||
}
|
||||
else
|
||||
{
|
||||
uint160 uReserved = mCurrency;
|
||||
Serializer s(160/8);
|
||||
|
||||
s.add160(mCurrency);
|
||||
@@ -123,7 +122,7 @@ bool STAmount::setValue(const std::string& sAmount, const std::string& sCurrency
|
||||
// ^1 2 0 2 -1
|
||||
// 123^ 4 3 1 0
|
||||
// 1^23 4 1 3 -2
|
||||
iOffset = -(sAmount.size()-uDecimal-1);
|
||||
iOffset = -int(sAmount.size()-uDecimal-1);
|
||||
|
||||
|
||||
// Issolate integer and fraction.
|
||||
|
||||
@@ -463,8 +463,8 @@ bool ConnectionPool::peerScanSet(const std::string& strIp, int iPort)
|
||||
else
|
||||
{
|
||||
// Scan connection terminated, already scheduled for retry.
|
||||
boost::posix_time::ptime tpNow = boost::posix_time::second_clock::universal_time();
|
||||
boost::posix_time::ptime tpNext = ptFromSeconds(db->getInt("ScanNext"));
|
||||
// boost::posix_time::ptime tpNow = boost::posix_time::second_clock::universal_time();
|
||||
// boost::posix_time::ptime tpNext = ptFromSeconds(db->getInt("ScanNext"));
|
||||
|
||||
//Log(lsINFO) << str(boost::format("Pool: Scan: schedule exists: %s %s (next %s, delay=%d)")
|
||||
// % mScanIp % mScanPort % tpNext % (tpNext-tpNow).total_seconds());
|
||||
|
||||
@@ -49,7 +49,7 @@ uint256 Ledger::getBookBase(const uint160& uCurrencyIn, const uint160& uAccountI
|
||||
|
||||
assert(!bInNative || !bOutNative); // Stamps to stamps not allowed.
|
||||
assert(bInNative == uAccountIn.isZero()); // Make sure issuer is specified as needed.
|
||||
assert(bOutNative == uAccountOut.isZero()); // Make sure issuer is specified as needed.
|
||||
assert(bOutNative == uAccountOut.isZero()); // Make sure issuer is specified as needed.
|
||||
assert(uCurrencyIn != uCurrencyOut || uAccountIn != uAccountOut); // Currencies or accounts must differ.
|
||||
|
||||
Serializer s(82);
|
||||
|
||||
@@ -215,6 +215,51 @@ NicknameState::pointer NetworkOPs::getNicknameState(const uint256& uLedger, cons
|
||||
return mLedgerMaster->getLedgerByHash(uLedger)->getNicknameState(strNickname);
|
||||
}
|
||||
|
||||
//
|
||||
// Owner functions
|
||||
//
|
||||
|
||||
Json::Value NetworkOPs::getOwnerInfo(const uint256& uLedger, const NewcoinAddress& naAccount)
|
||||
{
|
||||
Json::Value jvObjects(Json::arrayValue);
|
||||
|
||||
Ledger::pointer lpLedger = mLedgerMaster->getLedgerByHash(uLedger);
|
||||
uint256 uRootIndex = lpLedger->getOwnerDirIndex(naAccount.getAccountID());
|
||||
|
||||
LedgerStateParms lspNode = lepNONE;
|
||||
SLE::pointer sleNode = lpLedger->getDirNode(lspNode, uRootIndex);
|
||||
|
||||
if (sleNode)
|
||||
{
|
||||
uint64 uNodeDir;
|
||||
|
||||
do
|
||||
{
|
||||
STVector256 svIndexes = sleNode->getIFieldV256(sfIndexes);
|
||||
std::vector<uint256>& vuiIndexes = svIndexes.peekValue();
|
||||
|
||||
BOOST_FOREACH(uint256& uDirEntry, vuiIndexes)
|
||||
{
|
||||
LedgerStateParms lspOffer = lepNONE;
|
||||
SLE::pointer sleOffer = lpLedger->getOffer(lspOffer, uDirEntry);
|
||||
|
||||
jvObjects.append(sleOffer->getJson(0));
|
||||
}
|
||||
|
||||
uNodeDir = sleNode->getIFieldU64(sfIndexNext);
|
||||
if (uNodeDir)
|
||||
{
|
||||
lspNode = lepNONE;
|
||||
sleNode = lpLedger->getDirNode(lspNode, Ledger::getDirNodeIndex(uRootIndex, uNodeDir));
|
||||
|
||||
assert(sleNode);
|
||||
}
|
||||
} while (uNodeDir);
|
||||
}
|
||||
|
||||
return jvObjects;
|
||||
}
|
||||
|
||||
//
|
||||
// Ripple functions
|
||||
//
|
||||
|
||||
@@ -118,6 +118,12 @@ public:
|
||||
|
||||
NicknameState::pointer getNicknameState(const uint256& uLedger, const std::string& strNickname);
|
||||
|
||||
//
|
||||
// Owner functions
|
||||
//
|
||||
|
||||
Json::Value getOwnerInfo(const uint256& uLedger, const NewcoinAddress& naAccount);
|
||||
|
||||
//
|
||||
// Ripple functions
|
||||
//
|
||||
|
||||
@@ -139,7 +139,7 @@ std::string NewcoinAddress::humanNodePublic() const
|
||||
|
||||
bool NewcoinAddress::setNodePublic(const std::string& strPublic)
|
||||
{
|
||||
return SetString(strPublic.c_str(), VER_NODE_PUBLIC);
|
||||
return SetString(strPublic.c_str(), VER_NODE_PUBLIC);
|
||||
}
|
||||
|
||||
void NewcoinAddress::setNodePublic(const std::vector<unsigned char>& vPublic)
|
||||
@@ -302,9 +302,9 @@ std::string NewcoinAddress::humanAccountID() const
|
||||
|
||||
bool NewcoinAddress::setAccountID(const std::string& strAccountID)
|
||||
{
|
||||
if (strAccountID == "none")
|
||||
if (strAccountID.empty())
|
||||
{
|
||||
SetData(VER_ACCOUNT_ID, std::vector<unsigned char>());
|
||||
setAccountID(uint160());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -948,6 +948,40 @@ Json::Value RPCServer::doOfferCancel(const Json::Value ¶ms)
|
||||
return obj;
|
||||
}
|
||||
|
||||
// owner_info <account>|<nickname>|<account_public_key>
|
||||
Json::Value RPCServer::doOwnerInfo(const Json::Value& params)
|
||||
{
|
||||
std::string strIdent = params[0u].asString();
|
||||
bool bIndex;
|
||||
int iIndex = 2 == params.size()? lexical_cast_s<int>(params[1u].asString()) : 0;
|
||||
NewcoinAddress naAccount;
|
||||
|
||||
Json::Value ret;
|
||||
|
||||
// Get info on account.
|
||||
|
||||
uint256 uAccepted = mNetOps->getClosedLedger();
|
||||
Json::Value jAccepted = accountFromString(uAccepted, naAccount, bIndex, strIdent, iIndex);
|
||||
|
||||
if (jAccepted.empty())
|
||||
{
|
||||
jAccepted["offers"] = mNetOps->getOwnerInfo(uAccepted, naAccount);
|
||||
}
|
||||
|
||||
ret["accepted"] = jAccepted;
|
||||
|
||||
uint256 uCurrent = mNetOps->getCurrentLedger();
|
||||
Json::Value jCurrent = accountFromString(uCurrent, naAccount, bIndex, strIdent, iIndex);
|
||||
|
||||
if (jCurrent.empty())
|
||||
{
|
||||
jCurrent["offers"] = mNetOps->getOwnerInfo(uCurrent, naAccount);
|
||||
}
|
||||
|
||||
ret["current"] = jCurrent;
|
||||
|
||||
return ret;
|
||||
}
|
||||
// password_fund <seed> <paying_account> [<account>]
|
||||
// YYY Make making account default to first account for seed.
|
||||
Json::Value RPCServer::doPasswordFund(const Json::Value ¶ms)
|
||||
@@ -1504,9 +1538,10 @@ Json::Value RPCServer::doAccountTransactions(const Json::Value& params)
|
||||
else
|
||||
maxLedger = minLedger;
|
||||
|
||||
if ((maxLedger < minLedger) || (minLedger < 0) || (maxLedger == 0))
|
||||
if ((maxLedger < minLedger) || (maxLedger == 0))
|
||||
{
|
||||
std::cerr << "minL=" << minLedger << ", maxL=" << maxLedger << std::endl;
|
||||
|
||||
return RPCError(rpcLGR_IDXS_INVALID);
|
||||
}
|
||||
|
||||
@@ -2104,6 +2139,7 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params
|
||||
{ "nickname_set", &RPCServer::doNicknameSet, 2, 3, false, optCurrent },
|
||||
{ "offer_create", &RPCServer::doOfferCreate, 9, 10, false, optCurrent },
|
||||
{ "offer_cancel", &RPCServer::doOfferCancel, 3, 3, false, optCurrent },
|
||||
{ "owner_info", &RPCServer::doOwnerInfo, 1, 2, false, optCurrent },
|
||||
{ "password_fund", &RPCServer::doPasswordFund, 2, 3, false, optCurrent },
|
||||
{ "password_set", &RPCServer::doPasswordSet, 2, 3, false, optNetwork },
|
||||
{ "peers", &RPCServer::doPeers, 0, 0, true },
|
||||
|
||||
@@ -139,6 +139,7 @@ private:
|
||||
Json::Value doNicknameSet(const Json::Value& params);
|
||||
Json::Value doOfferCreate(const Json::Value& params);
|
||||
Json::Value doOfferCancel(const Json::Value& params);
|
||||
Json::Value doOwnerInfo(const Json::Value& params);
|
||||
Json::Value doPasswordFund(const Json::Value& params);
|
||||
Json::Value doPasswordSet(const Json::Value& params);
|
||||
Json::Value doPeers(const Json::Value& params);
|
||||
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
void setIFieldU8(SOE_Field field, unsigned char v) { return mObject.setValueFieldU8(field, v); }
|
||||
void setIFieldU16(SOE_Field field, uint16 v) { return mObject.setValueFieldU16(field, v); }
|
||||
void setIFieldU32(SOE_Field field, uint32 v) { return mObject.setValueFieldU32(field, v); }
|
||||
void setIFieldU64(SOE_Field field, uint32 v) { return mObject.setValueFieldU64(field, v); }
|
||||
void setIFieldU64(SOE_Field field, uint64 v) { return mObject.setValueFieldU64(field, v); }
|
||||
void setIFieldH128(SOE_Field field, const uint128& v) { return mObject.setValueFieldH128(field, v); }
|
||||
void setIFieldH160(SOE_Field field, const uint160& v) { return mObject.setValueFieldH160(field, v); }
|
||||
void setIFieldH256(SOE_Field field, const uint256& v) { return mObject.setValueFieldH256(field, v); }
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
#include "utils.h"
|
||||
#include "Log.h"
|
||||
|
||||
#define DIR_NODE_MAX 32
|
||||
// Small for testing, should likely be 32 or 64.
|
||||
#define DIR_NODE_MAX 2
|
||||
|
||||
bool transResultInfo(TransactionEngineResult terCode, std::string& strToken, std::string& strHuman)
|
||||
{
|
||||
@@ -170,32 +171,26 @@ TransactionEngineResult TransactionEngine::dirAdd(
|
||||
if (!sleRoot)
|
||||
{
|
||||
// No root, make it.
|
||||
sleRoot = entryCreate(ltDIR_NODE, uRootIndex);
|
||||
|
||||
sleNode = sleRoot;
|
||||
uNodeDir = 0;
|
||||
|
||||
sleRoot = entryCreate(ltDIR_NODE, uRootIndex);
|
||||
|
||||
sleNode = sleRoot;
|
||||
}
|
||||
else
|
||||
{
|
||||
uNodeDir = sleRoot->getIFieldU64(sfIndexPrevious); // Get index to last directory node.
|
||||
|
||||
uint64 uNodePrevious = uNodeDir;
|
||||
uint256 uNodeIndex; // Index of node.
|
||||
|
||||
if (uNodeDir)
|
||||
{
|
||||
// Try adding to non-root.
|
||||
uNodeIndex = Ledger::getDirNodeIndex(uRootIndex, uNodeDir);
|
||||
lspRoot = lepNONE;
|
||||
sleNode = mLedger->getDirNode(lspRoot, uNodeIndex);
|
||||
sleNode = mLedger->getDirNode(lspRoot, Ledger::getDirNodeIndex(uRootIndex, uNodeDir));
|
||||
|
||||
assert(sleNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try adding to root.
|
||||
uNodeIndex = uRootIndex;
|
||||
// Try adding to root. Didn't have a previous set.
|
||||
sleNode = sleRoot;
|
||||
}
|
||||
|
||||
@@ -213,24 +208,33 @@ TransactionEngineResult TransactionEngine::dirAdd(
|
||||
}
|
||||
else
|
||||
{
|
||||
// Have old last point to new node, if it was not root.
|
||||
if (uNodeDir == 1)
|
||||
{
|
||||
// Previous node is root node.
|
||||
|
||||
sleRoot->setIFieldU64(sfIndexNext, uNodeDir);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Previous node is not root node.
|
||||
|
||||
lspRoot = lepNONE;
|
||||
SLE::pointer slePrevious = mLedger->getDirNode(lspRoot, Ledger::getDirNodeIndex(uRootIndex, uNodeDir-1));
|
||||
|
||||
slePrevious->setIFieldU64(sfIndexNext, uNodeDir);
|
||||
entryModify(slePrevious);
|
||||
|
||||
sleNode->setIFieldU64(sfIndexPrevious, uNodeDir-1);
|
||||
}
|
||||
|
||||
// Have root point to new node.
|
||||
sleRoot->setIFieldU64(sfIndexPrevious, uNodeDir);
|
||||
entryModify(sleRoot);
|
||||
|
||||
// Have old last point to new node, if it was not root.
|
||||
if (uNodePrevious)
|
||||
{
|
||||
// Previous node is not root node.
|
||||
sleNode->setIFieldU64(sfIndexNext, uNodeDir);
|
||||
entryModify(sleNode);
|
||||
}
|
||||
|
||||
// Create the new node.
|
||||
sleNode = entryCreate(ltDIR_NODE, Ledger::getDirNodeIndex(uRootIndex, uNodeDir));
|
||||
svIndexes = STVector256();
|
||||
sleNode = entryCreate(ltDIR_NODE, uNodeIndex);
|
||||
|
||||
if (uNodePrevious)
|
||||
sleNode->setIFieldU64(sfIndexPrevious, uNodePrevious);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,19 +249,20 @@ TransactionEngineResult TransactionEngine::dirAdd(
|
||||
return terSUCCESS;
|
||||
}
|
||||
|
||||
// --> bKeepRoot: True, if we never completely clean up, after we overflow the root node.
|
||||
// --> uNodeDir: Node containing entry.
|
||||
// --> uRootIndex: The index of the base of the directory. Nodes are based off of this.
|
||||
// --> uLedgerIndex: Value to add to directory.
|
||||
// Ledger must be in a state for this to work.
|
||||
TransactionEngineResult TransactionEngine::dirDelete(
|
||||
bool bKeepRoot,
|
||||
const uint64& uNodeDir,
|
||||
const uint256& uRootIndex,
|
||||
const uint256& uLedgerIndex)
|
||||
{
|
||||
uint64 uNodeCur = uNodeDir;
|
||||
uint256 uNodeIndex = Ledger::getDirNodeIndex(uRootIndex, uNodeCur);
|
||||
LedgerStateParms lspNode = lepNONE;
|
||||
SLE::pointer sleNode = mLedger->getDirNode(lspNode, uNodeIndex);
|
||||
SLE::pointer sleNode = mLedger->getDirNode(lspNode, uNodeCur ? Ledger::getDirNodeIndex(uRootIndex, uNodeCur) : uRootIndex);
|
||||
|
||||
assert(sleNode);
|
||||
|
||||
@@ -267,163 +272,154 @@ TransactionEngineResult TransactionEngine::dirDelete(
|
||||
|
||||
return terBAD_LEDGER;
|
||||
}
|
||||
else
|
||||
|
||||
STVector256 svIndexes = sleNode->getIFieldV256(sfIndexes);
|
||||
std::vector<uint256>& vuiIndexes = svIndexes.peekValue();
|
||||
std::vector<uint256>::iterator it;
|
||||
|
||||
it = std::find(vuiIndexes.begin(), vuiIndexes.end(), uLedgerIndex);
|
||||
|
||||
assert(vuiIndexes.end() != it);
|
||||
if (vuiIndexes.end() == it)
|
||||
{
|
||||
STVector256 svIndexes = sleNode->getIFieldV256(sfIndexes);
|
||||
std::vector<uint256>& vuiIndexes = svIndexes.peekValue();
|
||||
std::vector<uint256>::iterator it;
|
||||
assert(false);
|
||||
|
||||
it = std::find(vuiIndexes.begin(), vuiIndexes.end(), uLedgerIndex);
|
||||
Log(lsWARNING) << "dirDelete: node not mentioned";
|
||||
|
||||
assert(vuiIndexes.end() != it);
|
||||
if (vuiIndexes.end() == it)
|
||||
return terBAD_LEDGER;
|
||||
}
|
||||
|
||||
// Remove the element.
|
||||
if (vuiIndexes.size() > 1)
|
||||
*it = vuiIndexes[vuiIndexes.size()-1];
|
||||
|
||||
vuiIndexes.resize(vuiIndexes.size()-1);
|
||||
|
||||
sleNode->setIFieldV256(sfIndexes, svIndexes);
|
||||
entryModify(sleNode);
|
||||
|
||||
if (vuiIndexes.empty())
|
||||
{
|
||||
// May be able to delete nodes.
|
||||
uint64 uNodePrevious = sleNode->getIFieldU64(sfIndexPrevious);
|
||||
uint64 uNodeNext = sleNode->getIFieldU64(sfIndexNext);
|
||||
|
||||
if (!uNodeCur)
|
||||
{
|
||||
Log(lsWARNING) << "dirDelete: node not mentioned";
|
||||
// Just emptied root node.
|
||||
|
||||
return terBAD_LEDGER;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove the element.
|
||||
if (vuiIndexes.size() > 1)
|
||||
*it = vuiIndexes[vuiIndexes.size()-1];
|
||||
|
||||
vuiIndexes.resize(vuiIndexes.size()-1);
|
||||
|
||||
if (vuiIndexes.size() > 0)
|
||||
if (!uNodePrevious)
|
||||
{
|
||||
// Node is not being deleted.
|
||||
sleNode->setIFieldV256(sfIndexes, svIndexes);
|
||||
entryModify(sleNode);
|
||||
// Never overflowed the root node. Delete it.
|
||||
entryDelete(sleNode);
|
||||
}
|
||||
// Root overflowed.
|
||||
else if (bKeepRoot)
|
||||
{
|
||||
// Not allowed to delete root node, if it ever overflowed.
|
||||
|
||||
nothing();
|
||||
}
|
||||
else if (uNodePrevious != uNodeNext)
|
||||
{
|
||||
// Have multiple other nodes. Can't delete root node.
|
||||
|
||||
nothing();
|
||||
}
|
||||
else
|
||||
{
|
||||
bool bRootDirty = false;
|
||||
SLE::pointer sleRoot;
|
||||
// Have only a root node and a last node.
|
||||
LedgerStateParms lspLast = lepNONE;
|
||||
SLE::pointer sleLast = mLedger->getDirNode(lspLast, Ledger::getDirNodeIndex(uRootIndex, uNodeNext));
|
||||
|
||||
// May be able to delete nodes.
|
||||
if (uNodeCur)
|
||||
assert(sleLast);
|
||||
|
||||
if (sleLast->getIFieldV256(sfIndexes).peekValue().empty())
|
||||
{
|
||||
uint64 uNodePrevious = sleNode->getIFieldU64(sfIndexPrevious);
|
||||
uint64 uNodeNext = sleNode->getIFieldU64(sfIndexNext);
|
||||
// Both nodes are empty.
|
||||
|
||||
entryDelete(sleNode);
|
||||
|
||||
// Fix previous link.
|
||||
if (uNodePrevious)
|
||||
{
|
||||
LedgerStateParms lspPrevious = lepNONE;
|
||||
SLE::pointer slePrevious = mLedger->getDirNode(lspPrevious, Ledger::getDirNodeIndex(uRootIndex, uNodePrevious));
|
||||
|
||||
assert(slePrevious);
|
||||
if (!slePrevious)
|
||||
{
|
||||
Log(lsWARNING) << "dirDelete: previous node is missing";
|
||||
|
||||
return terBAD_LEDGER;
|
||||
}
|
||||
else if (uNodeNext)
|
||||
{
|
||||
slePrevious->setIFieldU64(sfIndexNext, uNodeNext);
|
||||
}
|
||||
else
|
||||
{
|
||||
slePrevious->makeIFieldAbsent(sfIndexNext);
|
||||
}
|
||||
entryModify(slePrevious);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read root.
|
||||
bRootDirty = true;
|
||||
|
||||
sleRoot = mLedger->getDirNode(lspNode, uRootIndex);
|
||||
|
||||
if (uNodeNext)
|
||||
{
|
||||
sleRoot->setIFieldU64(sfIndexNext, uNodeNext);
|
||||
}
|
||||
else
|
||||
{
|
||||
sleRoot->makeIFieldAbsent(sfIndexNext);
|
||||
}
|
||||
}
|
||||
|
||||
// Fix next link.
|
||||
if (uNodeNext)
|
||||
{
|
||||
LedgerStateParms lspNext = lepNONE;
|
||||
SLE::pointer sleNext = mLedger->getDirNode(lspNext, Ledger::getDirNodeIndex(uRootIndex, uNodeNext));
|
||||
|
||||
assert(sleNext);
|
||||
if (!sleNext)
|
||||
{
|
||||
Log(lsWARNING) << "dirDelete: next node is missing";
|
||||
|
||||
return terBAD_LEDGER;
|
||||
}
|
||||
else if (uNodeNext)
|
||||
{
|
||||
sleNext->setIFieldU64(sfIndexNext, uNodeNext);
|
||||
}
|
||||
else
|
||||
{
|
||||
sleNext->makeIFieldAbsent(sfIndexNext);
|
||||
}
|
||||
entryModify(sleNext);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read root.
|
||||
bRootDirty = true;
|
||||
|
||||
sleRoot = mLedger->getDirNode(lspNode, uRootIndex);
|
||||
|
||||
if (uNodePrevious)
|
||||
{
|
||||
sleRoot->setIFieldU64(sfIndexPrevious, uNodePrevious);
|
||||
}
|
||||
else
|
||||
{
|
||||
sleRoot->makeIFieldAbsent(sfIndexPrevious);
|
||||
}
|
||||
}
|
||||
|
||||
if (bRootDirty)
|
||||
{
|
||||
// Need to update sleRoot;
|
||||
uNodeCur = 0;
|
||||
|
||||
// If we might be able to delete root, load it.
|
||||
if (!uNodePrevious && !uNodeNext)
|
||||
vuiIndexes = svIndexes.peekValue();
|
||||
}
|
||||
entryDelete(sleNode); // Delete root.
|
||||
entryDelete(sleLast); // Delete last.
|
||||
}
|
||||
else
|
||||
{
|
||||
bRootDirty = true;
|
||||
}
|
||||
// Have an entry, can't delete.
|
||||
|
||||
if (!uNodeCur)
|
||||
{
|
||||
// Looking at root node.
|
||||
uint64 uRootPrevious = sleNode->getIFieldU64(sfIndexPrevious);
|
||||
uint64 uRootNext = sleNode->getIFieldU64(sfIndexNext);
|
||||
|
||||
if (!uRootPrevious && !uRootNext && vuiIndexes.empty())
|
||||
{
|
||||
entryDelete(sleRoot);
|
||||
}
|
||||
else if (bRootDirty)
|
||||
{
|
||||
entryModify(sleRoot);
|
||||
}
|
||||
nothing();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Just emptied a non-root node.
|
||||
else if (uNodeNext)
|
||||
{
|
||||
// Not root and not last node. Can delete node.
|
||||
|
||||
return terSUCCESS;
|
||||
LedgerStateParms lspPrevious = lepNONE;
|
||||
SLE::pointer slePrevious = mLedger->getDirNode(lspPrevious, uNodePrevious ? Ledger::getDirNodeIndex(uRootIndex, uNodePrevious) : uRootIndex);
|
||||
|
||||
assert(slePrevious);
|
||||
|
||||
LedgerStateParms lspNext = lepNONE;
|
||||
SLE::pointer sleNext = mLedger->getDirNode(lspNext, uNodeNext ? Ledger::getDirNodeIndex(uRootIndex, uNodeNext) : uRootIndex);
|
||||
|
||||
assert(sleNext);
|
||||
|
||||
if (!slePrevious)
|
||||
{
|
||||
Log(lsWARNING) << "dirDelete: previous node is missing";
|
||||
|
||||
return terBAD_LEDGER;
|
||||
}
|
||||
|
||||
assert(sleNext);
|
||||
if (!sleNext)
|
||||
{
|
||||
Log(lsWARNING) << "dirDelete: next node is missing";
|
||||
|
||||
return terBAD_LEDGER;
|
||||
}
|
||||
|
||||
// Fix previous to point to its new next.
|
||||
slePrevious->setIFieldU64(sfIndexNext, uNodeNext);
|
||||
entryModify(slePrevious);
|
||||
|
||||
// Fix next to point to its new previous.
|
||||
sleNext->setIFieldU64(sfIndexPrevious, uNodePrevious);
|
||||
entryModify(sleNext);
|
||||
}
|
||||
// Last node.
|
||||
else if (bKeepRoot || uNodePrevious)
|
||||
{
|
||||
// Not allowed to delete last node as root was overflowed.
|
||||
// Or, have pervious entries preventing complete delete.
|
||||
|
||||
nothing();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Last and only node besides the root.
|
||||
LedgerStateParms lspRoot = lepNONE;
|
||||
SLE::pointer sleRoot = mLedger->getDirNode(lspRoot, uRootIndex);
|
||||
|
||||
assert(sleRoot);
|
||||
|
||||
if (sleRoot->getIFieldV256(sfIndexes).peekValue().empty())
|
||||
{
|
||||
// Both nodes are empty.
|
||||
|
||||
entryDelete(sleRoot); // Delete root.
|
||||
entryDelete(sleNode); // Delete last.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Root has an entry, can't delete.
|
||||
|
||||
nothing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return terSUCCESS;
|
||||
}
|
||||
|
||||
// Set the authorized public ket for an account. May also set the generator map.
|
||||
@@ -498,6 +494,8 @@ bool TransactionEngine::entryExists(SLE::pointer sleEntry)
|
||||
|
||||
SLE::pointer TransactionEngine::entryCreate(LedgerEntryType letType, const uint256& uIndex)
|
||||
{
|
||||
assert(!uIndex.isZero());
|
||||
|
||||
SLE::pointer sleNew = boost::make_shared<SerializedLedgerEntry>(letType);
|
||||
|
||||
sleNew->setIndex(uIndex);
|
||||
@@ -509,6 +507,7 @@ SLE::pointer TransactionEngine::entryCreate(LedgerEntryType letType, const uint2
|
||||
|
||||
void TransactionEngine::entryDelete(SLE::pointer sleEntry)
|
||||
{
|
||||
assert(sleEntry);
|
||||
entryMap::const_iterator it = mEntries.find(sleEntry);
|
||||
|
||||
switch (it == mEntries.end() ? taaNONE : it->second)
|
||||
@@ -531,6 +530,7 @@ void TransactionEngine::entryDelete(SLE::pointer sleEntry)
|
||||
|
||||
void TransactionEngine::entryModify(SLE::pointer sleEntry)
|
||||
{
|
||||
assert(sleEntry);
|
||||
entryMap::const_iterator it = mEntries.find(sleEntry);
|
||||
|
||||
switch (it == mEntries.end() ? taaNONE : it->second)
|
||||
@@ -553,6 +553,7 @@ void TransactionEngine::entryModify(SLE::pointer sleEntry)
|
||||
|
||||
void TransactionEngine::entryUnfunded(SLE::pointer sleEntry)
|
||||
{
|
||||
assert(sleEntry);
|
||||
entryMap::const_iterator it = mEntries.find(sleEntry);
|
||||
|
||||
switch (it == mEntries.end() ? taaNONE : it->second)
|
||||
@@ -1216,7 +1217,7 @@ TransactionEngineResult TransactionEngine::doCreditSet(const SerializedTransacti
|
||||
// Zero balance and eliminating last limit.
|
||||
|
||||
bDelIndex = true;
|
||||
terResult = dirDelete(uSrcRef, Ledger::getRippleDirIndex(uSrcAccountID), sleRippleState->getIndex());
|
||||
terResult = dirDelete(true, uSrcRef, Ledger::getRippleDirIndex(uSrcAccountID), sleRippleState->getIndex());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -2236,12 +2237,12 @@ TransactionEngineResult TransactionEngine::doOfferCancel(const SerializedTransac
|
||||
uint64 uBookNode = sleOffer->getIFieldU64(sfBookNode);
|
||||
uint256 uDirectory = sleOffer->getIFieldH256(sfDirectory);
|
||||
|
||||
terResult = dirDelete(uOwnerNode, Ledger::getOwnerDirIndex(uSrcAccountID), uLedgerIndex);
|
||||
terResult = dirDelete(true, uOwnerNode, Ledger::getOwnerDirIndex(uSrcAccountID), uLedgerIndex);
|
||||
|
||||
// if (terSUCCESS == terResult)
|
||||
// {
|
||||
// terResult = dirDelete(uBookNode, uDirectory, uLedgerIndex);
|
||||
// }
|
||||
if (terSUCCESS == terResult)
|
||||
{
|
||||
terResult = dirDelete(false, uBookNode, uDirectory, uLedgerIndex);
|
||||
}
|
||||
|
||||
entryDelete(sleOffer);
|
||||
}
|
||||
|
||||
@@ -114,6 +114,7 @@ private:
|
||||
const uint256& uLedgerIndex);
|
||||
|
||||
TransactionEngineResult dirDelete(
|
||||
bool bKeepRoot,
|
||||
const uint64& uNodeDir, // Node item is mentioned in.
|
||||
const uint256& uRootIndex,
|
||||
const uint256& uLedgerIndex); // Item being deleted
|
||||
|
||||
Reference in New Issue
Block a user