mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-05 01:37:00 +00:00
* XRPLF/develop: docs: Add --parallel flag to cmake build commands in BUILD.md (7302) fix: Fix wrong hybrid offer orderbook placement and update `LedgerStateFix` to amend `ExchangeRate` meta (7087) style: More clang-tidy identifier renaming (7290) fix: Update pDEX invariant firing under a valid offer deletion (7118) fix: Fix multisign and signfor to check for delegate (7064) refactor: Fix `sfGeneric` and `sfInvalid` field names (7300) docs: Fix some comments to improve readability (7122) feat: Propagate underlying MPT flags to vault shares (7077)
205 lines
6.9 KiB
C++
205 lines
6.9 KiB
C++
#include <test/jtx/Account.h>
|
|
#include <test/jtx/Env.h>
|
|
#include <test/jtx/amount.h>
|
|
#include <test/jtx/envconfig.h>
|
|
#include <test/jtx/noop.h>
|
|
|
|
#include <xrpld/app/ledger/LedgerMaster.h>
|
|
#include <xrpld/app/misc/SHAMapStore.h>
|
|
#include <xrpld/core/Config.h>
|
|
|
|
#include <xrpl/basics/ToString.h>
|
|
#include <xrpl/basics/base_uint.h>
|
|
#include <xrpl/beast/unit_test/suite.h>
|
|
#include <xrpl/protocol/Feature.h>
|
|
#include <xrpl/protocol/Protocol.h>
|
|
#include <xrpl/protocol/SField.h>
|
|
#include <xrpl/protocol/STObject.h>
|
|
#include <xrpl/protocol/STTx.h>
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <sstream>
|
|
#include <vector>
|
|
|
|
namespace xrpl::test {
|
|
|
|
class LedgerMaster_test : public beast::unit_test::Suite
|
|
{
|
|
static std::unique_ptr<Config>
|
|
makeNetworkConfig(uint32_t networkID)
|
|
{
|
|
using namespace jtx;
|
|
return envconfig([&](std::unique_ptr<Config> cfg) {
|
|
cfg->networkId = networkID;
|
|
// This test relies on ledger hash so must lock it to fee 10.
|
|
cfg->fees.referenceFee = 10;
|
|
return cfg;
|
|
});
|
|
}
|
|
|
|
void
|
|
testTxnIdFromIndex(FeatureBitset features)
|
|
{
|
|
testcase("tx_id_from_index");
|
|
|
|
using namespace test::jtx;
|
|
using namespace std::literals;
|
|
|
|
test::jtx::Env env{*this, makeNetworkConfig(11111)};
|
|
|
|
auto const alice = Account("alice");
|
|
env.fund(XRP(1000), alice);
|
|
env.close();
|
|
|
|
// build ledgers
|
|
std::vector<std::shared_ptr<STTx const>> txns;
|
|
std::vector<std::shared_ptr<STObject const>> metas;
|
|
auto const startLegSeq = env.current()->header().seq;
|
|
for (int i = 0; i < 2; ++i)
|
|
{
|
|
env(noop(alice));
|
|
txns.emplace_back(env.tx());
|
|
env.close();
|
|
metas.emplace_back(env.closed()->txRead(env.tx()->getTransactionID()).second);
|
|
}
|
|
// add last (empty) ledger
|
|
env.close();
|
|
auto const endLegSeq = env.closed()->header().seq;
|
|
|
|
// test invalid range
|
|
{
|
|
std::uint32_t const ledgerSeq = -1;
|
|
std::uint32_t const txnIndex = 0;
|
|
auto result = env.app().getLedgerMaster().txnIdFromIndex(ledgerSeq, txnIndex);
|
|
BEAST_EXPECT(!result);
|
|
}
|
|
// test not in ledger
|
|
{
|
|
uint32_t const txnIndex = metas[0]->getFieldU32(sfTransactionIndex);
|
|
auto result = env.app().getLedgerMaster().txnIdFromIndex(0, txnIndex);
|
|
BEAST_EXPECT(!result);
|
|
}
|
|
// test empty ledger
|
|
{
|
|
auto result = env.app().getLedgerMaster().txnIdFromIndex(endLegSeq, 0);
|
|
BEAST_EXPECT(!result);
|
|
}
|
|
// ended without result
|
|
{
|
|
uint32_t const txnIndex = metas[0]->getFieldU32(sfTransactionIndex);
|
|
auto result = env.app().getLedgerMaster().txnIdFromIndex(endLegSeq + 1, txnIndex);
|
|
BEAST_EXPECT(!result);
|
|
}
|
|
// success (first tx)
|
|
{
|
|
uint32_t const txnIndex = metas[0]->getFieldU32(sfTransactionIndex);
|
|
auto result = env.app().getLedgerMaster().txnIdFromIndex(startLegSeq, txnIndex);
|
|
BEAST_EXPECT(
|
|
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
|
*result ==
|
|
uint256(
|
|
"277F4FD89C20B92457FEF05FF63F6405563AD0563C73D967A29727"
|
|
"72679ADC65"));
|
|
}
|
|
// success (second tx)
|
|
{
|
|
uint32_t const txnIndex = metas[1]->getFieldU32(sfTransactionIndex);
|
|
auto result = env.app().getLedgerMaster().txnIdFromIndex(startLegSeq + 1, txnIndex);
|
|
BEAST_EXPECT(
|
|
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
|
*result ==
|
|
uint256(
|
|
"293DF7335EBBAF4420D52E70ABF470EB4C5792CAEA2F91F76193C2"
|
|
"819F538FDE"));
|
|
}
|
|
}
|
|
|
|
void
|
|
testCompleteLedgerRange(FeatureBitset features)
|
|
{
|
|
// Note that this test is intentionally very similar to
|
|
// SHAMapStore_test::testLedgerGaps, but has a different
|
|
// focus.
|
|
|
|
testcase("Complete Ledger operations");
|
|
|
|
using namespace test::jtx;
|
|
|
|
auto const deleteInterval = 8;
|
|
|
|
Env env{*this, envconfig([](auto cfg) {
|
|
return online_delete(std::move(cfg), deleteInterval);
|
|
})};
|
|
|
|
auto const alice = Account("alice");
|
|
env.fund(XRP(1000), alice);
|
|
env.close();
|
|
|
|
auto& lm = env.app().getLedgerMaster();
|
|
LedgerIndex minSeq = 2;
|
|
LedgerIndex maxSeq = env.closed()->header().seq;
|
|
auto& store = env.app().getSHAMapStore();
|
|
store.rendezvous();
|
|
LedgerIndex lastRotated = store.getLastRotated();
|
|
BEAST_EXPECTS(maxSeq == 3, to_string(maxSeq));
|
|
BEAST_EXPECTS(lm.getCompleteLedgers() == "2-3", lm.getCompleteLedgers());
|
|
BEAST_EXPECTS(lastRotated == 3, to_string(lastRotated));
|
|
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq, maxSeq) == 0);
|
|
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq + 1, maxSeq - 1) == 0);
|
|
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq - 1, maxSeq + 1) == 2);
|
|
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq - 2, maxSeq - 2) == 2);
|
|
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq + 2, maxSeq + 2) == 2);
|
|
|
|
// Close enough ledgers to rotate a few times
|
|
for (int i = 0; i < 24; ++i)
|
|
{
|
|
for (int t = 0; t < 3; ++t)
|
|
{
|
|
env(noop(alice));
|
|
}
|
|
env.close();
|
|
store.rendezvous();
|
|
|
|
++maxSeq;
|
|
|
|
if (maxSeq == lastRotated + deleteInterval)
|
|
{
|
|
minSeq = lastRotated;
|
|
lastRotated = maxSeq;
|
|
}
|
|
BEAST_EXPECTS(
|
|
env.closed()->header().seq == maxSeq, to_string(env.closed()->header().seq));
|
|
BEAST_EXPECTS(store.getLastRotated() == lastRotated, to_string(store.getLastRotated()));
|
|
std::stringstream expectedRange;
|
|
expectedRange << minSeq << "-" << maxSeq;
|
|
BEAST_EXPECTS(lm.getCompleteLedgers() == expectedRange.str(), lm.getCompleteLedgers());
|
|
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq, maxSeq) == 0);
|
|
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq + 1, maxSeq - 1) == 0);
|
|
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq - 1, maxSeq + 1) == 2);
|
|
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq - 2, maxSeq - 2) == 2);
|
|
BEAST_EXPECT(lm.missingFromCompleteLedgerRange(minSeq + 2, maxSeq + 2) == 2);
|
|
}
|
|
}
|
|
|
|
public:
|
|
void
|
|
run() override
|
|
{
|
|
using namespace test::jtx;
|
|
FeatureBitset const all{testableAmendments()};
|
|
testWithFeats(all);
|
|
}
|
|
|
|
void
|
|
testWithFeats(FeatureBitset features)
|
|
{
|
|
testTxnIdFromIndex(features);
|
|
testCompleteLedgerRange(features);
|
|
}
|
|
};
|
|
|
|
BEAST_DEFINE_TESTSUITE(LedgerMaster, app, xrpl);
|
|
|
|
} // namespace xrpl::test
|