1#include <test/jtx/Account.h>
2#include <test/jtx/Env.h>
3#include <test/jtx/amount.h>
4#include <test/jtx/batch.h>
5#include <test/jtx/envconfig.h>
6#include <test/jtx/fee.h>
7#include <test/jtx/pay.h>
8#include <test/jtx/seq.h>
9#include <test/jtx/sig.h>
10#include <test/jtx/tags.h>
11#include <test/jtx/ter.h>
13#include <xrpld/app/ledger/BuildLedger.h>
14#include <xrpld/app/ledger/InboundLedger.h>
15#include <xrpld/app/ledger/InboundLedgers.h>
16#include <xrpld/app/ledger/LedgerMaster.h>
17#include <xrpld/app/ledger/LedgerReplay.h>
18#include <xrpld/app/ledger/LedgerReplayTask.h>
19#include <xrpld/app/ledger/LedgerReplayer.h>
20#include <xrpld/app/ledger/detail/LedgerDeltaAcquire.h>
21#include <xrpld/app/ledger/detail/LedgerReplayMsgHandler.h>
22#include <xrpld/app/ledger/detail/SkipListAcquire.h>
23#include <xrpld/core/Config.h>
24#include <xrpld/overlay/Message.h>
25#include <xrpld/overlay/Peer.h>
26#include <xrpld/overlay/PeerSet.h>
27#include <xrpld/overlay/detail/Handshake.h>
29#include <xrpl/basics/Slice.h>
30#include <xrpl/basics/base_uint.h>
31#include <xrpl/beast/net/IPAddress.h>
32#include <xrpl/beast/net/IPEndpoint.h>
33#include <xrpl/beast/unit_test/suite.h>
34#include <xrpl/beast/utility/Journal.h>
35#include <xrpl/json/json_value.h>
36#include <xrpl/ledger/ApplyView.h>
37#include <xrpl/protocol/Indexes.h>
38#include <xrpl/protocol/KeyType.h>
39#include <xrpl/protocol/PublicKey.h>
40#include <xrpl/protocol/RippleLedgerHash.h>
41#include <xrpl/protocol/SecretKey.h>
42#include <xrpl/protocol/TER.h>
43#include <xrpl/protocol/TxFlags.h>
44#include <xrpl/resource/Charge.h>
45#include <xrpl/server/Handoff.h>
46#include <xrpl/shamap/SHAMapItem.h>
48#include <boost/asio/ip/address.hpp>
50#include <google/protobuf/message.h>
86 auto const alice =
Account(
"alice");
87 auto const bob =
Account(
"bob");
90 env.
fund(
XRP(100000), alice, bob);
95 auto const lastClosedParent = ledgerMaster.
getLedgerByHash(lastClosed->header().parentHash);
100 BEAST_EXPECT(replayed->header().hash == lastClosed->header().hash);
106 testcase(
"Replay ledger with batch transactions");
112 auto const alice =
Account(
"alice");
113 auto const bob =
Account(
"bob");
114 env.
fund(
XRP(100000), alice, bob);
117 auto const seq = env.
seq(alice);
127 auto const lastClosedParent = ledgerMaster.
getLedgerByHash(lastClosed->header().parentHash);
132 BEAST_EXPECT(replayed->header().hash == lastClosed->header().hash);
424 bool enableLedgerReplay)
444 ::google::protobuf::Message
const& msg,
445 protocol::MessageType type,
459 case protocol::mtPROOF_PATH_REQ: {
463 dynamic_cast<protocol::TMProofPathRequest const&
>(msg));
465 remote.processProofPathRequest(request));
466 local.processProofPathResponse(reply);
468 local.processProofPathResponse(reply);
471 case protocol::mtREPLAY_DELTA_REQ: {
475 dynamic_cast<protocol::TMReplayDeltaRequest const&
>(msg));
477 remote.processReplayDeltaRequest(request));
478 local.processReplayDeltaResponse(reply);
480 local.processReplayDeltaResponse(reply);
555 assert(
param.initLedgers > 0);
567 auto fundedAccounts =
accounts.size();
568 for (
int i = 0; i < newAccounts; ++i)
582 int fundedAccounts =
accounts.size();
583 assert(fundedAccounts >= newTxes);
590 auto updateIdx = [&]() {
591 assert(fundedAccounts > senders.
size());
592 fromIdx = (fromIdx + r) % fundedAccounts;
594 fromIdx = (fromIdx + 1) % fundedAccounts;
596 toIdx = (toIdx + (r * 2)) % fundedAccounts;
597 if (toIdx == fromIdx)
598 toIdx = (toIdx + 1) % fundedAccounts;
601 for (
int i = 0; i < newTxes; ++i)
621 for (
int i = 0; i <
param.initLedgers - 1; ++i)
684 uint256 hash = finishLedgerHash;
686 for (; i < totalReplay; ++i)
691 hash = l->header().parentHash;
699 int const totalRound = 100;
700 for (
int i = 0; i < totalRound; ++i)
704 if (i < totalRound - 1)
713 int const totalRound = 100;
714 for (
int i = 0; i < totalRound; ++i)
719 for (
auto const& t :
replayer.tasks_)
730 if (i < totalRound - 1)
748 return t->parameter_.finishHash == hash && t->parameter_.totalLedgers == totalReplay;
773 return replayer.tasks_.size() == tasks &&
replayer.skipLists_.size() == skipLists &&
781 auto i =
replayer.skipLists_.find(hash);
784 return i->second.lock();
791 auto i =
replayer.deltas_.find(hash);
794 return i->second.lock();
797 template <
typename T>
817 if (
taskStatus(task->skipListAcquirer_) == skiplistExpect)
819 if (task->deltas_.size() == deltaExpects.
size())
821 for (
int i = 0; i < deltaExpects.
size(); ++i)
823 if (
taskStatus(task->deltas_[i]) != deltaExpects[i])
841 auto t =
findTask(hash, totalReplay);
847 return asExpected(t, taskExpect, skiplistExpect, deltaExpects);
858 auto t =
findTask(hash, totalReplay);
864 return asExpected(t, taskExpect, skiplistExpect, deltaExpects);
878 return checkStatus(hash, totalReplay, taskExpect, skiplistExpect, deltaExpects);
955 request->set_ledgerhash(l->header().hash.data(), l->header().hash.size());
956 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
958 server.msgHandler.processProofPathRequest(request));
959 BEAST_EXPECT(reply->has_error());
966 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
969 request->set_ledgerhash(hash.
data(), hash.
size());
971 server.msgHandler.processProofPathRequest(request));
972 BEAST_EXPECT(reply->has_error());
978 request->set_ledgerhash(l->header().hash.data(), l->header().hash.size());
979 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
983 server.msgHandler.processProofPathRequest(request));
984 BEAST_EXPECT(!reply->has_error());
994 server.msgHandler.processProofPathResponse(bad) ==
1002 server.msgHandler.processProofPathResponse(bad) ==
1010 server.msgHandler.processProofPathResponse(bad) ==
1018 server.msgHandler.processProofPathResponse(bad) ==
1026 server.msgHandler.processProofPathResponse(bad) ==
1034 server.msgHandler.processProofPathResponse(bad) ==
1044 reply->set_ledgerheader(r);
1046 server.msgHandler.processProofPathResponse(reply) ==
1049 reply->set_ledgerheader(r);
1053 reply->mutable_path()->RemoveLast();
1055 server.msgHandler.processProofPathResponse(reply) ==
1072 server.msgHandler.processReplayDeltaRequest(request));
1073 BEAST_EXPECT(reply->has_error());
1078 request->set_ledgerhash(hash.
data(), hash.
size());
1080 server.msgHandler.processReplayDeltaRequest(request));
1081 BEAST_EXPECT(reply->has_error());
1089 request->set_ledgerhash(l->header().hash.data(), l->header().hash.size());
1091 server.msgHandler.processReplayDeltaRequest(request));
1092 BEAST_EXPECT(!reply->has_error());
1103 server.msgHandler.processReplayDeltaResponse(bad) ==
1111 server.msgHandler.processReplayDeltaResponse(bad) ==
1119 server.msgHandler.processReplayDeltaResponse(bad) ==
1129 reply->set_ledgerheader(r);
1131 server.msgHandler.processReplayDeltaResponse(reply) ==
1134 reply->set_ledgerheader(r);
1138 reply->mutable_transaction()->RemoveLast();
1140 server.msgHandler.processReplayDeltaResponse(reply) ==
1153 auto runNoThrow = [
this](
auto fn,
char const* what) {
1161 std::format(
"processor threw on truncated header ({}): {}", what, e.
what()),
1168 std::format(
"processor threw unknown exception ({}) on truncated header", what),
1176 request->set_ledgerhash(l->header().hash.data(), l->header().hash.size());
1178 server.msgHandler.processReplayDeltaRequest(request));
1179 BEAST_EXPECT(!reply->has_error());
1183 [&] {
return server.msgHandler.processReplayDeltaResponse(reply); },
"ReplayDelta");
1188 request->set_ledgerhash(l->header().hash.data(), l->header().hash.size());
1189 request->set_type(protocol::TMLedgerMapType::lmACCOUNT_STATE);
1192 server.msgHandler.processProofPathRequest(request));
1193 BEAST_EXPECT(!reply->has_error());
1197 [&] {
return server.msgHandler.processProofPathResponse(reply); },
"ProofPath");
1209 for (
int i = 0; i < count; ++i)
1215 BEAST_EXPECT(!tp10.
update(
uint256(777), 5, makeSkipList(10)));
1216 BEAST_EXPECT(!tp10.
update(
uint256(10), 5, makeSkipList(8)));
1217 BEAST_EXPECT(tp10.
update(
uint256(10), 10, makeSkipList(10)));
1245 BEAST_EXPECT(tp20.
update(
uint256(20), 20, makeSkipList(20)));
1286 auto handshake = [&](
bool client,
bool server,
bool expecting) ->
bool {
1289 httpRequest.version(request.version());
1290 httpRequest.base() = request.base();
1292 if (serverResult != expecting)
1296 jtx::Env serverEnv(*
this);
1297 serverEnv.app().config().ledgerReplay = server;
1299 true, httpRequest, addr, addr,
uint256{1}, 1, {1, 0}, serverEnv.app());
1301 return clientResult == expecting;
1304 BEAST_EXPECT(handshake(
false,
false,
false));
1305 BEAST_EXPECT(handshake(
false,
true,
false));
1306 BEAST_EXPECT(handshake(
true,
false,
false));
1307 BEAST_EXPECT(handshake(
true,
true,
true));
1313 testcase(
"local node has all the ledgers");
1318 NetworkOfTwo net(*
this, {.initLedgers = totalReplay + 1}, psBhvr, ilBhvr, peerFeature);
1321 uint256 const finalHash = l->header().hash;
1322 for (
int i = 0; i < totalReplay; ++i)
1327 net.client.ledgerMaster.storeLedger(l);
1328 l = net.server.ledgerMaster.getLedgerByHash(l->header().parentHash);
1339 BEAST_EXPECT(net.client.waitAndCheckStatus(
1343 net.client.replayer.sweep();
1344 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1350 testcase(
"all the ledgers from InboundLedgers");
1353 {.initLedgers = totalReplay + 1},
1359 uint256 const finalHash = l->header().hash;
1363 BEAST_EXPECT(net.client.waitAndCheckStatus(
1374 auto waitForSweep = [&net]() {
1375 for (
auto numAttempts = 0; numAttempts < 20; ++numAttempts)
1377 net.client.replayer.sweep();
1378 if (net.client.countsAsExpected(0, 0, 0))
1386 BEAST_EXPECT(waitForSweep());
1392 switch (peerSetBehavior)
1398 testcase(
"network drops 50% messages");
1401 testcase(
"network repeats all messages");
1409 {.initLedgers = totalReplay + 1},
1415 auto l = net.server.ledgerMaster.getClosedLedger();
1416 uint256 const finalHash = l->header().hash;
1417 for (
int i = 0; i < totalReplay - 1; ++i)
1419 l = net.server.ledgerMaster.getLedgerByHash(l->header().parentHash);
1421 net.client.ledgerMaster.storeLedger(l);
1426 BEAST_EXPECT(net.client.waitAndCheckStatus(
1428 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay));
1431 net.client.replayer.sweep();
1432 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1439 int const totalReplay = 3;
1442 {.initLedgers = totalReplay + 1},
1448 uint256 const finalHash = l->header().hash;
1452 BEAST_EXPECT(net.client.checkStatus(
1455 BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0));
1456 net.client.replayer.stop();
1457 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1463 testcase(
"SkipListAcquire bad reply");
1464 int const totalReplay = 3;
1467 {.initLedgers = totalReplay + 1 + 1},
1473 uint256 const finalHash = l->header().hash;
1476 auto skipList = net.client.findSkipListAcquire(finalHash);
1478 std::uint8_t payload[55] = {0x6A, 0x09, 0xE6, 0x67, 0xF3, 0xBC, 0xC9, 0x08, 0xB2};
1480 skipList->processData(l->seq(), item);
1483 BEAST_EXPECT(net.client.waitAndCheckStatus(
1488 BEAST_EXPECT(net.client.waitAndCheckStatus(
1490 BEAST_EXPECT(net.client.countsAsExpected(2, 1, 0));
1496 testcase(
"LedgerDeltaAcquire bad reply");
1497 int const totalReplay = 3;
1500 {.initLedgers = totalReplay + 1},
1506 uint256 const finalHash = l->header().hash;
1507 net.client.ledgerMaster.storeLedger(l);
1510 auto delta = net.client.findLedgerDeltaAcquire(l->header().parentHash);
1516 net.client.taskStatus(net.client.findTask(finalHash, totalReplay)) ==
1522 net.client.taskStatus(net.client.findTask(finalHash, totalReplay + 1)) ==
1530 int const totalReplay = 5;
1533 {.initLedgers = (totalReplay * 3) + 1},
1538 uint256 const finalHash = l->header().hash;
1541 BEAST_EXPECT(net.client.waitAndCheckStatus(
1543 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay));
1547 BEAST_EXPECT(net.client.countsAsExpected(1, 1, totalReplay - 1));
1550 BEAST_EXPECT(net.client.countsAsExpected(2, 1, totalReplay - 1));
1553 for (
int i = 0; i < totalReplay + 2; ++i)
1555 l = net.server.ledgerMaster.getLedgerByHash(l->header().parentHash);
1557 auto finalHashEarly = l->header().hash;
1559 BEAST_EXPECT(net.client.waitAndCheckStatus(
1565 BEAST_EXPECT(net.client.waitForLedgers(finalHashEarly, totalReplay));
1566 BEAST_EXPECT(net.client.countsAsExpected(3, 2, 2 * (totalReplay - 1)));
1569 l = net.server.ledgerMaster.getLedgerByHash(l->header().parentHash);
1570 auto finalHashMoreEarly = l->header().parentHash;
1572 BEAST_EXPECT(net.client.waitAndCheckStatus(
1578 BEAST_EXPECT(net.client.waitForLedgers(finalHashMoreEarly, totalReplay));
1579 BEAST_EXPECT(net.client.countsAsExpected(4, 3, (2 * (totalReplay - 1)) + 2));
1584 BEAST_EXPECT(net.client.waitAndCheckStatus(
1590 BEAST_EXPECT(net.client.waitForLedgers(finalHash, totalReplay * 3));
1591 BEAST_EXPECT(net.client.countsAsExpected(5, 3, (totalReplay * 3) - 1));
1594 net.client.replayer.sweep();
1595 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1627 testcase(
"SkipListAcquire timeout");
1628 int const totalReplay = 3;
1631 {.initLedgers = totalReplay + 1},
1637 uint256 const finalHash = l->header().hash;
1641 BEAST_EXPECT(net.client.waitAndCheckStatus(
1645 BEAST_EXPECT(net.client.countsAsExpected(1, 1, 0));
1646 net.client.replayer.sweep();
1647 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1653 testcase(
"LedgerDeltaAcquire timeout");
1654 int const totalReplay = 3;
1657 {.initLedgers = totalReplay + 1},
1663 uint256 const finalHash = l->header().hash;
1664 net.client.ledgerMaster.storeLedger(l);
1669 BEAST_EXPECT(net.client.waitAndCheckStatus(
1673 BEAST_EXPECT(net.client.countsAsExpected(1, 1, totalReplay - 1));
1674 net.client.replayer.sweep();
1675 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
1692 int const totalReplay = 250;
1693 int const rounds = 4;
1696 {.initLedgers = (totalReplay * rounds) + 1},
1702 auto l = net.server.ledgerMaster.getClosedLedger();
1703 for (
int i = 0; i < rounds; ++i)
1705 finishHashes.push_back(l->header().hash);
1706 for (
int j = 0; j < totalReplay; ++j)
1708 l = net.server.ledgerMaster.getLedgerByHash(l->header().parentHash);
1711 BEAST_EXPECT(finishHashes.size() == rounds);
1713 for (
int i = 0; i < rounds; ++i)
1715 net.client.replayer.replay(
1720 for (
int i = 0; i < rounds; ++i)
1722 BEAST_EXPECT(net.client.waitAndCheckStatus(
1730 BEAST_EXPECT(net.client.waitForLedgers(finishHashes[0], totalReplay * rounds));
1731 BEAST_EXPECT(net.client.countsAsExpected(rounds, rounds, rounds * (totalReplay - 1)));
1734 net.client.replayer.sweep();
1735 BEAST_EXPECT(net.client.countsAsExpected(0, 0, 0));
A version-independent IP address and port combination.
void fail(String const &reason, char const *file, int line)
Record a failure.
TestcaseT testcase
Memberspace for declaring test cases.
static constexpr std::size_t size()
void loadFromString(std::string const &fileContents)
Load the config from the contents of the string.
Manages the lifetime of inbound ledgers.
std::shared_ptr< Ledger const > getClosedLedger()
std::shared_ptr< Ledger const > getLedgerByHash(uint256 const &hash)
InboundLedger::Reason reason
std::uint32_t totalLedgers
bool update(uint256 const &hash, std::uint32_t seq, std::vector< uint256 > const &sList)
fill all the fields that was not filled during construction
bool canMergeInto(TaskParameter const &existingTask) const
check if this task can be merged into an existing task
Manages the lifetime of ledger replay tasks.
beast::Severity threshold() const
Supports data retrieval by managing a set of peers.
virtual LedgerMaster & getLedgerMaster()=0
virtual Logs & getLogs()=0
Ledger replay client side.
LedgerReplayClient(beast::unit_test::Suite &suite, LedgerServer &server, PeerSetBehavior behavior=PeerSetBehavior::Good, InboundLedgersBehavior inboundBhvr=InboundLedgersBehavior::Good, PeerFeature peerFeature=PeerFeature::LedgerReplayEnabled)
TaskStatus taskStatus(std::shared_ptr< T > const &t)
std::size_t countDeltas()
std::vector< std::shared_ptr< LedgerReplayTask > > getTasks()
bool asExpected(uint256 const &hash, int totalReplay, TaskStatus taskExpect, TaskStatus skiplistExpect, std::vector< TaskStatus > const &deltaExpects)
LedgerMaster & ledgerMaster
MagicInboundLedgers inboundLedgers
std::size_t countSkipLists()
LedgerReplayMsgHandler clientMsgHandler
bool haveLedgers(uint256 const &finishLedgerHash, int totalReplay)
void addLedger(std::shared_ptr< Ledger const > const &l)
std::shared_ptr< SkipListAcquire > findSkipListAcquire(uint256 const &hash)
bool countsAsExpected(std::size_t tasks, std::size_t skipLists, std::size_t deltas)
bool waitForLedgers(uint256 const &finishLedgerHash, int totalReplay)
LedgerReplayMsgHandler serverMsgHandler
bool waitAndCheckStatus(uint256 const &hash, int totalReplay, TaskStatus taskExpect, TaskStatus skiplistExpect, std::vector< TaskStatus > const &deltaExpects)
bool asExpected(std::shared_ptr< LedgerReplayTask > const &task, TaskStatus taskExpect, TaskStatus skiplistExpect, std::vector< TaskStatus > const &deltaExpects)
std::shared_ptr< LedgerReplayTask > findTask(uint256 const &hash, int totalReplay)
bool checkStatus(uint256 const &hash, int totalReplay, TaskStatus taskExpect, TaskStatus skiplistExpect, std::vector< TaskStatus > const &deltaExpects)
std::shared_ptr< LedgerDeltaAcquire > findLedgerDeltaAcquire(uint256 const &hash)
Simulate a network InboundLedgers.
std::shared_ptr< Ledger const > acquire(uint256 const &hash, std::uint32_t seq, InboundLedger::Reason) override
void clearFailures() override
void acquireAsync(uint256 const &hash, std::uint32_t seq, InboundLedger::Reason reason) override
bool gotLedgerData(LedgerHash const &ledgerHash, std::shared_ptr< Peer >, std::shared_ptr< protocol::TMLedgerData >) override
MagicInboundLedgers(LedgerMaster &ledgerSource, LedgerMaster &ledgerSink, InboundLedgersBehavior bhvr)
InboundLedgersBehavior bhvr
LedgerMaster & ledgerSink
void onLedgerFetched() override
Called when a complete ledger is obtained.
void gotFetchPack() override
std::shared_ptr< InboundLedger > find(LedgerHash const &hash) override
~MagicInboundLedgers() override=default
size_t cacheSize() override
LedgerMaster & ledgerSource
std::size_t fetchRate() override
Returns the rate of historical ledger fetches per minute.
void logFailure(uint256 const &h, std::uint32_t seq) override
json::Value getInfo() override
bool isFailure(uint256 const &h) override
void gotStaleData(std::shared_ptr< protocol::TMLedgerData > packet) override
LedgerReplayMsgHandler & local_
LedgerReplayMsgHandler & remote_
TestPeerSetBuilder(LedgerReplayMsgHandler &me, LedgerReplayMsgHandler &other, PeerSetBehavior bhvr, PeerFeature peerFeature)
std::unique_ptr< PeerSet > build() override
PeerSetBehavior behavior_
void cycleStatus() override
std::optional< std::size_t > publisherListSequence(PublicKey const &) const override
bool supportsFeature(ProtocolFeature f) const override
PublicKey const & getNodePublic() const override
std::string const & fingerprint() const override
void ledgerRange(std::uint32_t &minSeq, std::uint32_t &maxSeq) const override
bool compressionEnabled() const override
beast::ip::Endpoint getRemoteAddress() const override
json::Value json() override
bool ledgerReplayEnabled_
bool hasLedger(uint256 const &hash, std::uint32_t seq) const override
bool txReduceRelayEnabled() const override
TestPeer(bool enableLedgerReplay)
bool hasTxSet(uint256 const &hash) const override
uint256 getClosedLedgerHash() const override
int getScore(bool) const override
bool isHighLatency() const override
bool cluster() const override
void addTxQueue(uint256 const &) override
void removeTxQueue(uint256 const &) override
void send(std::shared_ptr< Message > const &m) override
void sendTxQueue() override
bool hasRange(std::uint32_t uMin, std::uint32_t uMax) override
void setPublisherListSequence(PublicKey const &, std::size_t const) override
void charge(resource::Charge const &fee, std::string const &context={}) override
A transaction testing environment.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
beast::Journal const journal
Set the regular signature on a JTx.
Set the expected result code for a JTx The test will fail if the code doesn't match.
Adds an inner Batch transaction to a JTx and autofills it.
T emplace_back(T... args)
boost::asio::ip::address Address
Severity
Severity level / threshold of a Journal message.
Keylet const & skip() noexcept
The index of the "short" skip list.
json::Value outer(jtx::Account const &account, uint32_t seq, STAmount const &fee, std::uint32_t flags)
Build an outer Batch transaction JSON object.
XRPAmount calcBatchFee(jtx::Env const &env, uint32_t const &numSigners, uint32_t const &txns=0)
Calculate the expected outer Batch transaction fee.
json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
XrpT const XRP
Converts to XRP Issue or STAmount.
FeatureBitset testableAmendments()
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
static AutofillT const kAutofill
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
void logAll(LedgerServer &server, LedgerReplayClient &client, beast::Severity level=Severity::Trace)
static uint256 ledgerHash(LedgerHeader const &info)
BEAST_DEFINE_TESTSUITE_MANUAL(AMMCalc, app, xrpl)
BEAST_DEFINE_TESTSUITE_PRIO(AccountDelete, app, xrpl, 2)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
PublicKey derivePublicKey(KeyType type, SecretKey const &sk)
Derive the public key from a secret key.
static constexpr char kFeatureLedgerReplay[]
auto makeRequest(bool crawlPublic, bool comprEnabled, bool ledgerReplayEnabled, bool txReduceRelayEnabled, bool vpReduceRelayEnabled) -> request_type
Make outbound http request.
boost::intrusive_ptr< SHAMapItem > makeShamapitem(uint256 const &tag, Slice data)
SecretKey randomSecretKey()
Create a secret key using secure random numbers.
std::shared_ptr< Ledger > buildLedger(std::shared_ptr< Ledger const > const &parent, NetClock::time_point closeTime, bool const closeTimeCorrect, NetClock::duration closeResolution, Application &app, CanonicalTXSet &txns, std::set< TxID > &failedTxs, beast::Journal j)
Build a new ledger by applying consensus transactions.
http_response_type makeResponse(bool crawlPublic, http_request_type const &req, beast::ip::Address publicIp, beast::ip::Address remoteIp, uint256 const &sharedValue, std::optional< std::uint32_t > networkID, ProtocolVersion protocol, Application &app)
Make http response.
bool peerFeatureEnabled(Headers const &request, std::string const &feature, std::string value, bool config)
Check if a feature should be enabled for a peer.
@ Malformed
Protocol-level violation; no honest peer would produce this.
@ BadData
Peer reported has_error() (legitimate "cannot fulfill" signal).
boost::beast::http::request< boost::beast::http::dynamic_body > http_request_type
void run() override
Runs the suite.
void testReplayBatchLedger()
void run() override
Runs the suite.
void testSkipListTimeout()
void testLedgerDeltaTimeout()
void run() override
Runs the suite.
Test cases: LedgerReplayer_test: – process TMProofPathRequest and TMProofPathResponse – process TMRep...
void run() override
Runs the suite.
void testAllLocal(int totalReplay)
void testSkipListBadReply()
void testPeerSetBehavior(PeerSetBehavior peerSetBehavior, int totalReplay=4)
void testAllInboundLedgers(int totalReplay)
void testTruncatedHeader()
void testLedgerReplayOverlap()
void testLedgerDeltaBadReply()
Utility class for (1) creating ledgers with txns and (2) providing the ledgers via the ledgerMaster.
LedgerMaster & ledgerMaster
std::vector< jtx::Account > accounts
LedgerServer(beast::unit_test::Suite &suite, Parameter const &p)
void createLedgerHistory()
create ledger history
void sendPayments(int newTxes)
LedgerReplayMsgHandler msgHandler
void createAccounts(int newAccounts)
NetworkOfTwo(beast::unit_test::Suite &suite, LedgerServer::Parameter const ¶m, PeerSetBehavior behavior=PeerSetBehavior::Good, InboundLedgersBehavior inboundBhvr=InboundLedgersBehavior::Good, PeerFeature peerFeature=PeerFeature::LedgerReplayEnabled)
LedgerReplayClient client
std::set< Peer::id_t > const & getPeerIds() const override
get the set of ids of previously added peers
LedgerReplayMsgHandler & local
std::shared_ptr< TestPeer > dummyPeer
TestPeerSet(LedgerReplayMsgHandler &me, LedgerReplayMsgHandler &other, PeerSetBehavior bhvr, bool enableLedgerReplay)
void sendRequest(::google::protobuf::Message const &msg, protocol::MessageType type, std::shared_ptr< Peer > const &peer) override
LedgerReplayMsgHandler & remote
std::atomic< int > sendCount
void addPeers(std::size_t limit, std::function< bool(std::shared_ptr< Peer > const &)> hasItem, std::function< void(std::shared_ptr< Peer > const &)> onPeerAdded) override
Set the sequence number on a JTx.