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
84 now_ = closedLedger_->header().closeTime;
85
86 // Create an open view on top of the genesis ledger
89}
90
91bool
92TxTest::isEnabled(uint256 const& feature) const
93{
94 // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
95 return rules_->enabled(feature);
96}
97
98Rules const&
100{
101 // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
102 return *rules_;
103}
104
105[[nodiscard]] TxResult
107{
108 auto result = apply(registry_, *openLedger_, *stx, TapNone, registry_.getJournal("apply"));
109
110 // Track successfully applied transactions for canonical reordering on close
111 // We make a copy since the TransactionBase doesn't own the STTx
112 if (result.applied)
113 pendingTxs_.push_back(stx);
114
115 return TxResult{
116 .ter = result.ter,
117 .applied = result.applied,
118 .metadata = std::move(result).metadata,
119 .tx = std::move(stx)};
120}
121
122void
123TxTest::createAccount(Account const& account, XRPAmount xrp, uint32_t accountFlags)
124{
125 auto const paymentTer =
127
128 if (paymentTer != tesSUCCESS)
129 {
130 throw std::runtime_error("TxTest::createAccount: failed to create account");
131 }
132
133 close();
134
135 if (accountFlags != 0)
136 {
137 auto const accountSetTer =
138 submit(transactions::AccountSetBuilder{account}.setSetFlag(accountFlags), account).ter;
139 if (accountSetTer != tesSUCCESS)
140 {
141 throw std::runtime_error("TxTest::createAccount: failed to set account flags");
142 }
143 close();
144 }
145}
146
149{
150 auto const sle = getOpenLedger().read(keylet::account(id));
151 if (!sle)
152 Throw<std::runtime_error>("TxTest::getAccountRoot: account not found");
154}
155
158{
159 return *openLedger_;
160}
161
162OpenView const&
164{
165 return *openLedger_;
166}
167
168ReadView const&
170{
171 return *closedLedger_;
172}
173
174void
176{
177 // Build a new closed ledger from the previous closed ledger,
178 // similar to how buildLedgerImpl works:
179 // 1. Create a new Ledger from the previous closed ledger
180 // 2. Re-apply transactions in canonical order
181 // 3. Mark it as accepted/immutable
182
183 auto const& prevLedger = *closedLedger_;
184
185 auto const ledgerCloseTime = now_ + prevLedger.header().closeTimeResolution;
186
187 now_ = ledgerCloseTime;
188
189 auto newLedger = std::make_shared<Ledger>(prevLedger, ledgerCloseTime);
190
191 CanonicalTXSet txSet(prevLedger.header().hash);
192 for (auto const& tx : pendingTxs_)
193 txSet.insert(tx);
194
195 {
196 OpenView accum(&*newLedger);
197 for (auto const& [key, tx] : txSet)
198 {
199 auto result = apply(registry_, accum, *tx, TapNone, registry_.getJournal("apply"));
200 if (!result.applied)
201 {
202 throw std::runtime_error("TxTest::close: failed to apply transaction");
203 }
204 }
205 accum.apply(*newLedger);
206 }
207
208 newLedger->setAccepted(ledgerCloseTime, newLedger->header().closeTimeResolution, true);
209
210 closedLedger_ = newLedger;
211
212 pendingTxs_.clear();
213
215 // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
217}
218
219void
224
227{
228 return now_;
229}
230
232TxTest::getBalance(AccountID const& account, IOU const& iou) const
233{
234 auto const sle = openLedger_->read(keylet::trustLine(account, iou.issue()));
235 if (!sle)
236 return STAmount{iou.issue(), 0};
237
238 auto const trustLine = ledger_entries::RippleState{sle};
239
240 auto balance = trustLine.getBalance();
241 if (iou.issue().account == account)
242 {
243 throw std::logic_error("TxTest::getBalance: account is issuer");
244 }
245
246 balance.get<Issue>().account = iou.issue().account;
247 if (account > iou.issue().account)
248 balance.negate();
249 return balance;
250}
251
252} // 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:13
AccountID account
Definition Issue.h:16
std::chrono::time_point< NetClock > time_point
Definition chrono.h:46
std::chrono::duration< rep, period > duration
Definition chrono.h:45
Writable ledger view that accumulates state and tx changes.
Definition OpenView.h:45
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:31
Rules controlling protocol behavior.
Definition Rules.h:33
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:123
std::unordered_set< uint256, beast::Uhash<> > featureSet_
Definition TxTest.h:352
NetClock::time_point getCloseTime() const
Get the current ledger close time.
Definition TxTest.cpp:226
std::shared_ptr< Ledger const > closedLedger_
Definition TxTest.h:354
OpenView & getOpenLedger()
Get the current open ledger view.
Definition TxTest.cpp:157
NetClock::time_point now_
Current time (can be advanced arbitrarily for testing).
Definition TxTest.h:361
ReadView const & getClosedLedger() const
Get the closed (base) ledger view.
Definition TxTest.cpp:169
TestServiceRegistry registry_
Definition TxTest.h:351
bool isEnabled(uint256 const &feature) const
Check if a feature is enabled.
Definition TxTest.cpp:92
Rules const & getRules() const
Get the current rules.
Definition TxTest.cpp:99
void close()
Close the current ledger.
Definition TxTest.cpp:175
void advanceTime(NetClock::duration duration)
Advance time without closing the ledger.
Definition TxTest.cpp:220
std::vector< std::shared_ptr< STTx const > > pendingTxs_
Transactions submitted to the open ledger, for canonical reordering on close.
Definition TxTest.h:358
std::optional< Rules > rules_
Definition TxTest.h:353
STAmount getBalance(AccountID const &account, IOU const &iou) const
Get the balance of an IOU for an account.
Definition TxTest.cpp:232
std::shared_ptr< OpenView > openLedger_
Definition TxTest.h:355
ledger_entries::AccountRoot getAccountRoot(AccountID const &id) const
Get the account root object from the current open ledger.
Definition TxTest.cpp:148
TxResult submit(T &&builder, Account const &signer)
Submit a transaction from a builder.
Definition TxTest.h:221
Immutable cryptographic account descriptor.
Definition jtx/Account.h:17
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:186
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:241
FeatureBitset allFeatures()
Returns all testable amendments.
Definition TxTest.cpp:42
constexpr XRPAmount
Convert XRP to drops (integral types).
Definition TxTest.h:48
ApplyResult apply(ServiceRegistry &registry, OpenView &view, STTx const &tx, ApplyFlags flags, beast::Journal journal)
Apply a transaction to an OpenView.
Definition apply.cpp:139
CreateGenesisT const kCreateGenesis
void foreachFeature(FeatureBitset bs, F &&f)
Definition Feature.h:375
@ TapNone
Definition ApplyView.h:13
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:28
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:562
@ tesSUCCESS
Definition TER.h:240
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:49
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:153
TER ter
The transaction engine result code.
Definition TxTest.h:154
T value_or(T... args)