Reduce (ab)use of exceptions.

This commit is contained in:
JoelKatz
2013-06-11 16:55:23 -07:00
parent 46e31c425d
commit d1af075b29
5 changed files with 74 additions and 83 deletions

View File

@@ -65,27 +65,15 @@ Ledger::Ledger (uint256 const& parentHash,
updateHash(); updateHash();
loaded = true; loaded = true;
try if (mTransHash.isNonZero() && !mTransactionMap->fetchRoot(mTransHash, NULL))
{
if (mTransHash.isNonZero())
mTransactionMap->fetchRoot(mTransHash, NULL);
}
catch (...)
{ {
loaded = false; loaded = false;
WriteLog (lsWARNING, Ledger) << "Don't have TX root for ledger"; WriteLog (lsWARNING, Ledger) << "Don't have TX root for ledger";
} }
try if (mAccountHash.isNonZero() && !mAccountStateMap->fetchRoot(mAccountHash, NULL))
{
if (mAccountHash.isNonZero())
mAccountStateMap->fetchRoot(mAccountHash, NULL);
}
catch (...)
{ {
loaded = false; loaded = false;
WriteLog (lsWARNING, Ledger) << "Don't have AS root for ledger"; WriteLog (lsWARNING, Ledger) << "Don't have AS root for ledger";
} }

View File

@@ -77,10 +77,9 @@ bool LedgerAcquire::tryLocal()
} }
else else
{ {
try TransactionStateSF filter(mLedger->getLedgerSeq());
if (mLedger->peekTransactionMap()->fetchRoot(mLedger->getTransHash(), &filter))
{ {
TransactionStateSF filter(mLedger->getLedgerSeq());
mLedger->peekTransactionMap()->fetchRoot(mLedger->getTransHash(), &filter);
WriteLog (lsTRACE, LedgerAcquire) << "Got root txn map locally"; WriteLog (lsTRACE, LedgerAcquire) << "Got root txn map locally";
std::vector<uint256> h = mLedger->getNeededTransactionHashes(1, &filter); std::vector<uint256> h = mLedger->getNeededTransactionHashes(1, &filter);
if (h.empty()) if (h.empty())
@@ -89,9 +88,6 @@ bool LedgerAcquire::tryLocal()
mHaveTransactions = true; mHaveTransactions = true;
} }
} }
catch (SHAMapMissingNode&)
{
}
} }
} }
@@ -104,10 +100,9 @@ bool LedgerAcquire::tryLocal()
} }
else else
{ {
try AccountStateSF filter(mLedger->getLedgerSeq());
if (mLedger->peekAccountStateMap()->fetchRoot(mLedger->getAccountHash(), &filter))
{ {
AccountStateSF filter(mLedger->getLedgerSeq());
mLedger->peekAccountStateMap()->fetchRoot(mLedger->getAccountHash(), &filter);
WriteLog (lsTRACE, LedgerAcquire) << "Got root AS map locally"; WriteLog (lsTRACE, LedgerAcquire) << "Got root AS map locally";
std::vector<uint256> h = mLedger->getNeededAccountStateHashes(1, &filter); std::vector<uint256> h = mLedger->getNeededAccountStateHashes(1, &filter);
if (h.empty()) if (h.empty())
@@ -116,9 +111,6 @@ bool LedgerAcquire::tryLocal()
mHaveState = true; mHaveState = true;
} }
} }
catch (SHAMapMissingNode&)
{
}
} }
} }

View File

