mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-03 01:15:53 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
@@ -538,7 +538,24 @@ Ledger::pointer Ledger::loadByHash(const uint256& ledgerHash)
|
|||||||
std::string sql="SELECT * from Ledgers WHERE LedgerHash='";
|
std::string sql="SELECT * from Ledgers WHERE LedgerHash='";
|
||||||
sql.append(ledgerHash.GetHex());
|
sql.append(ledgerHash.GetHex());
|
||||||
sql.append("';");
|
sql.append("';");
|
||||||
return getSQL(sql);
|
Ledger::pointer ret = getSQL(sql);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
HashedObject::pointer node = theApp->getHashedObjectStore().retrieve(ledgerHash);
|
||||||
|
if (!node)
|
||||||
|
return Ledger::pointer();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Ledger::pointer ledger = boost::make_shared<Ledger>(strCopy(node->getData()), true);
|
||||||
|
if (ledger->getHash() == ledgerHash)
|
||||||
|
return ledger;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
cLog(lsDEBUG) << "Exception trying to load ledger by hash: " << ledgerHash;
|
||||||
|
return Ledger::pointer();
|
||||||
|
}
|
||||||
|
return Ledger::pointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ledger::pointer Ledger::getLastFullLedger()
|
Ledger::pointer Ledger::getLastFullLedger()
|
||||||
|
|||||||
@@ -175,18 +175,21 @@ void LedgerAcquire::done()
|
|||||||
#endif
|
#endif
|
||||||
std::vector< boost::function<void (LedgerAcquire::pointer)> > triggers;
|
std::vector< boost::function<void (LedgerAcquire::pointer)> > triggers;
|
||||||
|
|
||||||
setComplete();
|
assert(isComplete() || isFailed());
|
||||||
|
|
||||||
mLock.lock();
|
mLock.lock();
|
||||||
triggers = mOnComplete;
|
triggers = mOnComplete;
|
||||||
mOnComplete.clear();
|
mOnComplete.clear();
|
||||||
mLock.unlock();
|
mLock.unlock();
|
||||||
|
|
||||||
if (mLedger)
|
if (isComplete() && mLedger)
|
||||||
{
|
{
|
||||||
if (mAccept)
|
if (mAccept)
|
||||||
mLedger->setAccepted();
|
mLedger->setAccepted();
|
||||||
theApp->getLedgerMaster().storeLedger(mLedger);
|
theApp->getLedgerMaster().storeLedger(mLedger);
|
||||||
}
|
}
|
||||||
|
else if (isFailed())
|
||||||
|
theApp->getMasterLedgerAcquire().logFailure(mHash);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < triggers.size(); ++i)
|
for (unsigned int i = 0; i < triggers.size(); ++i)
|
||||||
triggers[i](shared_from_this());
|
triggers[i](shared_from_this());
|
||||||
@@ -528,6 +531,21 @@ LedgerAcquire::pointer LedgerAcquireMaster::find(const uint256& hash)
|
|||||||
return LedgerAcquire::pointer();
|
return LedgerAcquire::pointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<uint256> LedgerAcquire::getNeededHashes()
|
||||||
|
{
|
||||||
|
std::vector<uint256> ret;
|
||||||
|
if (!mHaveBase)
|
||||||
|
{
|
||||||
|
ret.push_back(mHash);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (!mHaveState)
|
||||||
|
mLedger->peekAccountStateMap()->getNeededHashes(ret, 16);
|
||||||
|
if (!mHaveTransactions)
|
||||||
|
mLedger->peekTransactionMap()->getNeededHashes(ret, 16);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool LedgerAcquireMaster::hasLedger(const uint256& hash)
|
bool LedgerAcquireMaster::hasLedger(const uint256& hash)
|
||||||
{
|
{
|
||||||
assert(hash.isNonZero());
|
assert(hash.isNonZero());
|
||||||
@@ -621,4 +639,36 @@ SMAddNode LedgerAcquireMaster::gotLedgerData(ripple::TMLedgerData& packet, Peer:
|
|||||||
return SMAddNode::invalid();
|
return SMAddNode::invalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LedgerAcquireMaster::logFailure(const uint256& hash)
|
||||||
|
{
|
||||||
|
time_t now = time(NULL);
|
||||||
|
boost::mutex::scoped_lock sl(mLock);
|
||||||
|
|
||||||
|
std::map<uint256, time_t>::iterator it = mRecentFailures.begin();
|
||||||
|
while (it != mRecentFailures.end())
|
||||||
|
{
|
||||||
|
if (it->first == hash)
|
||||||
|
{
|
||||||
|
it->second = now;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (it->second > now)
|
||||||
|
{ // time jump or discontinuity
|
||||||
|
it->second = now;
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
else if ((it->second + 180) < now)
|
||||||
|
mRecentFailures.erase(it++);
|
||||||
|
else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
mRecentFailures[hash] = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LedgerAcquireMaster::isFailure(const uint256& hash)
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock sl(mLock);
|
||||||
|
return mRecentFailures.find(hash) != mRecentFailures.end();
|
||||||
|
}
|
||||||
|
|
||||||
// vim:ts=4
|
// vim:ts=4
|
||||||
|
|||||||
@@ -108,6 +108,8 @@ public:
|
|||||||
void trigger(Peer::ref, bool timer);
|
void trigger(Peer::ref, bool timer);
|
||||||
bool tryLocal();
|
bool tryLocal();
|
||||||
void addPeers();
|
void addPeers();
|
||||||
|
|
||||||
|
std::vector<uint256> getNeededHashes();
|
||||||
};
|
};
|
||||||
|
|
||||||
class LedgerAcquireMaster
|
class LedgerAcquireMaster
|
||||||
@@ -115,6 +117,7 @@ class LedgerAcquireMaster
|
|||||||
protected:
|
protected:
|
||||||
boost::mutex mLock;
|
boost::mutex mLock;
|
||||||
std::map<uint256, LedgerAcquire::pointer> mLedgers;
|
std::map<uint256, LedgerAcquire::pointer> mLedgers;
|
||||||
|
std::map<uint256, time_t> mRecentFailures;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LedgerAcquireMaster() { ; }
|
LedgerAcquireMaster() { ; }
|
||||||
@@ -124,6 +127,9 @@ public:
|
|||||||
bool hasLedger(const uint256& ledgerHash);
|
bool hasLedger(const uint256& ledgerHash);
|
||||||
void dropLedger(const uint256& ledgerHash);
|
void dropLedger(const uint256& ledgerHash);
|
||||||
SMAddNode gotLedgerData(ripple::TMLedgerData& packet, Peer::ref);
|
SMAddNode gotLedgerData(ripple::TMLedgerData& packet, Peer::ref);
|
||||||
|
|
||||||
|
void logFailure(const uint256&);
|
||||||
|
bool isFailure(const uint256&);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -170,6 +170,11 @@ void LedgerMaster::acquireMissingLedger(const uint256& ledgerHash, uint32 ledger
|
|||||||
mMissingLedger.reset();
|
mMissingLedger.reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (mMissingLedger->isDone())
|
||||||
|
{
|
||||||
|
mMissingLedger.reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
mMissingSeq = ledgerSeq;
|
mMissingSeq = ledgerSeq;
|
||||||
if (mMissingLedger->setAccept())
|
if (mMissingLedger->setAccept())
|
||||||
mMissingLedger->addOnComplete(boost::bind(&LedgerMaster::missingAcquireComplete, this, _1));
|
mMissingLedger->addOnComplete(boost::bind(&LedgerMaster::missingAcquireComplete, this, _1));
|
||||||
@@ -290,7 +295,11 @@ void LedgerMaster::setFullLedger(Ledger::ref ledger)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mMissingLedger && mMissingLedger->isDone())
|
if (mMissingLedger && mMissingLedger->isDone())
|
||||||
|
{
|
||||||
|
if (mMissingLedger->isFailed())
|
||||||
|
theApp->getMasterLedgerAcquire().dropLedger(mMissingLedger->getHash());
|
||||||
mMissingLedger.reset();
|
mMissingLedger.reset();
|
||||||
|
}
|
||||||
|
|
||||||
if (mMissingLedger || !theConfig.LEDGER_HISTORY)
|
if (mMissingLedger || !theConfig.LEDGER_HISTORY)
|
||||||
{
|
{
|
||||||
@@ -397,7 +406,7 @@ void LedgerMaster::checkPublish(const uint256& hash, uint32 seq)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mPubThread)
|
if (!mPubLedgers.empty() && !mPubThread)
|
||||||
{
|
{
|
||||||
mPubThread = true;
|
mPubThread = true;
|
||||||
theApp->getJobQueue().addJob(jtPUBLEDGER, boost::bind(&LedgerMaster::pubThread, this));
|
theApp->getJobQueue().addJob(jtPUBLEDGER, boost::bind(&LedgerMaster::pubThread, this));
|
||||||
|
|||||||
@@ -413,6 +413,7 @@ public:
|
|||||||
bool getNodeFat(const SHAMapNode& node, std::vector<SHAMapNode>& nodeIDs,
|
bool getNodeFat(const SHAMapNode& node, std::vector<SHAMapNode>& nodeIDs,
|
||||||
std::list<std::vector<unsigned char> >& rawNode, bool fatRoot, bool fatLeaves);
|
std::list<std::vector<unsigned char> >& rawNode, bool fatRoot, bool fatLeaves);
|
||||||
bool getRootNode(Serializer& s, SHANodeFormat format);
|
bool getRootNode(Serializer& s, SHANodeFormat format);
|
||||||
|
void getNeededHashes(std::vector<uint256>& hashes, int max);
|
||||||
SMAddNode addRootNode(const uint256& hash, const std::vector<unsigned char>& rootNode, SHANodeFormat format,
|
SMAddNode addRootNode(const uint256& hash, const std::vector<unsigned char>& rootNode, SHANodeFormat format,
|
||||||
SHAMapSyncFilter* filter);
|
SHAMapSyncFilter* filter);
|
||||||
SMAddNode addRootNode(const std::vector<unsigned char>& rootNode, SHANodeFormat format,
|
SMAddNode addRootNode(const std::vector<unsigned char>& rootNode, SHANodeFormat format,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint2
|
|||||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||||
|
|
||||||
assert(root->isValid());
|
assert(root->isValid());
|
||||||
|
|
||||||
if (root->isFullBelow())
|
if (root->isFullBelow())
|
||||||
{
|
{
|
||||||
clearSynching();
|
clearSynching();
|
||||||
@@ -91,6 +91,57 @@ void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint2
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHAMap::getNeededHashes(std::vector<uint256>& ret, int max)
|
||||||
|
{
|
||||||
|
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||||
|
|
||||||
|
assert(root->isValid());
|
||||||
|
|
||||||
|
if (root->isFullBelow() || !root->isInner())
|
||||||
|
{
|
||||||
|
clearSynching();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stack<SHAMapTreeNode*> stack;
|
||||||
|
stack.push(root.get());
|
||||||
|
|
||||||
|
while (!stack.empty())
|
||||||
|
{
|
||||||
|
SHAMapTreeNode* node = stack.top();
|
||||||
|
stack.pop();
|
||||||
|
|
||||||
|
int base = rand() % 256;
|
||||||
|
bool have_all = false;
|
||||||
|
for (int ii = 0; ii < 16; ++ii)
|
||||||
|
{ // traverse in semi-random order
|
||||||
|
int branch = (base + ii) % 16;
|
||||||
|
if (!node->isEmptyBranch(branch))
|
||||||
|
{
|
||||||
|
SHAMapNode childID = node->getChildNodeID(branch);
|
||||||
|
const uint256& childHash = node->getChildHash(branch);
|
||||||
|
SHAMapTreeNode* d;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
d = getNodePointer(childID, childHash);
|
||||||
|
assert(d);
|
||||||
|
if (d->isInner() && !d->isFullBelow())
|
||||||
|
stack.push(d);
|
||||||
|
}
|
||||||
|
catch (SHAMapMissingNode&)
|
||||||
|
{ // node is not in the map
|
||||||
|
have_all = false;
|
||||||
|
ret.push_back(childHash);
|
||||||
|
if (--max <= 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (have_all)
|
||||||
|
node->setFullBelow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool SHAMap::getNodeFat(const SHAMapNode& wanted, std::vector<SHAMapNode>& nodeIDs,
|
bool SHAMap::getNodeFat(const SHAMapNode& wanted, std::vector<SHAMapNode>& nodeIDs,
|
||||||
std::list<std::vector<unsigned char> >& rawNodes, bool fatRoot, bool fatLeaves)
|
std::list<std::vector<unsigned char> >& rawNodes, bool fatRoot, bool fatLeaves)
|
||||||
{ // Gets a node and some of its children
|
{ // Gets a node and some of its children
|
||||||
|
|||||||
Reference in New Issue
Block a user