xrpld
Loading...
Searching...
No Matches
LedgerHistory_test.cpp
1#include <test/jtx/Account.h>
2#include <test/jtx/CheckMessageLogs.h>
3#include <test/jtx/Env.h>
4#include <test/jtx/JTx.h>
5#include <test/jtx/amount.h>
6#include <test/jtx/envconfig.h>
7#include <test/jtx/noop.h>
8
9#include <xrpld/app/ledger/LedgerHistory.h>
10#include <xrpld/app/ledger/LedgerMaster.h>
11
12#include <xrpl/basics/base_uint.h>
13#include <xrpl/basics/chrono.h>
14#include <xrpl/beast/insight/NullCollector.h>
15#include <xrpl/beast/unit_test/suite.h>
16#include <xrpl/ledger/ApplyView.h>
17#include <xrpl/ledger/Ledger.h>
18#include <xrpl/ledger/OpenView.h>
19#include <xrpl/nodestore/NodeObject.h>
20#include <xrpl/protocol/STTx.h>
21#include <xrpl/tx/apply.h>
22
23#include <cassert>
24#include <memory>
25#include <vector>
26
27namespace xrpl::test {
28
30{
31public:
42 jtx::Env& env,
43 LedgerHistory& lh,
44 NetClock::duration closeOffset,
46 {
47 if (!prev)
48 {
49 assert(!stx);
52 Rules{env.app().config().features},
53 env.app().config().fees.toFees(),
55 env.app().getNodeFamily());
56 }
57 auto res = std::make_shared<Ledger>(*prev, prev->header().closeTime + closeOffset);
58
59 if (stx)
60 {
61 OpenView accum(&*res);
62 applyTransaction(env.app(), accum, *stx, false, TapNone, env.journal);
63 accum.apply(*res);
64 }
65 res->updateSkipList();
66
67 {
68 res->stateMap().flushDirty(NodeObjectType::AccountNode);
69 res->txMap().flushDirty(NodeObjectType::TransactionNode);
70 }
71 res->unshare();
72
73 // Accept ledger
74 res->setAccepted(
75 res->header().closeTime,
76 res->header().closeTimeResolution,
77 true /* close time correct*/);
78 lh.insert(res, false);
79 return res;
80 }
81
82 void
84 {
85 testcase("LedgerHistory mismatch");
86 using namespace jtx;
87 using namespace std::chrono;
88
89 // No mismatch
90 {
91 bool found = false;
92 Env env{*this, envconfig(), std::make_unique<CheckMessageLogs>("MISMATCH ", &found)};
94 auto const genesis = makeLedger({}, env, lh, 0s);
95 uint256 const dummyTxHash{1};
96 lh.builtLedger(genesis, dummyTxHash, {});
97 lh.validatedLedger(genesis, dummyTxHash);
98
99 BEAST_EXPECT(!found);
100 }
101
102 // Close time mismatch
103 {
104 bool found = false;
105 Env env{
106 *this,
107 envconfig(),
108 std::make_unique<CheckMessageLogs>("MISMATCH on close time", &found)};
110 auto const genesis = makeLedger({}, env, lh, 0s);
111 auto const ledgerA = makeLedger(genesis, env, lh, 4s);
112 auto const ledgerB = makeLedger(genesis, env, lh, 40s);
113
114 uint256 const dummyTxHash{1};
115 lh.builtLedger(ledgerA, dummyTxHash, {});
116 lh.validatedLedger(ledgerB, dummyTxHash);
117
118 BEAST_EXPECT(found);
119 }
120
121 // Prior ledger mismatch
122 {
123 bool found = false;
124 Env env{
125 *this,
126 envconfig(),
127 std::make_unique<CheckMessageLogs>("MISMATCH on prior ledger", &found)};
129 auto const genesis = makeLedger({}, env, lh, 0s);
130 auto const ledgerA = makeLedger(genesis, env, lh, 4s);
131 auto const ledgerB = makeLedger(genesis, env, lh, 40s);
132 auto const ledgerAC = makeLedger(ledgerA, env, lh, 4s);
133 auto const ledgerBD = makeLedger(ledgerB, env, lh, 4s);
134
135 uint256 const dummyTxHash{1};
136 lh.builtLedger(ledgerAC, dummyTxHash, {});
137 lh.validatedLedger(ledgerBD, dummyTxHash);
138
139 BEAST_EXPECT(found);
140 }
141
142 // Simulate a bug in which consensus may agree on transactions, but
143 // somehow generate different ledgers
144 for (bool const txBug : {true, false})
145 {
146 std::string const msg = txBug ? "MISMATCH with same consensus transaction set"
147 : "MISMATCH on consensus transaction set";
148 bool found = false;
149 Env env{*this, envconfig(), std::make_unique<CheckMessageLogs>(msg, &found)};
151
152 Account const alice{"A1"};
153 Account const bob{"A2"};
154 env.fund(XRP(1000), alice, bob);
155 env.close();
156
157 auto const ledgerBase = env.app().getLedgerMaster().getClosedLedger();
158
159 JTx const txAlice = env.jt(noop(alice));
160 auto const ledgerA = makeLedger(ledgerBase, env, lh, 4s, txAlice.stx);
161
162 JTx const txBob = env.jt(noop(bob));
163 auto const ledgerB = makeLedger(ledgerBase, env, lh, 4s, txBob.stx);
164
165 lh.builtLedger(ledgerA, txAlice.stx->getTransactionID(), {});
166 // Simulate the bug by claiming ledgerB had the same consensus hash
167 // as ledgerA, but somehow generated different ledgers
169 ledgerB, txBug ? txAlice.stx->getTransactionID() : txBob.stx->getTransactionID());
170
171 BEAST_EXPECT(found);
172 }
173 }
174
175 void
176 run() override
177 {
179 }
180};
181
183
184} // namespace xrpl::test
static std::shared_ptr< Collector > make()
A testsuite class.
Definition suite.h:50
TestcaseT testcase
Memberspace for declaring test cases.
Definition suite.h:149
virtual Config & config()=0
std::unordered_set< uint256, beast::Uhash<> > features
Definition Config.h:261
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()
std::chrono::duration< rep, period > duration
Definition chrono.h:45
Rules controlling protocol behavior.
Definition Rules.h:33
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 jtx/Account.h:17
A transaction testing environment.
Definition Env.h:143
Application & app()
Definition Env.h:280
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition Env.cpp:133
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition Env.cpp:296
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
Definition Env.h:566
beast::Journal const journal
Definition Env.h:184
T make_shared(T... args)
T make_unique(T... args)
XrpT const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:92
json::Value noop(Account const &account)
The null transaction.
Definition noop.h:9
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition envconfig.h:28
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
CreateGenesisT const kCreateGenesis
ApplyTransactionResult applyTransaction(ServiceRegistry &registry, OpenView &view, STTx const &tx, bool retryAssured, ApplyFlags flags, beast::Journal journal)
Transaction application helper.
Definition apply.cpp:222
@ TapNone
Definition ApplyView.h:13
BaseUInt< 256 > uint256
Definition base_uint.h:562
Execution context for applying a JSON transaction.
Definition JTx.h:23
std::shared_ptr< STTx const > stx
Definition JTx.h:33