xrpld
Loading...
Searching...
No Matches
TxTest.cpp
1#include <helpers/TxTest.h>
2
3#include <xrpl/basics/base_uint.h>
4#include <xrpl/basics/chrono.h>
5#include <xrpl/basics/contract.h>
6#include <xrpl/ledger/ApplyView.h>
7#include <xrpl/ledger/CanonicalTXSet.h>
8#include <xrpl/ledger/Ledger.h>
9#include <xrpl/ledger/OpenView.h>
10#include <xrpl/ledger/ReadView.h>
11#include <xrpl/protocol/AccountID.h>
12#include <xrpl/protocol/Feature.h>
13#include <xrpl/protocol/Fees.h>
14#include <xrpl/protocol/Indexes.h>
15#include <xrpl/protocol/SField.h>
16#include <xrpl/protocol/STLedgerEntry.h>
17#include <xrpl/protocol/STTx.h>
18#include <xrpl/protocol/TER.h>
19#include <xrpl/protocol_autogen/ledger_entries/AccountRoot.h>
20#include <xrpl/protocol_autogen/ledger_entries/RippleState.h>
21#include <xrpl/protocol_autogen/transactions/AccountSet.h>
22#include <xrpl/protocol_autogen/transactions/Payment.h>
23#include <xrpl/tx/apply.h>
24
25#include <helpers/Account.h>
26#include <helpers/IOU.h>
27
28#include <cstdint>
29#include <memory>
30#include <optional>
31#include <stdexcept>
32#include <utility>
33#include <vector>
34
35namespace xrpl::test {
36
37//------------------------------------------------------------------------------
38// Feature helpers
39//------------------------------------------------------------------------------
40
41FeatureBitset
43{
44 static FeatureBitset const kFeatures = [] {
45 auto const& sa = allAmendments();
47 feats.reserve(sa.size());
48 for ([[maybe_unused]] auto const& [name, _] : sa)
49 {
50 if (auto const f = getRegisteredFeature(name); f.has_value())
51 feats.push_back(*f);
52 }
53 return FeatureBitset(feats);
54 }();
55 return kFeatures;
56}
57
58//------------------------------------------------------------------------------
59// TxTest
60//------------------------------------------------------------------------------
61
63{
64 // Convert FeatureBitset to unordered_set for Rules constructor
65 auto const featureBits = features.value_or(allFeatures());
66 foreachFeature(featureBits, [&](uint256 const& f) { featureSet_.insert(f); });
67
68 // Create rules with the specified features
69 rules_.emplace(featureSet_);
70
71 // Default fees for testing
72 Fees const fees{XRPAmount{10}, XRPAmount{10000000}, XRPAmount{2000000}};
73
74 // Create a genesis ledger as the base
77 // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
78 *rules_,
79 fees,
81 registry_.getNodeFamily());
82
83 // Initialize time from the genesis ledger. closedLedger_ is created above
84 // in the body, so this cannot be a member initializer.
85 // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)
86 now_ = closedLedger_->header().closeTime;
87
88 // Create an open view on top of the genesis ledger
91}
92
93bool
94TxTest::isEnabled(uint256 const& feature) const
95{
96 // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
97 return rules_->enabled(feature);
98}
99
100Rules const&
102{
103 // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
104 return *rules_;
105}
106
107[[nodiscard]] TxResult
109{
110 auto result = apply(registry_, *openLedger_, *stx, TapNone, registry_.getJournal("apply"));
111
112 // Track successfully applied transactions for canonical reordering on close
113 // We make a copy since the TransactionBase doesn't own the STTx
114 if (result.applied)
115 pendingTxs_.push_back(stx);
116
117 return TxResult{
118 .ter = result.ter,
119 .applied = result.applied,
120 .metadata = std::move(result).metadata,
121 .tx = std::move(stx)};
122}
123
124void
125TxTest::createAccount(Account const& account, XRPAmount xrp, uint32_t accountFlags)
126{
127 auto const paymentTer =
129
130 if (paymentTer != tesSUCCESS)
131 {
132 throw std::runtime_error("TxTest::createAccount: failed to create account");
133 }
134
135 close();
136
137 if (accountFlags != 0)
138 {
139 auto const accountSetTer =
140 submit(transactions::AccountSetBuilder{account}.setSetFlag(accountFlags), account).ter;
141 if (accountSetTer != tesSUCCESS)
142 {
143 throw std::runtime_error("TxTest::createAccount: failed to set account flags");
144 }
145 close();
146 }
147}
148
151{
152 auto const sle = getOpenLedger().read(keylet::account(id));
153 if (!sle)
154 Throw<std::runtime_error>("TxTest::getAccountRoot: account not found");
156}
157
160{
161 return *openLedger_;
162}
163
164OpenView const&
166{
167 return *openLedger_;
168}
169
170ReadView const&
172{
173 return *closedLedger_;
174}
175
176void
178{
179 // Build a new closed ledger from the previous closed ledger,
180 // similar to how buildLedgerImpl works:
181 // 1. Create a new Ledger from the previous closed ledger
182 // 2. Re-apply transactions in canonical order
183 // 3. Mark it as accepted/immutable
184
185 auto const& prevLedger = *closedLedger_;
186
187 auto const ledgerCloseTime = now_ + prevLedger.header().closeTimeResolution;
188
189 now_ = ledgerCloseTime;
190
191 auto newLedger = std::make_shared<Ledger>(prevLedger, ledgerCloseTime);
192
193 CanonicalTXSet txSet(prevLedger.header().hash);
194 for (auto const& tx : pendingTxs_)
195 txSet.insert(tx);
196
197 {
198 OpenView accum(&*newLedger);
199 for (auto const& [key, tx] : txSet)
200 {
201 auto result = apply(registry_, accum, *tx, TapNone, registry_.getJournal("apply"));
202 if (!result.applied)
203 {
204 throw std::runtime_error("TxTest::close: failed to apply transaction");
205 }
206 }
207 accum.apply(*newLedger);
208 }
209
210 newLedger->setAccepted(ledgerCloseTime, newLedger->header().closeTimeResolution, true);
211
212 closedLedger_ = newLedger;
213
214 pendingTxs_.clear();
215
217 // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
219}
220
221void
226
229{
230 return now_;
231}
232
234TxTest::getBalance(AccountID const& account, IOU const& iou) const
235{
236 auto const sle = openLedger_->read(keylet::trustLine(account, iou.issue()));
237 if (!sle)
238 return STAmount{iou.issue(), 0};
239
240 auto const trustLine = ledger_entries::RippleState{sle};
241
242 auto balance = trustLine.getBalance();
243 if (iou.issue().account == account)
244 {
245 throw std::logic_error("TxTest::getBalance: account is issuer");
246 }
247
248 balance.get<Issue>().account = iou.issue().account;
249 if (account > iou.issue().account)
250 balance.negate();
251 return balance;
252}
253
254} // namespace xrpl::test
Holds transactions which were deferred to the next pass of consensus.
void insert(std::shared_ptr< STTx const > txn)
A currency issued by an account.
Definition Issue.h:18
AccountID account
Definition Issue.h:21
std::chrono::time_point< NetClock > time_point
Definition chrono.h:48
std::chrono::duration< rep, period > duration
Definition chrono.h:47
Writable ledger view that accumulates state and tx changes.
Definition OpenView.h:59
SLE::const_pointer read(Keylet const &k) const override
Return the state item associated with a key.
Definition OpenView.cpp:167
void apply(TxsRawView &to) const
Apply changes.
Definition OpenView.cpp:126
A view into a ledger.
Definition ReadView.h:41
Rules controlling protocol behavior.
Definition Rules.h:40
Ledger Entry: AccountRoot.
Definition AccountRoot.h:28
Ledger Entry: RippleState.
Definition RippleState.h:28
static Account const kMaster
The master account that holds all XRP in genesis.
TxTest(std::optional< FeatureBitset > features=std::nullopt)
Construct a TxTest environment.
Definition TxTest.cpp:62
void createAccount(Account const &account, XRPAmount xrp, uint32_t accountFlags=0)
Create a new account in the ledger.
Definition TxTest.cpp:125
std::unordered_set< uint256, beast::Uhash<> > featureSet_
Definition TxTest.h:358
NetClock::time_point getCloseTime() const
Get the current ledger close time.
Definition TxTest.cpp:228
std::shared_ptr< Ledger const > closedLedger_
Definition TxTest.h:360
OpenView & getOpenLedger()
Get the current open ledger view.
Definition TxTest.cpp:159
NetClock::time_point now_
Current time (can be advanced arbitrarily for testing).
Definition TxTest.h:371
ReadView const & getClosedLedger() const
Get the closed (base) ledger view.
Definition TxTest.cpp:171
TestServiceRegistry registry_
Definition TxTest.h:357
bool isEnabled(uint256 const &feature) const
Check if a feature is enabled.
Definition TxTest.cpp:94
Rules const & getRules() const
Get the current rules.
Definition TxTest.cpp:101
void close()
Close the current ledger.
Definition TxTest.cpp:177
void advanceTime(NetClock::duration duration)
Advance time without closing the ledger.
Definition TxTest.cpp:222
std::vector< std::shared_ptr< STTx const > > pendingTxs_
Transactions submitted to the open ledger, for canonical reordering on close.
Definition TxTest.h:366
std::optional< Rules > rules_
Definition TxTest.h:359
STAmount getBalance(AccountID const &account, IOU const &iou) const
Get the balance of an IOU for an account.
Definition TxTest.cpp:234
std::shared_ptr< OpenView > openLedger_
Definition TxTest.h:361
ledger_entries::AccountRoot getAccountRoot(AccountID const &id) const
Get the account root object from the current open ledger.
Definition TxTest.cpp:150
TxResult submit(T &&builder, Account const &signer)
Submit a transaction from a builder.
Definition TxTest.h:227
Immutable cryptographic account descriptor.
Definition jtx/Account.h:21
Converts to IOU Issue or STAmount.
AccountSetBuilder & setSetFlag(std::decay_t< typename SF_UINT32::type::value_type > const &value)
Set sfSetFlag (SoeOptional).
T make_shared(T... args)
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition Indexes.cpp:198
Keylet trustLine(AccountID const &id0, AccountID const &id1, Currency const &currency) noexcept
The index of a trust line for a given currency.
Definition Indexes.cpp:253
FeatureBitset allFeatures()
Returns all testable amendments.
Definition TxTest.cpp:42
constexpr XRPAmount
Convert XRP to drops (integral types).
Definition TxTest.h:54
ApplyResult apply(ServiceRegistry &registry, OpenView &view, STTx const &tx, ApplyFlags flags, beast::Journal journal)
Apply a transaction to an OpenView.
Definition apply.cpp:122
CreateGenesisT const kCreateGenesis
void foreachFeature(FeatureBitset bs, F &&f)
Definition Feature.h:383
@ TapNone
Definition ApplyView.h:28
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:34
std::map< std::string, AmendmentSupport > const & allAmendments()
All amendments libxrpl knows about.
constexpr struct xrpl::OpenLedgerT kOpenLedger
std::optional< uint256 > getRegisteredFeature(std::string const &name)
BaseUInt< 256 > uint256
Definition base_uint.h:580
@ tesSUCCESS
Definition TER.h:245
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
T const_pointer_cast(T... args)
T push_back(T... args)
T reserve(T... args)
Reflects the fee settings for a particular ledger.
Result of a transaction submission in TxTest.
Definition TxTest.h:159
TER ter
The transaction engine result code.
Definition TxTest.h:160
T value_or(T... args)