diff --git a/src/ripple/app/ledger/Ledger.cpp b/src/ripple/app/ledger/Ledger.cpp index 7757dac53bf..7552f755c6e 100644 --- a/src/ripple/app/ledger/Ledger.cpp +++ b/src/ripple/app/ledger/Ledger.cpp @@ -266,7 +266,7 @@ Ledger::Ledger( { info_.hash = calculateLedgerHash(info_); if (acquire && !config.reporting()) - family.missingNode(info_.hash, info_.seq); + family.missingNodeAcquireByHash(info_.hash, info_.seq); } } diff --git a/src/ripple/shamap/Family.h b/src/ripple/shamap/Family.h index 72c9a6cb07a..fea5545d31c 100644 --- a/src/ripple/shamap/Family.h +++ b/src/ripple/shamap/Family.h @@ -75,11 +75,23 @@ class Family virtual bool isShardBacked() const = 0; + /** Acquire ledger that has a missing node by ledger sequence + * + * Throw if in reporting mode. + * + * @param refNum Sequence of ledger to acquire. + * @param nodeHash Hash of missing node to report in throw. + */ virtual void - missingNode(std::uint32_t refNum) = 0; + missingNodeAcquireBySeq(std::uint32_t refNum, uint256 const& nodeHash) = 0; + /** Acquire ledger that has a missing node by ledger hash + * + * @param refHash Hash of ledger to acquire. + * @param refNum Ledger sequence with missing node. + */ virtual void - missingNode(uint256 const& refHash, std::uint32_t refNum) = 0; + missingNodeAcquireByHash(uint256 const& refHash, std::uint32_t refNum) = 0; virtual void reset() = 0; diff --git a/src/ripple/shamap/NodeFamily.h b/src/ripple/shamap/NodeFamily.h index 2d8236705b5..f20abccce9d 100644 --- a/src/ripple/shamap/NodeFamily.h +++ b/src/ripple/shamap/NodeFamily.h @@ -83,10 +83,10 @@ class NodeFamily : public Family reset() override; void - missingNode(std::uint32_t seq) override; + missingNodeAcquireBySeq(std::uint32_t seq, uint256 const& hash) override; void - missingNode(uint256 const& hash, std::uint32_t seq) override + missingNodeAcquireByHash(uint256 const& hash, std::uint32_t seq) override { acquire(hash, seq); } diff --git a/src/ripple/shamap/ShardFamily.h b/src/ripple/shamap/ShardFamily.h index 550efeb5b81..de809cf589c 100644 --- a/src/ripple/shamap/ShardFamily.h +++ b/src/ripple/shamap/ShardFamily.h @@ -89,10 +89,11 @@ class ShardFamily : public Family reset() override; void - missingNode(std::uint32_t seq) override; + missingNodeAcquireBySeq(std::uint32_t seq, uint256 const& nodeHash) + override; void - missingNode(uint256 const& hash, std::uint32_t seq) override + missingNodeAcquireByHash(uint256 const& hash, std::uint32_t seq) override { acquire(hash, seq); } diff --git a/src/ripple/shamap/impl/NodeFamily.cpp b/src/ripple/shamap/impl/NodeFamily.cpp index f9c6dedb265..1752db06a8e 100644 --- a/src/ripple/shamap/impl/NodeFamily.cpp +++ b/src/ripple/shamap/impl/NodeFamily.cpp @@ -21,6 +21,7 @@ #include #include #include +#include namespace ripple { @@ -65,9 +66,16 @@ NodeFamily::reset() } void -NodeFamily::missingNode(std::uint32_t seq) +NodeFamily::missingNodeAcquireBySeq(std::uint32_t seq, uint256 const& nodeHash) { JLOG(j_.error()) << "Missing node in " << seq; + if (app_.config().reporting()) + { + std::stringstream ss; + ss << "Node not read, likely a Cassandra error in ledger seq " << seq + << " object hash " << nodeHash; + Throw(ss.str()); + } std::unique_lock lock(maxSeqMutex_); if (maxSeq_ == 0) diff --git a/src/ripple/shamap/impl/SHAMap.cpp b/src/ripple/shamap/impl/SHAMap.cpp index 1a5a283dd3c..fa42c8e8f82 100644 --- a/src/ripple/shamap/impl/SHAMap.cpp +++ b/src/ripple/shamap/impl/SHAMap.cpp @@ -173,30 +173,40 @@ SHAMap::finishFetch( std::shared_ptr const& object) const { assert(backed_); - if (!object) - { - if (full_) - { - full_ = false; - f_.missingNode(ledgerSeq_); - } - return {}; - } std::shared_ptr node; try { + if (!object) + { + if (full_) + { + full_ = false; + f_.missingNodeAcquireBySeq(ledgerSeq_, hash.as_uint256()); + } + return {}; + } + node = SHAMapTreeNode::makeFromPrefix(makeSlice(object->getData()), hash); if (node) canonicalize(hash, node); return node; } - catch (std::exception const&) + catch (SHAMapMissingNode const& e) + { + JLOG(journal_.warn()) << "Missing node: " << hash << " : " << e.what(); + } + catch (std::runtime_error const& e) + { + JLOG(journal_.warn()) << e.what(); + } + catch (...) { JLOG(journal_.warn()) << "Invalid DB node " << hash; - return std::shared_ptr(); } + + return std::shared_ptr(); } // See if a sync filter has a node diff --git a/src/ripple/shamap/impl/ShardFamily.cpp b/src/ripple/shamap/impl/ShardFamily.cpp index eadfc42aa27..f22d4152e2b 100644 --- a/src/ripple/shamap/impl/ShardFamily.cpp +++ b/src/ripple/shamap/impl/ShardFamily.cpp @@ -22,6 +22,7 @@ #include #include #include +#include namespace ripple { @@ -152,8 +153,9 @@ ShardFamily::reset() } void -ShardFamily::missingNode(std::uint32_t seq) +ShardFamily::missingNodeAcquireBySeq(std::uint32_t seq, uint256 const& nodeHash) { + std::ignore = nodeHash; JLOG(j_.error()) << "Missing node in ledger sequence " << seq; std::unique_lock lock(maxSeqMutex_); diff --git a/src/test/shamap/common.h b/src/test/shamap/common.h index c4238b2a65f..d89acb988d7 100644 --- a/src/test/shamap/common.h +++ b/src/test/shamap/common.h @@ -105,13 +105,15 @@ class TestNodeFamily : public Family } void - missingNode(std::uint32_t refNum) override + missingNodeAcquireBySeq(std::uint32_t refNum, uint256 const& nodeHash) + override { Throw("missing node"); } void - missingNode(uint256 const& refHash, std::uint32_t refNum) override + missingNodeAcquireByHash(uint256 const& refHash, std::uint32_t refNum) + override { Throw("missing node"); }