mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-01 16:35:53 +00:00
test: Unit tests to recreate invalid index logic error (#5242)
* One hits the global cache, one does not. * Also some extra checking. Co-authored-by: Bronek Kozicki <brok@incorrekt.com>
This commit is contained in:
@@ -16,11 +16,15 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <test/jtx.h>
|
||||
#include <test/jtx/check.h>
|
||||
#include <test/jtx/envconfig.h>
|
||||
#include <xrpld/app/ledger/LedgerMaster.h>
|
||||
#include <xrpld/app/tx/apply.h>
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/basics/StringUtilities.h>
|
||||
#include <xrpl/json/json_reader.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
|
||||
namespace ripple {
|
||||
@@ -247,6 +251,80 @@ struct Regression_test : public beast::unit_test::suite
|
||||
jrReader.parse(jvRequest, buffers) && jvRequest.isObject());
|
||||
}
|
||||
|
||||
void
|
||||
testInvalidTxObjectIDType()
|
||||
{
|
||||
testcase("Invalid Transaction Object ID Type");
|
||||
// Crasher bug introduced in 2.0.1. Fixed in 2.3.0.
|
||||
|
||||
using namespace jtx;
|
||||
Env env(*this);
|
||||
|
||||
Account alice("alice");
|
||||
Account bob("bob");
|
||||
env.fund(XRP(10'000), alice, bob);
|
||||
env.close();
|
||||
|
||||
{
|
||||
auto const alice_index = keylet::account(alice).key;
|
||||
if (BEAST_EXPECT(alice_index.isNonZero()))
|
||||
{
|
||||
env(check::cash(
|
||||
alice, alice_index, check::DeliverMin(XRP(100))),
|
||||
ter(tecNO_ENTRY));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto const bob_index = keylet::account(bob).key;
|
||||
|
||||
auto const digest = [&]() -> std::optional<uint256> {
|
||||
auto const& state =
|
||||
env.app().getLedgerMaster().getClosedLedger()->stateMap();
|
||||
SHAMapHash digest;
|
||||
if (!state.peekItem(bob_index, digest))
|
||||
return std::nullopt;
|
||||
return digest.as_uint256();
|
||||
}();
|
||||
|
||||
auto const mapCounts = [&](CountedObjects::List const& list) {
|
||||
std::map<std::string, int> result;
|
||||
for (auto const& e : list)
|
||||
{
|
||||
result[e.first] = e.second;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
if (BEAST_EXPECT(bob_index.isNonZero()) &&
|
||||
BEAST_EXPECT(digest.has_value()))
|
||||
{
|
||||
auto& cache = env.app().cachedSLEs();
|
||||
cache.del(*digest, false);
|
||||
auto const beforeCounts =
|
||||
mapCounts(CountedObjects::getInstance().getCounts(0));
|
||||
|
||||
env(check::cash(alice, bob_index, check::DeliverMin(XRP(100))),
|
||||
ter(tecNO_ENTRY));
|
||||
|
||||
auto const afterCounts =
|
||||
mapCounts(CountedObjects::getInstance().getCounts(0));
|
||||
|
||||
using namespace std::string_literals;
|
||||
BEAST_EXPECT(
|
||||
beforeCounts.at("CachedView::hit"s) ==
|
||||
afterCounts.at("CachedView::hit"s));
|
||||
BEAST_EXPECT(
|
||||
beforeCounts.at("CachedView::hitExpired"s) + 1 ==
|
||||
afterCounts.at("CachedView::hitExpired"s));
|
||||
BEAST_EXPECT(
|
||||
beforeCounts.at("CachedView::miss"s) ==
|
||||
afterCounts.at("CachedView::miss"s));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
@@ -256,6 +334,7 @@ struct Regression_test : public beast::unit_test::suite
|
||||
testFeeEscalationAutofill();
|
||||
testFeeEscalationExtremeConfig();
|
||||
testJsonInvalid();
|
||||
testInvalidTxObjectIDType();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -57,6 +57,10 @@ CachedViewImpl::read(Keylet const& k) const
|
||||
baseRead = true;
|
||||
return base_.read(k);
|
||||
});
|
||||
// If the sle is null, then a failure must have occurred in base_.read()
|
||||
XRPL_ASSERT(
|
||||
sle || baseRead,
|
||||
"ripple::CachedView::read : null SLE result from base");
|
||||
if (cacheHit && baseRead)
|
||||
hitsexpired.increment();
|
||||
else if (cacheHit)
|
||||
|
||||
Reference in New Issue
Block a user