Merge branch 'master' of github.com:jedmccaleb/NewCoin

This commit is contained in:
Arthur Britto
2013-01-04 16:02:08 -08:00
6 changed files with 139 additions and 5 deletions

View File

@@ -538,7 +538,24 @@ Ledger::pointer Ledger::loadByHash(const uint256& ledgerHash)
std::string sql="SELECT * from Ledgers WHERE LedgerHash='";
sql.append(ledgerHash.GetHex());
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()

View File

@@ -175,18 +175,21 @@ void LedgerAcquire::done()
#endif
std::vector< boost::function<void (LedgerAcquire::pointer)> > triggers;
setComplete();
assert(isComplete() || isFailed());
mLock.lock();
triggers = mOnComplete;
mOnComplete.clear();
mLock.unlock();
if (mLedger)
if (isComplete() && mLedger)
{
if (mAccept)
mLedger->setAccepted();
theApp->getLedgerMaster().storeLedger(mLedger);
}
else if (isFailed())
theApp->getMasterLedgerAcquire().logFailure(mHash);
for (unsigned int i = 0; i < triggers.size(); ++i)
triggers[i](shared_from_this());
@@ -528,6 +531,21 @@ LedgerAcquire::pointer LedgerAcquireMaster::find(const uint256& hash)
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)
{
assert(hash.isNonZero());
@@ -621,4 +639,36 @@ SMAddNode LedgerAcquireMaster::gotLedgerData(ripple::TMLedgerData& packet, Peer:
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

View File

@@ -108,6 +108,8 @@ public:
void trigger(Peer::ref, bool timer);
bool tryLocal();
void addPeers();
std::vector<uint256> getNeededHashes();
};
class LedgerAcquireMaster
@@ -115,6 +117,7 @@ class LedgerAcquireMaster
protected:
boost::mutex mLock;
std::map<uint256, LedgerAcquire::pointer> mLedgers;
std::map<uint256, time_t> mRecentFailures;
public:
LedgerAcquireMaster() { ; }
@@ -124,6 +127,9 @@ public:
bool hasLedger(const uint256& ledgerHash);
void dropLedger(const uint256& ledgerHash);
SMAddNode gotLedgerData(ripple::TMLedgerData& packet, Peer::ref);
void logFailure(const uint256&);
bool isFailure(const uint256&);
};
#endif

View File

@@ -170,6 +170,11 @@ void LedgerMaster::acquireMissingLedger(const uint256& ledgerHash, uint32 ledger
mMissingLedger.reset();
return;
}
else if (mMissingLedger->isDone())
{
mMissingLedger.reset();
return;
}
mMissingSeq = ledgerSeq;
if (mMissingLedger->setAccept())
mMissingLedger->addOnComplete(boost::bind(&LedgerMaster::missingAcquireComplete, this, _1));
@@ -290,7 +295,11 @@ void LedgerMaster::setFullLedger(Ledger::ref ledger)
}
if (mMissingLedger && mMissingLedger->isDone())
{
if (mMissingLedger->isFailed())
theApp->getMasterLedgerAcquire().dropLedger(mMissingLedger->getHash());
mMissingLedger.reset();
}
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;
theApp->getJobQueue().addJob(jtPUBLEDGER, boost::bind(&LedgerMaster::pubThread, this));

View File

@@ -413,6 +413,7 @@ public:
bool getNodeFat(const SHAMapNode& node, std::vector<SHAMapNode>& nodeIDs,
std::list<std::vector<unsigned char> >& rawNode, bool fatRoot, bool fatLeaves);
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,
SHAMapSyncFilter* filter);
SMAddNode addRootNode(const std::vector<unsigned char>& rootNode, SHANodeFormat format,

View File

@@ -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,
std::list<std::vector<unsigned char> >& rawNodes, bool fatRoot, bool fatLeaves)
{ // Gets a node and some of its children