xrpld
Loading...
Searching...
No Matches
ConfidentialMPTSendTests.cpp
1// Auto-generated unit tests for transaction ConfidentialMPTSend
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/ConfidentialMPTSend.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(TransactionsConfidentialMPTSendTests, BuilderSettersRoundTrip)
21{
22 // Generate a deterministic keypair for signing
23 auto const [publicKey, secretKey] =
24 generateKeyPair(KeyType::Secp256k1, generateSeed("testConfidentialMPTSend"));
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 mPTokenIssuanceIDValue = canonical_UINT192();
33 auto const destinationValue = canonical_ACCOUNT();
34 auto const destinationTagValue = canonical_UINT32();
35 auto const senderEncryptedAmountValue = canonical_VL();
36 auto const destinationEncryptedAmountValue = canonical_VL();
37 auto const issuerEncryptedAmountValue = canonical_VL();
38 auto const auditorEncryptedAmountValue = canonical_VL();
39 auto const zKProofValue = canonical_VL();
40 auto const amountCommitmentValue = canonical_VL();
41 auto const balanceCommitmentValue = canonical_VL();
42 auto const credentialIDsValue = canonical_VECTOR256();
43
45 accountValue,
46 mPTokenIssuanceIDValue,
47 destinationValue,
48 senderEncryptedAmountValue,
49 destinationEncryptedAmountValue,
50 issuerEncryptedAmountValue,
51 zKProofValue,
52 amountCommitmentValue,
53 balanceCommitmentValue,
54 sequenceValue,
55 feeValue
56 };
57
58 // Set optional fields
59 builder.setDestinationTag(destinationTagValue);
60 builder.setAuditorEncryptedAmount(auditorEncryptedAmountValue);
61 builder.setCredentialIDs(credentialIDsValue);
62
63 auto tx = builder.build(publicKey, secretKey);
64
65 std::string reason;
66 EXPECT_TRUE(tx.validate(reason)) << reason;
67
68 // Verify signing was applied
69 EXPECT_FALSE(tx.getSigningPubKey().empty());
70 EXPECT_TRUE(tx.hasTxnSignature());
71
72 // Verify common fields
73 EXPECT_EQ(tx.getAccount(), accountValue);
74 EXPECT_EQ(tx.getSequence(), sequenceValue);
75 EXPECT_EQ(tx.getFee(), feeValue);
76
77 // Verify required fields
78 {
79 auto const& expected = mPTokenIssuanceIDValue;
80 auto const actual = tx.getMPTokenIssuanceID();
81 expectEqualField(expected, actual, "sfMPTokenIssuanceID");
82 }
83
84 {
85 auto const& expected = destinationValue;
86 auto const actual = tx.getDestination();
87 expectEqualField(expected, actual, "sfDestination");
88 }
89
90 {
91 auto const& expected = senderEncryptedAmountValue;
92 auto const actual = tx.getSenderEncryptedAmount();
93 expectEqualField(expected, actual, "sfSenderEncryptedAmount");
94 }
95
96 {
97 auto const& expected = destinationEncryptedAmountValue;
98 auto const actual = tx.getDestinationEncryptedAmount();
99 expectEqualField(expected, actual, "sfDestinationEncryptedAmount");
100 }
101
102 {
103 auto const& expected = issuerEncryptedAmountValue;
104 auto const actual = tx.getIssuerEncryptedAmount();
105 expectEqualField(expected, actual, "sfIssuerEncryptedAmount");
106 }
107
108 {
109 auto const& expected = zKProofValue;
110 auto const actual = tx.getZKProof();
111 expectEqualField(expected, actual, "sfZKProof");
112 }
113
114 {
115 auto const& expected = amountCommitmentValue;
116 auto const actual = tx.getAmountCommitment();
117 expectEqualField(expected, actual, "sfAmountCommitment");
118 }
119
120 {
121 auto const& expected = balanceCommitmentValue;
122 auto const actual = tx.getBalanceCommitment();
123 expectEqualField(expected, actual, "sfBalanceCommitment");
124 }
125
126 // Verify optional fields
127 {
128 auto const& expected = destinationTagValue;
129 auto const actualOpt = tx.getDestinationTag();
130 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present";
131 expectEqualField(expected, *actualOpt, "sfDestinationTag");
132 EXPECT_TRUE(tx.hasDestinationTag());
133 }
134
135 {
136 auto const& expected = auditorEncryptedAmountValue;
137 auto const actualOpt = tx.getAuditorEncryptedAmount();
138 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAuditorEncryptedAmount should be present";
139 expectEqualField(expected, *actualOpt, "sfAuditorEncryptedAmount");
140 EXPECT_TRUE(tx.hasAuditorEncryptedAmount());
141 }
142
143 {
144 auto const& expected = credentialIDsValue;
145 auto const actualOpt = tx.getCredentialIDs();
146 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCredentialIDs should be present";
147 expectEqualField(expected, *actualOpt, "sfCredentialIDs");
148 EXPECT_TRUE(tx.hasCredentialIDs());
149 }
150
151}
152
153// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper,
154// and verify all fields match.
155TEST(TransactionsConfidentialMPTSendTests, BuilderFromStTxRoundTrip)
156{
157 // Generate a deterministic keypair for signing
158 auto const [publicKey, secretKey] =
159 generateKeyPair(KeyType::Secp256k1, generateSeed("testConfidentialMPTSendFromTx"));
160
161 // Common transaction fields
162 auto const accountValue = calcAccountID(publicKey);
163 std::uint32_t const sequenceValue = 2;
164 auto const feeValue = canonical_AMOUNT();
165
166 // Transaction-specific field values
167 auto const mPTokenIssuanceIDValue = canonical_UINT192();
168 auto const destinationValue = canonical_ACCOUNT();
169 auto const destinationTagValue = canonical_UINT32();
170 auto const senderEncryptedAmountValue = canonical_VL();
171 auto const destinationEncryptedAmountValue = canonical_VL();
172 auto const issuerEncryptedAmountValue = canonical_VL();
173 auto const auditorEncryptedAmountValue = canonical_VL();
174 auto const zKProofValue = canonical_VL();
175 auto const amountCommitmentValue = canonical_VL();
176 auto const balanceCommitmentValue = canonical_VL();
177 auto const credentialIDsValue = canonical_VECTOR256();
178
179 // Build an initial transaction
180 ConfidentialMPTSendBuilder initialBuilder{
181 accountValue,
182 mPTokenIssuanceIDValue,
183 destinationValue,
184 senderEncryptedAmountValue,
185 destinationEncryptedAmountValue,
186 issuerEncryptedAmountValue,
187 zKProofValue,
188 amountCommitmentValue,
189 balanceCommitmentValue,
190 sequenceValue,
191 feeValue
192 };
193
194 initialBuilder.setDestinationTag(destinationTagValue);
195 initialBuilder.setAuditorEncryptedAmount(auditorEncryptedAmountValue);
196 initialBuilder.setCredentialIDs(credentialIDsValue);
197
198 auto initialTx = initialBuilder.build(publicKey, secretKey);
199
200 // Create builder from existing STTx
201 ConfidentialMPTSendBuilder builderFromTx{initialTx.getSTTx()};
202
203 auto rebuiltTx = builderFromTx.build(publicKey, secretKey);
204
205 std::string reason;
206 EXPECT_TRUE(rebuiltTx.validate(reason)) << reason;
207
208 // Verify common fields
209 EXPECT_EQ(rebuiltTx.getAccount(), accountValue);
210 EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue);
211 EXPECT_EQ(rebuiltTx.getFee(), feeValue);
212
213 // Verify required fields
214 {
215 auto const& expected = mPTokenIssuanceIDValue;
216 auto const actual = rebuiltTx.getMPTokenIssuanceID();
217 expectEqualField(expected, actual, "sfMPTokenIssuanceID");
218 }
219
220 {
221 auto const& expected = destinationValue;
222 auto const actual = rebuiltTx.getDestination();
223 expectEqualField(expected, actual, "sfDestination");
224 }
225
226 {
227 auto const& expected = senderEncryptedAmountValue;
228 auto const actual = rebuiltTx.getSenderEncryptedAmount();
229 expectEqualField(expected, actual, "sfSenderEncryptedAmount");
230 }
231
232 {
233 auto const& expected = destinationEncryptedAmountValue;
234 auto const actual = rebuiltTx.getDestinationEncryptedAmount();
235 expectEqualField(expected, actual, "sfDestinationEncryptedAmount");
236 }
237
238 {
239 auto const& expected = issuerEncryptedAmountValue;
240 auto const actual = rebuiltTx.getIssuerEncryptedAmount();
241 expectEqualField(expected, actual, "sfIssuerEncryptedAmount");
242 }
243
244 {
245 auto const& expected = zKProofValue;
246 auto const actual = rebuiltTx.getZKProof();
247 expectEqualField(expected, actual, "sfZKProof");
248 }
249
250 {
251 auto const& expected = amountCommitmentValue;
252 auto const actual = rebuiltTx.getAmountCommitment();
253 expectEqualField(expected, actual, "sfAmountCommitment");
254 }
255
256 {
257 auto const& expected = balanceCommitmentValue;
258 auto const actual = rebuiltTx.getBalanceCommitment();
259 expectEqualField(expected, actual, "sfBalanceCommitment");
260 }
261
262 // Verify optional fields
263 {
264 auto const& expected = destinationTagValue;
265 auto const actualOpt = rebuiltTx.getDestinationTag();
266 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfDestinationTag should be present";
267 expectEqualField(expected, *actualOpt, "sfDestinationTag");
268 }
269
270 {
271 auto const& expected = auditorEncryptedAmountValue;
272 auto const actualOpt = rebuiltTx.getAuditorEncryptedAmount();
273 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAuditorEncryptedAmount should be present";
274 expectEqualField(expected, *actualOpt, "sfAuditorEncryptedAmount");
275 }
276
277 {
278 auto const& expected = credentialIDsValue;
279 auto const actualOpt = rebuiltTx.getCredentialIDs();
280 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfCredentialIDs should be present";
281 expectEqualField(expected, *actualOpt, "sfCredentialIDs");
282 }
283
284}
285
286// 3) Verify wrapper throws when constructed from wrong transaction type.
287TEST(TransactionsConfidentialMPTSendTests, WrapperThrowsOnWrongTxType)
288{
289 // Build a valid transaction of a different type
290 auto const [pk, sk] =
292 auto const account = calcAccountID(pk);
293
294 AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()};
295 auto wrongTx = wrongBuilder.build(pk, sk);
296
297 EXPECT_THROW(ConfidentialMPTSend{wrongTx.getSTTx()}, std::runtime_error);
298}
299
300// 4) Verify builder throws when constructed from wrong transaction type.
301TEST(TransactionsConfidentialMPTSendTests, BuilderThrowsOnWrongTxType)
302{
303 // Build a valid transaction of a different type
304 auto const [pk, sk] =
305 generateKeyPair(KeyType::Secp256k1, generateSeed("testWrongTypeBuilder"));
306 auto const account = calcAccountID(pk);
307
308 AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()};
309 auto wrongTx = wrongBuilder.build(pk, sk);
310
311 EXPECT_THROW(ConfidentialMPTSendBuilder{wrongTx.getSTTx()}, std::runtime_error);
312}
313
314// 5) Build with only required fields and verify optional fields return nullopt.
315TEST(TransactionsConfidentialMPTSendTests, OptionalFieldsReturnNullopt)
316{
317 // Generate a deterministic keypair for signing
318 auto const [publicKey, secretKey] =
319 generateKeyPair(KeyType::Secp256k1, generateSeed("testConfidentialMPTSendNullopt"));
320
321 // Common transaction fields
322 auto const accountValue = calcAccountID(publicKey);
323 std::uint32_t const sequenceValue = 3;
324 auto const feeValue = canonical_AMOUNT();
325
326 // Transaction-specific required field values
327 auto const mPTokenIssuanceIDValue = canonical_UINT192();
328 auto const destinationValue = canonical_ACCOUNT();
329 auto const senderEncryptedAmountValue = canonical_VL();
330 auto const destinationEncryptedAmountValue = canonical_VL();
331 auto const issuerEncryptedAmountValue = canonical_VL();
332 auto const zKProofValue = canonical_VL();
333 auto const amountCommitmentValue = canonical_VL();
334 auto const balanceCommitmentValue = canonical_VL();
335
337 accountValue,
338 mPTokenIssuanceIDValue,
339 destinationValue,
340 senderEncryptedAmountValue,
341 destinationEncryptedAmountValue,
342 issuerEncryptedAmountValue,
343 zKProofValue,
344 amountCommitmentValue,
345 balanceCommitmentValue,
346 sequenceValue,
347 feeValue
348 };
349
350 // Do NOT set optional fields
351
352 auto tx = builder.build(publicKey, secretKey);
353
354 // Verify optional fields are not present
355 EXPECT_FALSE(tx.hasDestinationTag());
356 EXPECT_FALSE(tx.getDestinationTag().has_value());
357 EXPECT_FALSE(tx.hasAuditorEncryptedAmount());
358 EXPECT_FALSE(tx.getAuditorEncryptedAmount().has_value());
359 EXPECT_FALSE(tx.hasCredentialIDs());
360 EXPECT_FALSE(tx.getCredentialIDs().has_value());
361}
362
363}
AccountSet build(PublicKey const &publicKey, SecretKey const &secretKey)
Build and return the AccountSet wrapper.
ConfidentialMPTSendBuilder & setCredentialIDs(std::decay_t< typename SF_VECTOR256::type::value_type > const &value)
Set sfCredentialIDs (SoeOptional).
ConfidentialMPTSend build(PublicKey const &publicKey, SecretKey const &secretKey)
Build and return the ConfidentialMPTSend wrapper.
ConfidentialMPTSendBuilder & setAuditorEncryptedAmount(std::decay_t< typename SF_VL::type::value_type > const &value)
Set sfAuditorEncryptedAmount (SoeOptional).
ConfidentialMPTSendBuilder & setDestinationTag(std::decay_t< typename SF_UINT32::type::value_type > const &value)
Set sfDestinationTag (SoeOptional).
TEST(TransactionsAccountDeleteTests, BuilderSettersRoundTrip)
Vector256Value canonical_VECTOR256()
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)