rippled
Loading...
Searching...
No Matches
LedgerHistory_test.cpp
1#include <test/jtx.h>
2#include <test/jtx/CheckMessageLogs.h>
3
4#include <xrpld/app/ledger/LedgerHistory.h>
5#include <xrpld/app/ledger/LedgerMaster.h>
6#include <xrpld/app/tx/apply.h>
7
8#include <xrpl/beast/insight/NullCollector.h>
9#include <xrpl/beast/unit_test.h>
10#include <xrpl/ledger/OpenView.h>
11
12#include <chrono>
13#include <sstream>
14
15namespace xrpl {
16namespace test {
17
19{
20public:
31 jtx::Env& env,
32 LedgerHistory& lh,
33 NetClock::duration closeOffset,
35 {
36 if (!prev)
37 {
38 assert(!stx);
41 }
42 auto res = std::make_shared<Ledger>(*prev, prev->header().closeTime + closeOffset);
43
44 if (stx)
45 {
46 OpenView accum(&*res);
47 applyTransaction(env.app(), accum, *stx, false, tapNONE, env.journal);
48 accum.apply(*res);
49 }
50 res->updateSkipList();
51
52 {
53 res->stateMap().flushDirty(hotACCOUNT_NODE);
54 res->txMap().flushDirty(hotTRANSACTION_NODE);
55 }
56 res->unshare();
57
58 // Accept ledger
59 res->setAccepted(res->header().closeTime, res->header().closeTimeResolution, true /* close time correct*/);
60 lh.insert(res, false);
61 return res;
62 }
63
64 void
66 {
67 testcase("LedgerHistory mismatch");
68 using namespace jtx;
69 using namespace std::chrono;
70
71 // No mismatch
72 {
73 bool found = false;
74 Env env{*this, envconfig(), std::make_unique<CheckMessageLogs>("MISMATCH ", &found)};
76 auto const genesis = makeLedger({}, env, lh, 0s);
77 uint256 const dummyTxHash{1};
78 lh.builtLedger(genesis, dummyTxHash, {});
79 lh.validatedLedger(genesis, dummyTxHash);
80
81 BEAST_EXPECT(!found);
82 }
83
84 // Close time mismatch
85 {
86 bool found = false;
87 Env env{*this, envconfig(), std::make_unique<CheckMessageLogs>("MISMATCH on close time", &found)};
89 auto const genesis = makeLedger({}, env, lh, 0s);
90 auto const ledgerA = makeLedger(genesis, env, lh, 4s);
91 auto const ledgerB = makeLedger(genesis, env, lh, 40s);
92
93 uint256 const dummyTxHash{1};
94 lh.builtLedger(ledgerA, dummyTxHash, {});
95 lh.validatedLedger(ledgerB, dummyTxHash);
96
97 BEAST_EXPECT(found);
98 }
99
100 // Prior ledger mismatch
101 {
102 bool found = false;
103 Env env{*this, envconfig(), std::make_unique<CheckMessageLogs>("MISMATCH on prior ledger", &found)};
105 auto const genesis = makeLedger({}, env, lh, 0s);
106 auto const ledgerA = makeLedger(genesis, env, lh, 4s);
107 auto const ledgerB = makeLedger(genesis, env, lh, 40s);
108 auto const ledgerAC = makeLedger(ledgerA, env, lh, 4s);
109 auto const ledgerBD = makeLedger(ledgerB, env, lh, 4s);
110
111 uint256 const dummyTxHash{1};
112 lh.builtLedger(ledgerAC, dummyTxHash, {});
113 lh.validatedLedger(ledgerBD, dummyTxHash);
114
115 BEAST_EXPECT(found);
116 }
117
118 // Simulate a bug in which consensus may agree on transactions, but
119 // somehow generate different ledgers
120 for (bool const txBug : {true, false})
121 {
122 std::string const msg =
123 txBug ? "MISMATCH with same consensus transaction set" : "MISMATCH on consensus transaction set";
124 bool found = false;
125 Env env{*this, envconfig(), std::make_unique<CheckMessageLogs>(msg, &found)};
127
128 Account alice{"A1"};
129 Account bob{"A2"};
130 env.fund(XRP(1000), alice, bob);
131 env.close();
132
133 auto const ledgerBase = env.app().getLedgerMaster().getClosedLedger();
134
135 JTx txAlice = env.jt(noop(alice));
136 auto const ledgerA = makeLedger(ledgerBase, env, lh, 4s, txAlice.stx);
137
138 JTx txBob = env.jt(noop(bob));
139 auto const ledgerB = makeLedger(ledgerBase, env, lh, 4s, txBob.stx);
140
141 lh.builtLedger(ledgerA, txAlice.stx->getTransactionID(), {});
142 // Simulate the bug by claiming ledgerB had the same consensus hash
143 // as ledgerA, but somehow generated different ledgers
144 lh.validatedLedger(ledgerB, txBug ? txAlice.stx->getTransactionID() : txBob.stx->getTransactionID());
145
146 BEAST_EXPECT(found);
147 }
148 }
149
150 void
151 run() override
152 {
154 }
155};
156
157BEAST_DEFINE_TESTSUITE(LedgerHistory, app, xrpl);
158
159} // namespace test
160} // namespace xrpl
static std::shared_ptr< Collector > New()
A testsuite class.
Definition suite.h:51
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:147
virtual Config & config()=0
Retains historical ledgers.
void validatedLedger(std::shared_ptr< Ledger const > const &, std::optional< uint256 > const &consensusHash)
Report that we have validated a particular ledger.
bool insert(std::shared_ptr< Ledger const > const &ledger, bool validated)
Track a ledger.
void builtLedger(std::shared_ptr< Ledger const > const &, uint256 const &consensusHash, Json::Value)
Report that we have locally built a particular ledger.
std::shared_ptr< Ledger const > getClosedLedger()
Writable ledger view that accumulates state and tx changes.
Definition OpenView.h:45
virtual LedgerMaster & getLedgerMaster()=0
virtual Family & getNodeFamily()=0
static std::shared_ptr< Ledger > makeLedger(std::shared_ptr< Ledger const > const &prev, jtx::Env &env, LedgerHistory &lh, NetClock::duration closeOffset, std::shared_ptr< STTx const > stx={})
Generate a new ledger by hand, applying a specific close time offset and optionally inserting a trans...
void run() override
Runs the suite.
Immutable cryptographic account descriptor.
Definition Account.h:19
A transaction testing environment.
Definition Env.h:119
Application & app()
Definition Env.h:251
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition Env.cpp:98
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition Env.cpp:261
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition Env.h:494
beast::Journal const journal
Definition Env.h:160
T is_same_v
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:90
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition envconfig.h:34
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
ApplyTransactionResult applyTransaction(Application &app, OpenView &view, STTx const &tx, bool retryAssured, ApplyFlags flags, beast::Journal journal)
Transaction application helper.
Definition apply.cpp:190
create_genesis_t const create_genesis
Definition Ledger.cpp:31
@ hotTRANSACTION_NODE
Definition NodeObject.h:16
@ hotACCOUNT_NODE
Definition NodeObject.h:15
@ tapNONE
Definition ApplyView.h:11
Execution context for applying a JSON transaction.
Definition JTx.h:25
std::shared_ptr< STTx const > stx
Definition JTx.h:35