Fixes and simplifications.

This commit is contained in:
JoelKatz
2013-04-26 00:11:44 -07:00
parent 4812d30c16
commit 7f4d76808b
6 changed files with 79 additions and 99 deletions

View File

@@ -37,7 +37,7 @@ bool HashedObjectStore::store(HashedObjectType type, uint32 index,
{ // return: false = already in cache, true = added to cache
if (!theApp->getHashNodeDB())
{
cLog(lsTRACE) << "HOS: no db";
cLog(lsWARNING) << "HOS: no db";
return true;
}
if (mCache.touch(hash))
@@ -50,7 +50,7 @@ bool HashedObjectStore::store(HashedObjectType type, uint32 index,
HashedObject::pointer object = boost::make_shared<HashedObject>(type, index, data, hash);
if (!mCache.canonicalize(hash, object))
{
Serializer s(1 + (32 / 8) + (32 / 8) + data.size());
Serializer s(9 + data.size());
s.add8(static_cast<unsigned char>(type));
s.add32(index);
s.add32(index);
@@ -63,6 +63,8 @@ bool HashedObjectStore::store(HashedObjectType type, uint32 index,
assert(false);
}
}
else
cLog(lsDEBUG) << "HOS: store race";
return true;
}
@@ -77,12 +79,18 @@ HashedObject::pointer HashedObjectStore::retrieve(const uint256& hash)
return obj;
if (!theApp || !theApp->getHashNodeDB())
{
cLog(lsWARNING) << "HOS: no db";
return obj;
}
std::string sData;
leveldb::Status st = theApp->getHashNodeDB()->Get(leveldb::ReadOptions(), hash.GetHex(), &sData);
if (!st.ok())
{
assert(st.IsNotFound());
return obj;
}
Serializer s(sData);

View File

@@ -960,7 +960,10 @@ void LedgerAcquireMaster::gotLedgerData(Job&, uint256 hash,
cLog(lsWARNING) << "Included TXbase invalid";
}
if (!san.isInvalid())
{
ledger->progress();
ledger->trigger(peer);
}
else
cLog(lsDEBUG) << "Peer sends invalid base data";
return;
@@ -996,7 +999,10 @@ void LedgerAcquireMaster::gotLedgerData(Job&, uint256 hash,
else
ledger->takeAsNode(nodeIDs, nodeData, ret);
if (!ret.isInvalid())
{
ledger->progress();
ledger->trigger(peer);
}
else
cLog(lsDEBUG) << "Peer sends invalid node data";
return;

View File

@@ -267,6 +267,7 @@ void LedgerConsensus::checkLCL()
void LedgerConsensus::handleLCL(const uint256& lclHash)
{
assert((lclHash != mPrevLedgerHash) || (mPreviousLedger->getHash() != lclHash));
if (mPrevLedgerHash != lclHash)
{ // first time switching to this ledger
mPrevLedgerHash = lclHash;
@@ -286,30 +287,35 @@ void LedgerConsensus::handleLCL(const uint256& lclHash)
playbackProposals();
}
if (mPreviousLedger->getHash() != mPrevLedgerHash)
{ // we need to switch the ledger we're working from
if (mPreviousLedger->getHash() == mPrevLedgerHash)
return;
// we need to switch the ledger we're working from
Ledger::pointer newLCL = theApp->getLedgerMaster().getLedgerByHash(lclHash);
if (newLCL)
{
assert(newLCL->isClosed());
assert(newLCL->isImmutable());
assert(newLCL->getHash() == lclHash);
mPreviousLedger = newLCL;
mPrevLedgerHash = newLCL->getHash();
mPrevLedgerHash = lclHash;
}
else if (!mAcquiringLedger || (mAcquiringLedger->getHash() != mPrevLedgerHash))
{ // need to start acquiring the correct consensus LCL
cLog(lsWARNING) << "Need consensus ledger " << mPrevLedgerHash;
if (mAcquiringLedger)
theApp->getMasterLedgerAcquire().dropLedger(mAcquiringLedger->getHash());
mAcquiringLedger = theApp->getMasterLedgerAcquire().findCreate(mPrevLedgerHash, 0);
mHaveCorrectLCL = false;
return;
}
}
cLog(lsINFO) << "Have the consensus ledger " << mPrevLedgerHash;
mHaveCorrectLCL = true;
#if 0 // FIXME: can trigger early
if (mAcquiringLedger && mAcquiringLedger->isComplete())
theApp->getOPs().clearNeedNetworkLedger();
#endif
mCloseResolution = ContinuousLedgerTiming::getNextLedgerTimeResolution(
mPreviousLedger->getCloseResolution(), mPreviousLedger->getCloseAgree(),
mPreviousLedger->getLedgerSeq() + 1);

View File

@@ -236,6 +236,31 @@ SHAMapTreeNode* SHAMap::getNodePointer(const SHAMapNode& id, const uint256& hash
return fetchNodeExternal(id, hash).get();
}
SHAMapTreeNode* SHAMap::getNodePointer(const SHAMapNode& id, const uint256& hash, SHAMapSyncFilter* filter)
{
try
{
return getNodePointer(id, hash);
}
catch (SHAMapMissingNode)
{
if (filter)
{
std::vector<unsigned char> nodeData;
if (filter->haveNode(id, hash, nodeData))
{
SHAMapTreeNode::pointer node = boost::make_shared<SHAMapTreeNode>(
boost::cref(id), boost::cref(nodeData), mSeq - 1, snfPREFIX, boost::cref(hash), true);
mTNByID[id] = node;
filter->gotNode(true, id, hash, nodeData, node->getType());
return node.get();
}
}
throw;
}
}
void SHAMap::returnNode(SHAMapTreeNode::pointer& node, bool modify)
{ // make sure the node is suitable for the intended operation (copy on write)
assert(node->isValid());

View File

@@ -369,6 +369,7 @@ protected:
SHAMapTreeNode::pointer getNode(const SHAMapNode& id);
SHAMapTreeNode::pointer getNode(const SHAMapNode& id, const uint256& hash, bool modify);
SHAMapTreeNode* getNodePointer(const SHAMapNode& id, const uint256& hash);
SHAMapTreeNode* getNodePointer(const SHAMapNode& id, const uint256& hash, SHAMapSyncFilter* filter);
SHAMapTreeNode* firstBelow(SHAMapTreeNode*);
SHAMapTreeNode* lastBelow(SHAMapTreeNode*);

View File

@@ -58,38 +58,21 @@ void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint2
SHAMapTreeNode* d = NULL;
try
{
d = getNodePointer(childID, childHash);
d = getNodePointer(childID, childHash, filter);
if (d->isInner() && !d->isFullBelow())
{
have_all = false;
stack.push(d);
}
}
catch (SHAMapMissingNode&)
{ // node is not in the map
if (filter != NULL)
{
std::vector<unsigned char> nodeData;
if (filter->haveNode(childID, childHash, nodeData))
{
assert(mSeq >= 1);
SHAMapTreeNode::pointer ptr =
boost::make_shared<SHAMapTreeNode>(childID, nodeData, mSeq - 1,
snfPREFIX, childHash, true);
mTNByID[*ptr] = ptr;
d = ptr.get();
filter->gotNode(true, childID, childHash, nodeData, ptr->getType());
}
}
}
if (!d)
{ // we need this node
nodeIDs.push_back(childID);
hashes.push_back(childHash);
if (--max <= 0)
return;
have_all = false;
}
else if (d->isInner() && !d->isFullBelow()) // we might need children of this node
{
have_all = false;
stack.push(d);
}
}
}
}
@@ -142,32 +125,15 @@ std::vector<uint256> SHAMap::getNeededHashes(int max, SHAMapSyncFilter* filter)
SHAMapTreeNode* d = NULL;
try
{
d = getNodePointer(childID, childHash);
assert(d);
}
catch (SHAMapMissingNode&)
{ // node is not in the map
std::vector<unsigned char> nodeData;
if (filter && filter->haveNode(childID, childHash, nodeData))
{
SHAMapTreeNode::pointer ptr =
boost::make_shared<SHAMapTreeNode>(childID, nodeData, mSeq -1,
snfPREFIX, childHash, true);
mTNByID[*ptr] = ptr;
d = ptr.get();
filter->gotNode(true, childID, childHash, nodeData, ptr->getType());
}
}
if (d)
{
d = getNodePointer(childID, childHash, filter);
if (d->isInner() && !d->isFullBelow())
{
have_all = false;
stack.push(d);
}
}
else
{
catch (SHAMapMissingNode&)
{ // node is not in the map
have_all = false;
ret.push_back(childHash);
if (--max <= 0)
@@ -340,11 +306,8 @@ SMAddNode SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigne
return SMAddNode::okay();
SHAMapTreeNode* iNode = root.get();
while (!iNode->isLeaf() && !iNode->isFullBelow())
while (!iNode->isLeaf() && !iNode->isFullBelow() && (iNode->getDepth() < node.getDepth()))
{
if (iNode->isLeaf() || iNode->isFullBelow() || (iNode->getDepth() >= node.getDepth()))
return SMAddNode::okay();
int branch = iNode->selectBranch(node.getNodeID());
assert(branch >= 0);
@@ -358,7 +321,7 @@ SMAddNode SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigne
try
{
iNode = getNodePointer(iNode->getChildNodeID(branch), iNode->getChildHash(branch));
iNode = getNodePointer(iNode->getChildNodeID(branch), iNode->getChildHash(branch), filter);
}
catch (SHAMapMissingNode)
{
@@ -374,6 +337,7 @@ SMAddNode SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigne
boost::make_shared<SHAMapTreeNode>(node, rawNode, mSeq - 1, snfWIRE, uZero, false);
if (iNode->getChildHash(branch) != newNode->getNodeHash())
{
cLog(lsWARNING) << "Corrupt node recevied";
return SMAddNode::invalid();
}
@@ -384,41 +348,11 @@ SMAddNode SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigne
filter->gotNode(false, node, iNode->getChildHash(branch), s.peekData(), newNode->getType());
}
mTNByID[node] = newNode;
if (!newNode->isLeaf()) // only a leaf can fill an inner node
return SMAddNode::useful();
try
{
for (int i = 0; i < 16; ++i)
{ // does the parent still need more nodes
if (!iNode->isEmptyBranch(i) && !fullBelowCache.isPresent(iNode->getChildHash(i)))
{
SHAMapTreeNode* d = getNodePointer(iNode->getChildNodeID(i), iNode->getChildHash(i));
if (d->isInner() && !d->isFullBelow()) // unfilled inner node
return SMAddNode::useful();
}
}
}
catch (SHAMapMissingNode)
{ // still missing something
return SMAddNode::useful();
}
// received leaf fills its parent
iNode->setFullBelow();
if (mType == smtSTATE)
{
fullBelowCache.add(iNode->getNodeHash());
dropBelow(iNode);
}
if (root->isFullBelow())
clearSynching();
return SMAddNode::useful();
}
}
cLog(lsTRACE) << "got inner node, already had it (late)";
cLog(lsTRACE) << "got node, already had it (late)";
return SMAddNode::okay();
}