diff --git a/src/data/AmendmentCenter.cpp b/src/data/AmendmentCenter.cpp index eb7c14eae..4863ff0e5 100644 --- a/src/data/AmendmentCenter.cpp +++ b/src/data/AmendmentCenter.cpp @@ -146,9 +146,12 @@ AmendmentCenter::isEnabled(AmendmentKey const& key, uint32_t seq) const bool AmendmentCenter::isEnabled(boost::asio::yield_context yield, AmendmentKey const& key, uint32_t seq) const { - if (auto const listAmendments = fetchAmendmentsList(yield, seq); listAmendments) - return lookupAmendment(all_, *listAmendments, key); - + try { + if (auto const listAmendments = fetchAmendmentsList(yield, seq); listAmendments) + return lookupAmendment(all_, *listAmendments, key); + } catch (std::runtime_error const&) { + return false; // Some old ledger does not contain Amendments ledger object so do best we can for now + } return false; } @@ -157,13 +160,19 @@ AmendmentCenter::isEnabled(boost::asio::yield_context yield, std::vector out; - rg::transform(keys, std::back_inserter(out), [this, &listAmendments](auto const& key) { - return lookupAmendment(all_, *listAmendments, key); - }); + try { + if (auto const listAmendments = fetchAmendmentsList(yield, seq); listAmendments) { + std::vector out; + rg::transform(keys, std::back_inserter(out), [this, &listAmendments](auto const& key) { + return lookupAmendment(all_, *listAmendments, key); + }); - return out; + return out; + } + } catch (std::runtime_error const&) { + return std::vector( + keys.size(), false + ); // Some old ledger does not contain Amendments ledger object so do best we can for now } return std::vector(keys.size(), false); diff --git a/tests/unit/data/AmendmentCenterTests.cpp b/tests/unit/data/AmendmentCenterTests.cpp index 18bb2e6bb..c5d2b1d48 100644 --- a/tests/unit/data/AmendmentCenterTests.cpp +++ b/tests/unit/data/AmendmentCenterTests.cpp @@ -104,16 +104,13 @@ TEST_F(AmendmentCenterTest, IsMultipleEnabled) }); } -TEST_F(AmendmentCenterTest, IsEnabledThrowsWhenUnavailable) +TEST_F(AmendmentCenterTest, IsEnabledReturnsFalseWhenAmendmentsLedgerObjectUnavailable) { EXPECT_CALL(*backend_, doFetchLedgerObject(ripple::keylet::amendments().key, kSEQ, testing::_)) .WillOnce(testing::Return(std::nullopt)); runSpawn([this](auto yield) { - EXPECT_THROW( - { [[maybe_unused]] auto const result = amendmentCenter.isEnabled(yield, "irrelevant", kSEQ); }, - std::runtime_error - ); + EXPECT_NO_THROW(EXPECT_FALSE(amendmentCenter.isEnabled(yield, "irrelevant", kSEQ))); }); } @@ -126,6 +123,21 @@ TEST_F(AmendmentCenterTest, IsEnabledReturnsFalseWhenNoAmendments) runSpawn([this](auto yield) { EXPECT_FALSE(amendmentCenter.isEnabled(yield, "irrelevant", kSEQ)); }); } +TEST_F(AmendmentCenterTest, IsEnabledReturnsVectorOfFalseWhenAmendmentsLedgerObjectUnavailable) +{ + EXPECT_CALL(*backend_, doFetchLedgerObject(ripple::keylet::amendments().key, kSEQ, testing::_)) + .WillOnce(testing::Return(std::nullopt)); + + runSpawn([this](auto yield) { + std::vector const keys{"fixUniversalNumber", "ImmediateOfferKilled"}; + std::vector vec; + EXPECT_NO_THROW(vec = amendmentCenter.isEnabled(yield, keys, kSEQ)); + + EXPECT_EQ(vec.size(), keys.size()); + EXPECT_TRUE(std::ranges::all_of(vec, std::logical_not<>{})); + }); +} + TEST_F(AmendmentCenterTest, IsEnabledReturnsVectorOfFalseWhenNoAmendments) { auto const amendments = createBrokenAmendmentsObject();