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
7#include <xrpl/beast/insight/NullCollector.h>
8#include <xrpl/beast/unit_test.h>
9#include <xrpl/ledger/OpenView.h>
10#include <xrpl/tx/apply.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 Rules{env.app().config().features},
42 env.app().config().FEES.toFees(),
44 env.app().getNodeFamily());
45 }
46 auto res = std::make_shared<Ledger>(*prev, prev->header().closeTime + closeOffset);
47
48 if (stx)
49 {
50 OpenView accum(&*res);
51 applyTransaction(env.app(), accum, *stx, false, tapNONE, env.journal);
52 accum.apply(*res);
53 }
54 res->updateSkipList();
55
56 {
57 res->stateMap().flushDirty(hotACCOUNT_NODE);
58 res->txMap().flushDirty(hotTRANSACTION_NODE);
59 }
60 res->unshare();
61
62 // Accept ledger
63 res->setAccepted(
64 res->header().closeTime,
65 res->header().closeTimeResolution,
66 true /* close time correct*/);
67 lh.insert(res, false);
68 return res;
69 }
70
71 void
73 {
74 testcase("LedgerHistory mismatch");
75 using namespace jtx;
76 using namespace std::chrono;
77
78 // No mismatch
79 {
80 bool found = false;
81 Env env{*this, envconfig(), std::make_unique<CheckMessageLogs>("MISMATCH ", &found)};
83 auto const genesis = makeLedger({}, env, lh, 0s);
84 uint256 const dummyTxHash{1};
85 lh.builtLedger(genesis, dummyTxHash, {});
86 lh.validatedLedger(genesis, dummyTxHash);
87
88 BEAST_EXPECT(!found);
89 }
90
91 // Close time mismatch
92 {
93 bool found = false;
94 Env env{
95 *this,
96 envconfig(),
97 std::make_unique<CheckMessageLogs>("MISMATCH on close time", &found)};
99 auto const genesis = makeLedger({}, env, lh, 0s);
100 auto const ledgerA = makeLedger(genesis, env, lh, 4s);
101 auto const ledgerB = makeLedger(genesis, env, lh, 40s);
102
103 uint256 const dummyTxHash{1};
104 lh.builtLedger(ledgerA, dummyTxHash, {});
105 lh.validatedLedger(ledgerB, dummyTxHash);
106
107 BEAST_EXPECT(found);
108 }
109
110 // Prior ledger mismatch
111 {
112 bool found = false;
113 Env env{
114 *this,
115 envconfig(),
116 std::make_unique<CheckMessageLogs>("MISMATCH on prior ledger", &found)};
118 auto const genesis = makeLedger({}, env, lh, 0s);
119 auto const ledgerA = makeLedger(genesis, env, lh, 4s);
120 auto const ledgerB = makeLedger(genesis, env, lh, 40s);
121 auto const ledgerAC = makeLedger(ledgerA, env, lh, 4s);
122 auto const ledgerBD = makeLedger(ledgerB, env, lh, 4s);
123
124 uint256 const dummyTxHash{1};
125 lh.builtLedger(ledgerAC, dummyTxHash, {});
126 lh.validatedLedger(ledgerBD, dummyTxHash);
127
128 BEAST_EXPECT(found);
129 }
130
131 // Simulate a bug in which consensus may agree on transactions, but
132 // somehow generate different ledgers
133 for (bool const txBug : {true, false})
134 {
135 std::string const msg = txBug ? "MISMATCH with same consensus transaction set"
136 : "MISMATCH on consensus transaction set";
137 bool found = false;
138 Env env{*this, envconfig(), std::make_unique<CheckMessageLogs>(msg, &found)};
140
141 Account const alice{"A1"};
142 Account const bob{"A2"};
143 env.fund(XRP(1000), alice, bob);
144 env.close();
145
146 auto const ledgerBase = env.app().getLedgerMaster().getClosedLedger();
147
148 JTx const txAlice = env.jt(noop(alice));
149 auto const ledgerA = makeLedger(ledgerBase, env, lh, 4s, txAlice.stx);
150
151 JTx const txBob = env.jt(noop(bob));
152 auto const ledgerB = makeLedger(ledgerBase, env, lh, 4s, txBob.stx);
153
154 lh.builtLedger(ledgerA, txAlice.stx->getTransactionID(), {});
155 // Simulate the bug by claiming ledgerB had the same consensus hash
156 // as ledgerA, but somehow generated different ledgers
158 ledgerB, txBug ? txAlice.stx->getTransactionID() : txBob.stx->getTransactionID());
159
160 BEAST_EXPECT(found);
161 }
162 }
163
164 void
165 run() override
166 {
168 }
169};
170
171BEAST_DEFINE_TESTSUITE(LedgerHistory, app, xrpl);
172
173} // namespace test
174} // 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:150
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()
Rules controlling protocol behavior.
Definition Rules.h:18
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:122
Application & app()
Definition Env.h:259
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition Env.cpp:100
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition Env.cpp:270
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition Env.h:549
beast::Journal const journal
Definition Env.h:163
T is_same_v
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:95
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(ServiceRegistry &registry, OpenView &view, STTx const &tx, bool retryAssured, ApplyFlags flags, beast::Journal journal)
Transaction application helper.
Definition apply.cpp:207
create_genesis_t const create_genesis
@ 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