@@ -203,36 +203,46 @@ SHAMapTreeNode::pointer SHAMap::getNode(const SHAMapNode& id, uint256 const& has
} }
SHAMapTreeNode* SHAMap::getNodePointer(const SHAMapNode& id, uint256 const& hash) SHAMapTreeNode* SHAMap::getNodePointer(const SHAMapNode& id, uint256 const& hash)
{ // fast, but you do not hold a reference
SHAMapTreeNode* ret = getNodePointerNT(id, hash);
if (!ret)
throw SHAMapMissingNode(mType, id, hash);
return ret;
}
SHAMapTreeNode* SHAMap::getNodePointerNT(const SHAMapNode& id, uint256 const& hash)
{ // fast, but you do not hold a reference { // fast, but you do not hold a reference
boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer>::iterator it = mTNByID.find(id); boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer>::iterator it = mTNByID.find(id);
if (it != mTNByID.end()) if (it != mTNByID.end())
return it->second.get(); return it->second.get();
return fetchNodeExternal(id, hash).get(); return fetchNodeExternalNT(id, hash).get();
} }
SHAMapTreeNode* SHAMap::getNodePointer(const SHAMapNode& id, uint256 const& hash, SHAMapSyncFilter* filter) SHAMapTreeNode* SHAMap::getNodePointer(const SHAMapNode& id, uint256 const& hash, SHAMapSyncFilter* filter)
{ {
try SHAMapTreeNode* ret = getNodePointerNT(id, hash, filter);
if (!ret)
throw SHAMapMissingNode(mType, id, hash);
return ret;
}
SHAMapTreeNode* SHAMap::getNodePointerNT(const SHAMapNode& id, uint256 const& hash, SHAMapSyncFilter* filter)
{
SHAMapTreeNode* node = getNodePointerNT(id, hash);
if (!node && filter)
{ {
return getNodePointer(id, hash); Blob nodeData;
} if (filter->haveNode(id, hash, nodeData))
catch (SHAMapMissingNode)
{
if (filter)
{ {
Blob nodeData; SHAMapTreeNode::pointer node = boost::make_shared<SHAMapTreeNode>(
if (filter->haveNode(id, hash, nodeData)) boost::cref(id), boost::cref(nodeData), mSeq - 1, snfPREFIX, boost::cref(hash), true);
{ mTNByID[id] = node;
SHAMapTreeNode::pointer node = boost::make_shared<SHAMapTreeNode>( filter->gotNode(true, id, hash, nodeData, node->getType());
boost::cref(id), boost::cref(nodeData), mSeq - 1, snfPREFIX, boost::cref(hash), true); return node.get();
mTNByID[id] = node;
filter->gotNode(true, id, hash, nodeData, node->getType());
return node.get();
}
} }
throw;
} }
return node;
} }
@@ -692,8 +702,18 @@ void SHAMapItem::dump()
SHAMapTreeNode::pointer SHAMap::fetchNodeExternal(const SHAMapNode& id, uint256 const& hash) SHAMapTreeNode::pointer SHAMap::fetchNodeExternal(const SHAMapNode& id, uint256 const& hash)
{ {
if (!theApp->running()) SHAMapTreeNode::pointer ret = fetchNodeExternalNT(id, hash);
if (!ret)
throw SHAMapMissingNode(mType, id, hash); throw SHAMapMissingNode(mType, id, hash);
return ret;
}
SHAMapTreeNode::pointer SHAMap::fetchNodeExternalNT(const SHAMapNode& id, uint256 const& hash)
{
SHAMapTreeNode::pointer ret;
if (!theApp->running())
return ret;
HashedObject::pointer obj(theApp->getHashedObjectStore().retrieve(hash)); HashedObject::pointer obj(theApp->getHashedObjectStore().retrieve(hash));
if (!obj) if (!obj)
@@ -704,13 +724,12 @@ SHAMapTreeNode::pointer SHAMap::fetchNodeExternal(const SHAMapNode& id, uint256
theApp->getOPs().missingNodeInLedger(mLedgerSeq); theApp->getOPs().missingNodeInLedger(mLedgerSeq);
mLedgerSeq = 0; mLedgerSeq = 0;
} }
throw SHAMapMissingNode(mType, id, hash); return ret;
} }
try try
{ {
SHAMapTreeNode::pointer ret = ret = boost::make_shared<SHAMapTreeNode>(id, obj->getData(), mSeq, snfPREFIX, hash, true);
boost::make_shared<SHAMapTreeNode>(id, obj->getData(), mSeq, snfPREFIX, hash, true);
if (id != *ret) if (id != *ret)
{ {
WriteLog (lsFATAL, SHAMap) << "id:" << id << ", got:" << *ret; WriteLog (lsFATAL, SHAMap) << "id:" << id << ", got:" << *ret;
@@ -733,14 +752,14 @@ SHAMapTreeNode::pointer SHAMap::fetchNodeExternal(const SHAMapNode& id, uint256
catch (...) catch (...)
{ {
WriteLog (lsWARNING, SHAMap) << "fetchNodeExternal gets an invalid node: " << hash; WriteLog (lsWARNING, SHAMap) << "fetchNodeExternal gets an invalid node: " << hash;
throw SHAMapMissingNode(mType, id, hash); return SHAMapTreeNode::pointer();
} }
} }
void SHAMap::fetchRoot(uint256 const& hash, SHAMapSyncFilter* filter) bool SHAMap::fetchRoot(uint256 const& hash, SHAMapSyncFilter* filter)
{ {
if (hash == root->getNodeHash()) if (hash == root->getNodeHash())
return; return true;
if (ShouldLog (lsTRACE, SHAMap)) if (ShouldLog (lsTRACE, SHAMap))
{ {
if (mType == smtTRANSACTION) if (mType == smtTRANSACTION)
@@ -750,21 +769,19 @@ void SHAMap::fetchRoot(uint256 const& hash, SHAMapSyncFilter* filter)
else else
WriteLog (lsTRACE, SHAMap) << "Fetch root SHAMap node " << hash; WriteLog (lsTRACE, SHAMap) << "Fetch root SHAMap node " << hash;
} }
try root = fetchNodeExternalNT(SHAMapNode(), hash);
{ if (!root)
root = fetchNodeExternal(SHAMapNode(), hash);
}
catch (SHAMapMissingNode&)
{ {
Blob nodeData; Blob nodeData;
if (!filter || !filter->haveNode(SHAMapNode(), hash, nodeData)) if (!filter || !filter->haveNode(SHAMapNode(), hash, nodeData))
throw; return false;
root = boost::make_shared<SHAMapTreeNode>(SHAMapNode(), nodeData, root = boost::make_shared<SHAMapTreeNode>(SHAMapNode(), nodeData,
mSeq - 1, snfPREFIX, hash, true); mSeq - 1, snfPREFIX, hash, true);
mTNByID[*root] = root; mTNByID[*root] = root;
filter->gotNode(true, SHAMapNode(), hash, nodeData, root->getType()); filter->gotNode(true, SHAMapNode(), hash, nodeData, root->getType());
} }
assert(root->getNodeHash() == hash); assert(root->getNodeHash() == hash);
return true;
} }
int SHAMap::armDirty() int SHAMap::armDirty()

View File

@@ -41,7 +41,7 @@ public:
ScopedLock Lock() const { return ScopedLock(mLock); } ScopedLock Lock() const { return ScopedLock(mLock); }
bool hasNode(const SHAMapNode& id); bool hasNode(const SHAMapNode& id);
void fetchRoot(uint256 const& hash, SHAMapSyncFilter* filter); bool fetchRoot(uint256 const& hash, SHAMapSyncFilter* filter);
// normal hash access functions // normal hash access functions
bool hasItem(uint256 const& id); bool hasItem(uint256 const& id);
@@ -104,7 +104,8 @@ public:
uint32 getSeq() { return mSeq; } uint32 getSeq() { return mSeq; }
// overloads for backed maps // overloads for backed maps
boost::shared_ptr<SHAMapTreeNode> fetchNodeExternal(const SHAMapNode& id, uint256 const& hash); boost::shared_ptr<SHAMapTreeNode> fetchNodeExternal(const SHAMapNode& id, uint256 const& hash); // throws
boost::shared_ptr<SHAMapTreeNode> fetchNodeExternalNT(const SHAMapNode& id, uint256 const& hash); // no throw
bool operator==(const SHAMap& s) { return getHash() == s.getHash(); } bool operator==(const SHAMap& s) { return getHash() == s.getHash(); }
@@ -143,7 +144,9 @@ private:
SHAMapTreeNode::pointer getNode(const SHAMapNode& id); SHAMapTreeNode::pointer getNode(const SHAMapNode& id);
SHAMapTreeNode::pointer getNode(const SHAMapNode& id, uint256 const& hash, bool modify); SHAMapTreeNode::pointer getNode(const SHAMapNode& id, uint256 const& hash, bool modify);
SHAMapTreeNode* getNodePointer(const SHAMapNode& id, uint256 const& hash); SHAMapTreeNode* getNodePointer(const SHAMapNode& id, uint256 const& hash);
SHAMapTreeNode* getNodePointerNT(const SHAMapNode& id, uint256 const& hash);
SHAMapTreeNode* getNodePointer(const SHAMapNode& id, uint256 const& hash, SHAMapSyncFilter* filter); SHAMapTreeNode* getNodePointer(const SHAMapNode& id, uint256 const& hash, SHAMapSyncFilter* filter);
SHAMapTreeNode* getNodePointerNT(const SHAMapNode& id, uint256 const& hash, SHAMapSyncFilter* filter);
SHAMapTreeNode* firstBelow(SHAMapTreeNode*); SHAMapTreeNode* firstBelow(SHAMapTreeNode*);
SHAMapTreeNode* lastBelow(SHAMapTreeNode*); SHAMapTreeNode* lastBelow(SHAMapTreeNode*);

View File

@@ -43,17 +43,8 @@ void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint2
if (!fullBelowCache.isPresent(childHash)) if (!fullBelowCache.isPresent(childHash))
{ {
SHAMapNode childID = node->getChildNodeID(branch); SHAMapNode childID = node->getChildNodeID(branch);
SHAMapTreeNode* d = NULL; SHAMapTreeNode* d = getNodePointerNT(childID, childHash, filter);
try if (!d)
{
d = getNodePointer(childID, childHash, filter);
if (d->isInner() && !d->isFullBelow())
{
have_all = false;
stack.push(d);
}
}
catch (SHAMapMissingNode&)
{ // node is not in the map { // node is not in the map
nodeIDs.push_back(childID); nodeIDs.push_back(childID);
hashes.push_back(childHash); hashes.push_back(childHash);
@@ -61,6 +52,11 @@ void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint2
return; return;
have_all = false; have_all = false;
} }
else if (d->isInner() && !d->isFullBelow())
{
have_all = false;
stack.push(d);
}
} }
} }
} }
@@ -110,23 +106,19 @@ std::vector<uint256> SHAMap::getNeededHashes(int max, SHAMapSyncFilter* filter)
if (!fullBelowCache.isPresent(childHash)) if (!fullBelowCache.isPresent(childHash))
{ {
SHAMapNode childID = node->getChildNodeID(branch); SHAMapNode childID = node->getChildNodeID(branch);
SHAMapTreeNode* d = NULL; SHAMapTreeNode* d = getNodePointerNT(childID, childHash, filter);
try if (!d)
{ {
d = getNodePointer(childID, childHash, filter);
if (d->isInner() && !d->isFullBelow())
{
have_all = false;
stack.push(d);
}
}
catch (SHAMapMissingNode&)
{ // node is not in the map
have_all = false; have_all = false;
ret.push_back(childHash); ret.push_back(childHash);
if (--max <= 0) if (--max <= 0)
return ret; return ret;
} }
else if (d->isInner() && !d->isFullBelow())
{
have_all = false;
stack.push(d);
}
} }
} }
} }
@@ -270,8 +262,7 @@ SHAMapAddNode SHAMap::addRootNode(uint256 const& hash, Blob const& rootNode, SHA
return SHAMapAddNode::useful(); return SHAMapAddNode::useful();
} }
SHAMapAddNode SHAMap::addKnownNode(const SHAMapNode& node, Blob const& rawNode, SHAMapAddNode SHAMap::addKnownNode(const SHAMapNode& node, Blob const& rawNode, SHAMapSyncFilter* filter)
SHAMapSyncFilter* filter)
{ // return value: true=okay, false=error { // return value: true=okay, false=error
assert(!node.isRoot()); assert(!node.isRoot());
if (!isSynching()) if (!isSynching())
@@ -303,7 +294,7 @@ SHAMapAddNode SHAMap::addKnownNode(const SHAMapNode& node, Blob const& rawNode,
{ {
iNode = getNodePointer(iNode->getChildNodeID(branch), iNode->getChildHash(branch), filter); iNode = getNodePointer(iNode->getChildNodeID(branch), iNode->getChildHash(branch), filter);
} }
catch (SHAMapMissingNode) catch (SHAMapMissingNode&)
{ {
if (iNode->getDepth() != (node.getDepth() - 1)) if (iNode->getDepth() != (node.getDepth() - 1))
{ // Either this node is broken or we didn't request it (yet) { // Either this node is broken or we didn't request it (yet)