rippled
Loading...
Searching...
No Matches
CheckTests.cpp
1// Auto-generated unit tests for ledger entry Check
2
3
4#include <gtest/gtest.h>
5
6#include <protocol_autogen/TestHelpers.h>
7
8#include <xrpl/protocol/STLedgerEntry.h>
9#include <xrpl/protocol_autogen/ledger_entries/Check.h>
10#include <xrpl/protocol_autogen/ledger_entries/Ticket.h>
11
12#include <string>
13
14namespace xrpl::ledger_entries {
15
16// 1 & 4) Set fields via builder setters, build, then read them back via
17// wrapper getters. After build(), validate() should succeed for both the
18// builder's STObject and the wrapper's SLE.
19TEST(CheckTests, BuilderSettersRoundTrip)
20{
21 uint256 const index{1u};
22
23 auto const accountValue = canonical_ACCOUNT();
24 auto const destinationValue = canonical_ACCOUNT();
25 auto const sendMaxValue = canonical_AMOUNT();
26 auto const sequenceValue = canonical_UINT32();
27 auto const ownerNodeValue = canonical_UINT64();
28 auto const destinationNodeValue = canonical_UINT64();
29 auto const expirationValue = canonical_UINT32();
30 auto const invoiceIDValue = canonical_UINT256();
31 auto const sourceTagValue = canonical_UINT32();
32 auto const destinationTagValue = canonical_UINT32();
33 auto const previousTxnIDValue = canonical_UINT256();
34 auto const previousTxnLgrSeqValue = canonical_UINT32();
35
36 CheckBuilder builder{
37 accountValue,
38 destinationValue,
39 sendMaxValue,
40 sequenceValue,
41 ownerNodeValue,
42 destinationNodeValue,
43 previousTxnIDValue,
44 previousTxnLgrSeqValue
45 };
46
47 builder.setExpiration(expirationValue);
48 builder.setInvoiceID(invoiceIDValue);
49 builder.setSourceTag(sourceTagValue);
50 builder.setDestinationTag(destinationTagValue);
51
52 builder.setLedgerIndex(index);
53 builder.setFlags(0x1u);
54
55 EXPECT_TRUE(builder.validate());
56
57 auto const entry = builder.build(index);
58
59 EXPECT_TRUE(entry.validate());
60
61 {
62 auto const& expected = accountValue;
63 auto const actual = entry.getAccount();
64 expectEqualField(expected, actual, "sfAccount");
65 }
66
67 {
68 auto const& expected = destinationValue;
69 auto const actual = entry.getDestination();
70 expectEqualField(expected, actual, "sfDestination");
71 }
72
73 {
74 auto const& expected = sendMaxValue;
75 auto const actual = entry.getSendMax();
76 expectEqualField(expected, actual, "sfSendMax");
77 }
78
79 {
80 auto const& expected = sequenceValue;
81 auto const actual = entry.getSequence();
82 expectEqualField(expected, actual, "sfSequence");
83 }
84
85 {
86 auto const& expected = ownerNodeValue;
87 auto const actual = entry.getOwnerNode();
88 expectEqualField(expected, actual, "sfOwnerNode");
89 }
90
91 {
92 auto const& expected = destinationNodeValue;
93 auto const actual = entry.getDestinationNode();
94 expectEqualField(expected, actual, "sfDestinationNode");
95 }
96
97 {
98 auto const& expected = previousTxnIDValue;
99 auto const actual = entry.getPreviousTxnID();
100 expectEqualField(expected, actual, "sfPreviousTxnID");
101 }
102
103 {
104 auto const& expected = previousTxnLgrSeqValue;
105 auto const actual = entry.getPreviousTxnLgrSeq();
106 expectEqualField(expected, actual, "sfPreviousTxnLgrSeq");
107 }
108
109 {
110 auto const& expected = expirationValue;
111 auto const actualOpt = entry.getExpiration();
112 ASSERT_TRUE(actualOpt.has_value());
113 expectEqualField(expected, *actualOpt, "sfExpiration");
114 EXPECT_TRUE(entry.hasExpiration());
115 }
116
117 {
118 auto const& expected = invoiceIDValue;
119 auto const actualOpt = entry.getInvoiceID();
120 ASSERT_TRUE(actualOpt.has_value());
121 expectEqualField(expected, *actualOpt, "sfInvoiceID");
122 EXPECT_TRUE(entry.hasInvoiceID());
123 }
124
125 {
126 auto const& expected = sourceTagValue;
127 auto const actualOpt = entry.getSourceTag();
128 ASSERT_TRUE(actualOpt.has_value());
129 expectEqualField(expected, *actualOpt, "sfSourceTag");
130 EXPECT_TRUE(entry.hasSourceTag());
131 }
132
133 {
134 auto const& expected = destinationTagValue;
135 auto const actualOpt = entry.getDestinationTag();
136 ASSERT_TRUE(actualOpt.has_value());
137 expectEqualField(expected, *actualOpt, "sfDestinationTag");
138 EXPECT_TRUE(entry.hasDestinationTag());
139 }
140
141 EXPECT_TRUE(entry.hasLedgerIndex());
142 auto const ledgerIndex = entry.getLedgerIndex();
143 ASSERT_TRUE(ledgerIndex.has_value());
144 EXPECT_EQ(*ledgerIndex, index);
145 EXPECT_EQ(entry.getKey(), index);
146}
147
148// 2 & 4) Start from an SLE, set fields directly on it, construct a builder
149// from that SLE, build a new wrapper, and verify all fields (and validate()).
150TEST(CheckTests, BuilderFromSleRoundTrip)
151{
152 uint256 const index{2u};
153
154 auto const accountValue = canonical_ACCOUNT();
155 auto const destinationValue = canonical_ACCOUNT();
156 auto const sendMaxValue = canonical_AMOUNT();
157 auto const sequenceValue = canonical_UINT32();
158 auto const ownerNodeValue = canonical_UINT64();
159 auto const destinationNodeValue = canonical_UINT64();
160 auto const expirationValue = canonical_UINT32();
161 auto const invoiceIDValue = canonical_UINT256();
162 auto const sourceTagValue = canonical_UINT32();
163 auto const destinationTagValue = canonical_UINT32();
164 auto const previousTxnIDValue = canonical_UINT256();
165 auto const previousTxnLgrSeqValue = canonical_UINT32();
166
167 auto sle = std::make_shared<SLE>(Check::entryType, index);
168
169 sle->at(sfAccount) = accountValue;
170 sle->at(sfDestination) = destinationValue;
171 sle->at(sfSendMax) = sendMaxValue;
172 sle->at(sfSequence) = sequenceValue;
173 sle->at(sfOwnerNode) = ownerNodeValue;
174 sle->at(sfDestinationNode) = destinationNodeValue;
175 sle->at(sfExpiration) = expirationValue;
176 sle->at(sfInvoiceID) = invoiceIDValue;
177 sle->at(sfSourceTag) = sourceTagValue;
178 sle->at(sfDestinationTag) = destinationTagValue;
179 sle->at(sfPreviousTxnID) = previousTxnIDValue;
180 sle->at(sfPreviousTxnLgrSeq) = previousTxnLgrSeqValue;
181
182 CheckBuilder builderFromSle{sle};
183 EXPECT_TRUE(builderFromSle.validate());
184
185 auto const entryFromBuilder = builderFromSle.build(index);
186
187 Check entryFromSle{sle};
188 EXPECT_TRUE(entryFromBuilder.validate());
189 EXPECT_TRUE(entryFromSle.validate());
190
191 {
192 auto const& expected = accountValue;
193
194 auto const fromSle = entryFromSle.getAccount();
195 auto const fromBuilder = entryFromBuilder.getAccount();
196
197 expectEqualField(expected, fromSle, "sfAccount");
198 expectEqualField(expected, fromBuilder, "sfAccount");
199 }
200
201 {
202 auto const& expected = destinationValue;
203
204 auto const fromSle = entryFromSle.getDestination();
205 auto const fromBuilder = entryFromBuilder.getDestination();
206
207 expectEqualField(expected, fromSle, "sfDestination");
208 expectEqualField(expected, fromBuilder, "sfDestination");
209 }
210
211 {
212 auto const& expected = sendMaxValue;
213
214 auto const fromSle = entryFromSle.getSendMax();
215 auto const fromBuilder = entryFromBuilder.getSendMax();
216
217 expectEqualField(expected, fromSle, "sfSendMax");
218 expectEqualField(expected, fromBuilder, "sfSendMax");
219 }
220
221 {
222 auto const& expected = sequenceValue;
223
224 auto const fromSle = entryFromSle.getSequence();
225 auto const fromBuilder = entryFromBuilder.getSequence();
226
227 expectEqualField(expected, fromSle, "sfSequence");
228 expectEqualField(expected, fromBuilder, "sfSequence");
229 }
230
231 {
232 auto const& expected = ownerNodeValue;
233
234 auto const fromSle = entryFromSle.getOwnerNode();
235 auto const fromBuilder = entryFromBuilder.getOwnerNode();
236
237 expectEqualField(expected, fromSle, "sfOwnerNode");
238 expectEqualField(expected, fromBuilder, "sfOwnerNode");
239 }
240
241 {
242 auto const& expected = destinationNodeValue;
243
244 auto const fromSle = entryFromSle.getDestinationNode();
245 auto const fromBuilder = entryFromBuilder.getDestinationNode();
246
247 expectEqualField(expected, fromSle, "sfDestinationNode");
248 expectEqualField(expected, fromBuilder, "sfDestinationNode");
249 }
250
251 {
252 auto const& expected = previousTxnIDValue;
253
254 auto const fromSle = entryFromSle.getPreviousTxnID();
255 auto const fromBuilder = entryFromBuilder.getPreviousTxnID();
256
257 expectEqualField(expected, fromSle, "sfPreviousTxnID");
258 expectEqualField(expected, fromBuilder, "sfPreviousTxnID");
259 }
260
261 {
262 auto const& expected = previousTxnLgrSeqValue;
263
264 auto const fromSle = entryFromSle.getPreviousTxnLgrSeq();
265 auto const fromBuilder = entryFromBuilder.getPreviousTxnLgrSeq();
266
267 expectEqualField(expected, fromSle, "sfPreviousTxnLgrSeq");
268 expectEqualField(expected, fromBuilder, "sfPreviousTxnLgrSeq");
269 }
270
271 {
272 auto const& expected = expirationValue;
273
274 auto const fromSleOpt = entryFromSle.getExpiration();
275 auto const fromBuilderOpt = entryFromBuilder.getExpiration();
276
277 ASSERT_TRUE(fromSleOpt.has_value());
278 ASSERT_TRUE(fromBuilderOpt.has_value());
279
280 expectEqualField(expected, *fromSleOpt, "sfExpiration");
281 expectEqualField(expected, *fromBuilderOpt, "sfExpiration");
282 }
283
284 {
285 auto const& expected = invoiceIDValue;
286
287 auto const fromSleOpt = entryFromSle.getInvoiceID();
288 auto const fromBuilderOpt = entryFromBuilder.getInvoiceID();
289
290 ASSERT_TRUE(fromSleOpt.has_value());
291 ASSERT_TRUE(fromBuilderOpt.has_value());
292
293 expectEqualField(expected, *fromSleOpt, "sfInvoiceID");
294 expectEqualField(expected, *fromBuilderOpt, "sfInvoiceID");
295 }
296
297 {
298 auto const& expected = sourceTagValue;
299
300 auto const fromSleOpt = entryFromSle.getSourceTag();
301 auto const fromBuilderOpt = entryFromBuilder.getSourceTag();
302
303 ASSERT_TRUE(fromSleOpt.has_value());
304 ASSERT_TRUE(fromBuilderOpt.has_value());
305
306 expectEqualField(expected, *fromSleOpt, "sfSourceTag");
307 expectEqualField(expected, *fromBuilderOpt, "sfSourceTag");
308 }
309
310 {
311 auto const& expected = destinationTagValue;
312
313 auto const fromSleOpt = entryFromSle.getDestinationTag();
314 auto const fromBuilderOpt = entryFromBuilder.getDestinationTag();
315
316 ASSERT_TRUE(fromSleOpt.has_value());
317 ASSERT_TRUE(fromBuilderOpt.has_value());
318
319 expectEqualField(expected, *fromSleOpt, "sfDestinationTag");
320 expectEqualField(expected, *fromBuilderOpt, "sfDestinationTag");
321 }
322
323 EXPECT_EQ(entryFromSle.getKey(), index);
324 EXPECT_EQ(entryFromBuilder.getKey(), index);
325}
326
327// 3) Verify wrapper throws when constructed from wrong ledger entry type.
328TEST(CheckTests, WrapperThrowsOnWrongEntryType)
329{
330 uint256 const index{3u};
331
332 // Build a valid ledger entry of a different type
333 // Ticket requires: Account, OwnerNode, TicketSequence, PreviousTxnID, PreviousTxnLgrSeq
334 // Check requires: Account, Destination, SendMax, Sequence, OwnerNode, DestinationNode, PreviousTxnID, PreviousTxnLgrSeq
335 TicketBuilder wrongBuilder{
341 auto wrongEntry = wrongBuilder.build(index);
342
343 EXPECT_THROW(Check{wrongEntry.getSle()}, std::runtime_error);
344}
345
346// 4) Verify builder throws when constructed from wrong ledger entry type.
347TEST(CheckTests, BuilderThrowsOnWrongEntryType)
348{
349 uint256 const index{4u};
350
351 // Build a valid ledger entry of a different type
352 TicketBuilder wrongBuilder{
358 auto wrongEntry = wrongBuilder.build(index);
359
360 EXPECT_THROW(CheckBuilder{wrongEntry.getSle()}, std::runtime_error);
361}
362
363// 5) Build with only required fields and verify optional fields return nullopt.
364TEST(CheckTests, OptionalFieldsReturnNullopt)
365{
366 uint256 const index{3u};
367
368 auto const accountValue = canonical_ACCOUNT();
369 auto const destinationValue = canonical_ACCOUNT();
370 auto const sendMaxValue = canonical_AMOUNT();
371 auto const sequenceValue = canonical_UINT32();
372 auto const ownerNodeValue = canonical_UINT64();
373 auto const destinationNodeValue = canonical_UINT64();
374 auto const previousTxnIDValue = canonical_UINT256();
375 auto const previousTxnLgrSeqValue = canonical_UINT32();
376
377 CheckBuilder builder{
378 accountValue,
379 destinationValue,
380 sendMaxValue,
381 sequenceValue,
382 ownerNodeValue,
383 destinationNodeValue,
384 previousTxnIDValue,
385 previousTxnLgrSeqValue
386 };
387
388 auto const entry = builder.build(index);
389
390 // Verify optional fields are not present
391 EXPECT_FALSE(entry.hasExpiration());
392 EXPECT_FALSE(entry.getExpiration().has_value());
393 EXPECT_FALSE(entry.hasInvoiceID());
394 EXPECT_FALSE(entry.getInvoiceID().has_value());
395 EXPECT_FALSE(entry.hasSourceTag());
396 EXPECT_FALSE(entry.getSourceTag().has_value());
397 EXPECT_FALSE(entry.hasDestinationTag());
398 EXPECT_FALSE(entry.getDestinationTag().has_value());
399}
400}
Builder for Check ledger entries.
Definition Check.h:241
CheckBuilder & setSourceTag(std::decay_t< typename SF_UINT32::type::value_type > const &value)
Set sfSourceTag (soeOPTIONAL)
Definition Check.h:376
CheckBuilder & setExpiration(std::decay_t< typename SF_UINT32::type::value_type > const &value)
Set sfExpiration (soeOPTIONAL)
Definition Check.h:354
CheckBuilder & setDestinationTag(std::decay_t< typename SF_UINT32::type::value_type > const &value)
Set sfDestinationTag (soeOPTIONAL)
Definition Check.h:387
CheckBuilder & setInvoiceID(std::decay_t< typename SF_UINT256::type::value_type > const &value)
Set sfInvoiceID (soeOPTIONAL)
Definition Check.h:365
Ledger Entry: Check.
Definition Check.h:28
static constexpr LedgerEntryType entryType
Definition Check.h:30
std::shared_ptr< SLE const > getSle() const
Get the underlying SLE object.
Derived & setLedgerIndex(uint256 const &value)
Set the ledger index.
Derived & setFlags(uint32_t value)
Set the flags.
Builder for Ticket ledger entries.
Definition Ticket.h:112
T is_same_v
TEST(AccountRootTests, BuilderSettersRoundTrip)
void expectEqualField(T const &expected, T const &actual, char const *fieldName)