xrpld
Loading...
Searching...
No Matches
VaultCreateTests.cpp
1// Auto-generated unit tests for transaction VaultCreate
2
3
4#include <gtest/gtest.h>
5
6#include <protocol_autogen/TestHelpers.h>
7
8#include <xrpl/protocol/SecretKey.h>
9#include <xrpl/protocol/Seed.h>
10#include <xrpl/protocol/STTx.h>
11#include <xrpl/protocol_autogen/transactions/VaultCreate.h>
12#include <xrpl/protocol_autogen/transactions/AccountSet.h>
13
14#include <string>
15
16namespace xrpl::transactions {
17
18// 1 & 4) Set fields via builder setters, build, then read them back via
19// wrapper getters. After build(), validate() should succeed.
20TEST(TransactionsVaultCreateTests, BuilderSettersRoundTrip)
21{
22 // Generate a deterministic keypair for signing
23 auto const [publicKey, secretKey] =
25
26 // Common transaction fields
27 auto const accountValue = calcAccountID(publicKey);
28 std::uint32_t const sequenceValue = 1;
29 auto const feeValue = canonical_AMOUNT();
30
31 // Transaction-specific field values
32 auto const assetValue = canonical_ISSUE();
33 auto const assetsMaximumValue = canonical_NUMBER();
34 auto const mPTokenMetadataValue = canonical_VL();
35 auto const domainIDValue = canonical_UINT256();
36 auto const withdrawalPolicyValue = canonical_UINT8();
37 auto const dataValue = canonical_VL();
38 auto const scaleValue = canonical_UINT8();
39 auto const vaultKindValue = canonical_UINT8();
40 auto const subscriptionDateValue = canonical_UINT32();
41 auto const redemptionDateValue = canonical_UINT32();
42
43 VaultCreateBuilder builder{
44 accountValue,
45 assetValue,
46 sequenceValue,
47 feeValue
48 };
49
50 // Set optional fields
51 builder.setAssetsMaximum(assetsMaximumValue);
52 builder.setMPTokenMetadata(mPTokenMetadataValue);
53 builder.setDomainID(domainIDValue);
54 builder.setWithdrawalPolicy(withdrawalPolicyValue);
55 builder.setData(dataValue);
56 builder.setScale(scaleValue);
57 builder.setVaultKind(vaultKindValue);
58 builder.setSubscriptionDate(subscriptionDateValue);
59 builder.setRedemptionDate(redemptionDateValue);
60
61 auto tx = builder.build(publicKey, secretKey);
62
63 std::string reason;
64 EXPECT_TRUE(tx.validate(reason)) << reason;
65
66 // Verify signing was applied
67 EXPECT_FALSE(tx.getSigningPubKey().empty());
68 EXPECT_TRUE(tx.hasTxnSignature());
69
70 // Verify common fields
71 EXPECT_EQ(tx.getAccount(), accountValue);
72 EXPECT_EQ(tx.getSequence(), sequenceValue);
73 EXPECT_EQ(tx.getFee(), feeValue);
74
75 // Verify required fields
76 {
77 auto const& expected = assetValue;
78 auto const actual = tx.getAsset();
79 expectEqualField(expected, actual, "sfAsset");
80 }
81
82 // Verify optional fields
83 {
84 auto const& expected = assetsMaximumValue;
85 auto const actualOpt = tx.getAssetsMaximum();
86 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAssetsMaximum should be present";
87 expectEqualField(expected, *actualOpt, "sfAssetsMaximum");
88 EXPECT_TRUE(tx.hasAssetsMaximum());
89 }
90
91 {
92 auto const& expected = mPTokenMetadataValue;
93 auto const actualOpt = tx.getMPTokenMetadata();
94 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMPTokenMetadata should be present";
95 expectEqualField(expected, *actualOpt, "sfMPTokenMetadata");
96 EXPECT_TRUE(tx.hasMPTokenMetadata());
97 }
98
99 {
100 auto const& expected = domainIDValue;
101 auto const actualOpt = tx.getDomainID();
102 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present";
103 expectEqualField(expected, *actualOpt, "sfDomainID");
104 EXPECT_TRUE(tx.hasDomainID());
105 }
106
107 {
108 auto const& expected = withdrawalPolicyValue;
109 auto const actualOpt = tx.getWithdrawalPolicy();
110 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfWithdrawalPolicy should be present";
111 expectEqualField(expected, *actualOpt, "sfWithdrawalPolicy");
112 EXPECT_TRUE(tx.hasWithdrawalPolicy());
113 }
114
115 {
116 auto const& expected = dataValue;
117 auto const actualOpt = tx.getData();
118 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfData should be present";
119 expectEqualField(expected, *actualOpt, "sfData");
120 EXPECT_TRUE(tx.hasData());
121 }
122
123 {
124 auto const& expected = scaleValue;
125 auto const actualOpt = tx.getScale();
126 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfScale should be present";
127 expectEqualField(expected, *actualOpt, "sfScale");
128 EXPECT_TRUE(tx.hasScale());
129 }
130
131 {
132 auto const& expected = vaultKindValue;
133 auto const actualOpt = tx.getVaultKind();
134 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfVaultKind should be present";
135 expectEqualField(expected, *actualOpt, "sfVaultKind");
136 EXPECT_TRUE(tx.hasVaultKind());
137 }
138
139 {
140 auto const& expected = subscriptionDateValue;
141 auto const actualOpt = tx.getSubscriptionDate();
142 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfSubscriptionDate should be present";
143 expectEqualField(expected, *actualOpt, "sfSubscriptionDate");
144 EXPECT_TRUE(tx.hasSubscriptionDate());
145 }
146
147 {
148 auto const& expected = redemptionDateValue;
149 auto const actualOpt = tx.getRedemptionDate();
150 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfRedemptionDate should be present";
151 expectEqualField(expected, *actualOpt, "sfRedemptionDate");
152 EXPECT_TRUE(tx.hasRedemptionDate());
153 }
154
155}
156
157// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper,
158// and verify all fields match.
159TEST(TransactionsVaultCreateTests, BuilderFromStTxRoundTrip)
160{
161 // Generate a deterministic keypair for signing
162 auto const [publicKey, secretKey] =
163 generateKeyPair(KeyType::Secp256k1, generateSeed("testVaultCreateFromTx"));
164
165 // Common transaction fields
166 auto const accountValue = calcAccountID(publicKey);
167 std::uint32_t const sequenceValue = 2;
168 auto const feeValue = canonical_AMOUNT();
169
170 // Transaction-specific field values
171 auto const assetValue = canonical_ISSUE();
172 auto const assetsMaximumValue = canonical_NUMBER();
173 auto const mPTokenMetadataValue = canonical_VL();
174 auto const domainIDValue = canonical_UINT256();
175 auto const withdrawalPolicyValue = canonical_UINT8();
176 auto const dataValue = canonical_VL();
177 auto const scaleValue = canonical_UINT8();
178 auto const vaultKindValue = canonical_UINT8();
179 auto const subscriptionDateValue = canonical_UINT32();
180 auto const redemptionDateValue = canonical_UINT32();
181
182 // Build an initial transaction
183 VaultCreateBuilder initialBuilder{
184 accountValue,
185 assetValue,
186 sequenceValue,
187 feeValue
188 };
189
190 initialBuilder.setAssetsMaximum(assetsMaximumValue);
191 initialBuilder.setMPTokenMetadata(mPTokenMetadataValue);
192 initialBuilder.setDomainID(domainIDValue);
193 initialBuilder.setWithdrawalPolicy(withdrawalPolicyValue);
194 initialBuilder.setData(dataValue);
195 initialBuilder.setScale(scaleValue);
196 initialBuilder.setVaultKind(vaultKindValue);
197 initialBuilder.setSubscriptionDate(subscriptionDateValue);
198 initialBuilder.setRedemptionDate(redemptionDateValue);
199
200 auto initialTx = initialBuilder.build(publicKey, secretKey);
201
202 // Create builder from existing STTx
203 VaultCreateBuilder builderFromTx{initialTx.getSTTx()};
204
205 auto rebuiltTx = builderFromTx.build(publicKey, secretKey);
206
207 std::string reason;
208 EXPECT_TRUE(rebuiltTx.validate(reason)) << reason;
209
210 // Verify common fields
211 EXPECT_EQ(rebuiltTx.getAccount(), accountValue);
212 EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue);
213 EXPECT_EQ(rebuiltTx.getFee(), feeValue);
214
215 // Verify required fields
216 {
217 auto const& expected = assetValue;
218 auto const actual = rebuiltTx.getAsset();
219 expectEqualField(expected, actual, "sfAsset");
220 }
221
222 // Verify optional fields
223 {
224 auto const& expected = assetsMaximumValue;
225 auto const actualOpt = rebuiltTx.getAssetsMaximum();
226 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAssetsMaximum should be present";
227 expectEqualField(expected, *actualOpt, "sfAssetsMaximum");
228 }
229
230 {
231 auto const& expected = mPTokenMetadataValue;
232 auto const actualOpt = rebuiltTx.getMPTokenMetadata();
233 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfMPTokenMetadata should be present";
234 expectEqualField(expected, *actualOpt, "sfMPTokenMetadata");
235 }
236
237 {
238 auto const& expected = domainIDValue;
239 auto const actualOpt = rebuiltTx.getDomainID();
240 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDomainID should be present";
241 expectEqualField(expected, *actualOpt, "sfDomainID");
242 }
243
244 {
245 auto const& expected = withdrawalPolicyValue;
246 auto const actualOpt = rebuiltTx.getWithdrawalPolicy();
247 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfWithdrawalPolicy should be present";
248 expectEqualField(expected, *actualOpt, "sfWithdrawalPolicy");
249 }
250
251 {
252 auto const& expected = dataValue;
253 auto const actualOpt = rebuiltTx.getData();
254 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfData should be present";
255 expectEqualField(expected, *actualOpt, "sfData");
256 }
257
258 {
259 auto const& expected = scaleValue;
260 auto const actualOpt = rebuiltTx.getScale();
261 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfScale should be present";
262 expectEqualField(expected, *actualOpt, "sfScale");
263 }
264
265 {
266 auto const& expected = vaultKindValue;
267 auto const actualOpt = rebuiltTx.getVaultKind();
268 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfVaultKind should be present";
269 expectEqualField(expected, *actualOpt, "sfVaultKind");
270 }
271
272 {
273 auto const& expected = subscriptionDateValue;
274 auto const actualOpt = rebuiltTx.getSubscriptionDate();
275 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfSubscriptionDate should be present";
276 expectEqualField(expected, *actualOpt, "sfSubscriptionDate");
277 }
278
279 {
280 auto const& expected = redemptionDateValue;
281 auto const actualOpt = rebuiltTx.getRedemptionDate();
282 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfRedemptionDate should be present";
283 expectEqualField(expected, *actualOpt, "sfRedemptionDate");
284 }
285
286}
287
288// 3) Verify wrapper throws when constructed from wrong transaction type.
289TEST(TransactionsVaultCreateTests, WrapperThrowsOnWrongTxType)
290{
291 // Build a valid transaction of a different type
292 auto const [pk, sk] =
294 auto const account = calcAccountID(pk);
295
296 AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()};
297 auto wrongTx = wrongBuilder.build(pk, sk);
298
299 EXPECT_THROW(VaultCreate{wrongTx.getSTTx()}, std::runtime_error);
300}
301
302// 4) Verify builder throws when constructed from wrong transaction type.
303TEST(TransactionsVaultCreateTests, BuilderThrowsOnWrongTxType)
304{
305 // Build a valid transaction of a different type
306 auto const [pk, sk] =
307 generateKeyPair(KeyType::Secp256k1, generateSeed("testWrongTypeBuilder"));
308 auto const account = calcAccountID(pk);
309
310 AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()};
311 auto wrongTx = wrongBuilder.build(pk, sk);
312
313 EXPECT_THROW(VaultCreateBuilder{wrongTx.getSTTx()}, std::runtime_error);
314}
315
316// 5) Build with only required fields and verify optional fields return nullopt.
317TEST(TransactionsVaultCreateTests, OptionalFieldsReturnNullopt)
318{
319 // Generate a deterministic keypair for signing
320 auto const [publicKey, secretKey] =
321 generateKeyPair(KeyType::Secp256k1, generateSeed("testVaultCreateNullopt"));
322
323 // Common transaction fields
324 auto const accountValue = calcAccountID(publicKey);
325 std::uint32_t const sequenceValue = 3;
326 auto const feeValue = canonical_AMOUNT();
327
328 // Transaction-specific required field values
329 auto const assetValue = canonical_ISSUE();
330
331 VaultCreateBuilder builder{
332 accountValue,
333 assetValue,
334 sequenceValue,
335 feeValue
336 };
337
338 // Do NOT set optional fields
339
340 auto tx = builder.build(publicKey, secretKey);
341
342 // Verify optional fields are not present
343 EXPECT_FALSE(tx.hasAssetsMaximum());
344 EXPECT_FALSE(tx.getAssetsMaximum().has_value());
345 EXPECT_FALSE(tx.hasMPTokenMetadata());
346 EXPECT_FALSE(tx.getMPTokenMetadata().has_value());
347 EXPECT_FALSE(tx.hasDomainID());
348 EXPECT_FALSE(tx.getDomainID().has_value());
349 EXPECT_FALSE(tx.hasWithdrawalPolicy());
350 EXPECT_FALSE(tx.getWithdrawalPolicy().has_value());
351 EXPECT_FALSE(tx.hasData());
352 EXPECT_FALSE(tx.getData().has_value());
353 EXPECT_FALSE(tx.hasScale());
354 EXPECT_FALSE(tx.getScale().has_value());
355 EXPECT_FALSE(tx.hasVaultKind());
356 EXPECT_FALSE(tx.getVaultKind().has_value());
357 EXPECT_FALSE(tx.hasSubscriptionDate());
358 EXPECT_FALSE(tx.getSubscriptionDate().has_value());
359 EXPECT_FALSE(tx.hasRedemptionDate());
360 EXPECT_FALSE(tx.getRedemptionDate().has_value());
361}
362
363}
AccountSet build(PublicKey const &publicKey, SecretKey const &secretKey)
Build and return the AccountSet wrapper.
VaultCreateBuilder & setWithdrawalPolicy(std::decay_t< typename SF_UINT8::type::value_type > const &value)
Set sfWithdrawalPolicy (SoeOptional).
VaultCreateBuilder & setDomainID(std::decay_t< typename SF_UINT256::type::value_type > const &value)
Set sfDomainID (SoeOptional).
VaultCreateBuilder & setMPTokenMetadata(std::decay_t< typename SF_VL::type::value_type > const &value)
Set sfMPTokenMetadata (SoeOptional).
VaultCreateBuilder & setSubscriptionDate(std::decay_t< typename SF_UINT32::type::value_type > const &value)
Set sfSubscriptionDate (SoeOptional).
VaultCreateBuilder & setRedemptionDate(std::decay_t< typename SF_UINT32::type::value_type > const &value)
Set sfRedemptionDate (SoeOptional).
VaultCreateBuilder & setData(std::decay_t< typename SF_VL::type::value_type > const &value)
Set sfData (SoeOptional).
VaultCreate build(PublicKey const &publicKey, SecretKey const &secretKey)
Build and return the VaultCreate wrapper.
VaultCreateBuilder & setScale(std::decay_t< typename SF_UINT8::type::value_type > const &value)
Set sfScale (SoeOptional).
VaultCreateBuilder & setVaultKind(std::decay_t< typename SF_UINT8::type::value_type > const &value)
Set sfVaultKind (SoeOptional).
VaultCreateBuilder & setAssetsMaximum(std::decay_t< typename SF_NUMBER::type::value_type > const &value)
Set sfAssetsMaximum (SoeOptional).
TEST(TransactionsAccountDeleteTests, BuilderSettersRoundTrip)
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
Definition Seed.cpp:58
std::pair< PublicKey, SecretKey > generateKeyPair(KeyType type, Seed const &seed)
Generate a key pair deterministically.
AccountID calcAccountID(PublicKey const &pk)
void expectEqualField(T const &expected, T const &actual, char const *fieldName)