xrpld
Loading...
Searching...
No Matches
ConfidentialMPTConvertTests.cpp
1// Auto-generated unit tests for transaction ConfidentialMPTConvert
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/ConfidentialMPTConvert.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(TransactionsConfidentialMPTConvertTests, BuilderSettersRoundTrip)
21{
22 // Generate a deterministic keypair for signing
23 auto const [publicKey, secretKey] =
24 generateKeyPair(KeyType::Secp256k1, generateSeed("testConfidentialMPTConvert"));
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 mPTAmountValue = canonical_UINT64();
34 auto const holderEncryptionKeyValue = canonical_VL();
35 auto const holderEncryptedAmountValue = canonical_VL();
36 auto const issuerEncryptedAmountValue = canonical_VL();
37 auto const auditorEncryptedAmountValue = canonical_VL();
38 auto const blindingFactorValue = canonical_UINT256();
39 auto const zKProofValue = canonical_VL();
40
42 accountValue,
43 mPTokenIssuanceIDValue,
44 mPTAmountValue,
45 holderEncryptedAmountValue,
46 issuerEncryptedAmountValue,
47 blindingFactorValue,
48 sequenceValue,
49 feeValue
50 };
51
52 // Set optional fields
53 builder.setHolderEncryptionKey(holderEncryptionKeyValue);
54 builder.setAuditorEncryptedAmount(auditorEncryptedAmountValue);
55 builder.setZKProof(zKProofValue);
56
57 auto tx = builder.build(publicKey, secretKey);
58
59 std::string reason;
60 EXPECT_TRUE(tx.validate(reason)) << reason;
61
62 // Verify signing was applied
63 EXPECT_FALSE(tx.getSigningPubKey().empty());
64 EXPECT_TRUE(tx.hasTxnSignature());
65
66 // Verify common fields
67 EXPECT_EQ(tx.getAccount(), accountValue);
68 EXPECT_EQ(tx.getSequence(), sequenceValue);
69 EXPECT_EQ(tx.getFee(), feeValue);
70
71 // Verify required fields
72 {
73 auto const& expected = mPTokenIssuanceIDValue;
74 auto const actual = tx.getMPTokenIssuanceID();
75 expectEqualField(expected, actual, "sfMPTokenIssuanceID");
76 }
77
78 {
79 auto const& expected = mPTAmountValue;
80 auto const actual = tx.getMPTAmount();
81 expectEqualField(expected, actual, "sfMPTAmount");
82 }
83
84 {
85 auto const& expected = holderEncryptedAmountValue;
86 auto const actual = tx.getHolderEncryptedAmount();
87 expectEqualField(expected, actual, "sfHolderEncryptedAmount");
88 }
89
90 {
91 auto const& expected = issuerEncryptedAmountValue;
92 auto const actual = tx.getIssuerEncryptedAmount();
93 expectEqualField(expected, actual, "sfIssuerEncryptedAmount");
94 }
95
96 {
97 auto const& expected = blindingFactorValue;
98 auto const actual = tx.getBlindingFactor();
99 expectEqualField(expected, actual, "sfBlindingFactor");
100 }
101
102 // Verify optional fields
103 {
104 auto const& expected = holderEncryptionKeyValue;
105 auto const actualOpt = tx.getHolderEncryptionKey();
106 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfHolderEncryptionKey should be present";
107 expectEqualField(expected, *actualOpt, "sfHolderEncryptionKey");
108 EXPECT_TRUE(tx.hasHolderEncryptionKey());
109 }
110
111 {
112 auto const& expected = auditorEncryptedAmountValue;
113 auto const actualOpt = tx.getAuditorEncryptedAmount();
114 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAuditorEncryptedAmount should be present";
115 expectEqualField(expected, *actualOpt, "sfAuditorEncryptedAmount");
116 EXPECT_TRUE(tx.hasAuditorEncryptedAmount());
117 }
118
119 {
120 auto const& expected = zKProofValue;
121 auto const actualOpt = tx.getZKProof();
122 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfZKProof should be present";
123 expectEqualField(expected, *actualOpt, "sfZKProof");
124 EXPECT_TRUE(tx.hasZKProof());
125 }
126
127}
128
129// 2 & 4) Start from an STTx, construct a builder from it, build a new wrapper,
130// and verify all fields match.
131TEST(TransactionsConfidentialMPTConvertTests, BuilderFromStTxRoundTrip)
132{
133 // Generate a deterministic keypair for signing
134 auto const [publicKey, secretKey] =
135 generateKeyPair(KeyType::Secp256k1, generateSeed("testConfidentialMPTConvertFromTx"));
136
137 // Common transaction fields
138 auto const accountValue = calcAccountID(publicKey);
139 std::uint32_t const sequenceValue = 2;
140 auto const feeValue = canonical_AMOUNT();
141
142 // Transaction-specific field values
143 auto const mPTokenIssuanceIDValue = canonical_UINT192();
144 auto const mPTAmountValue = canonical_UINT64();
145 auto const holderEncryptionKeyValue = canonical_VL();
146 auto const holderEncryptedAmountValue = canonical_VL();
147 auto const issuerEncryptedAmountValue = canonical_VL();
148 auto const auditorEncryptedAmountValue = canonical_VL();
149 auto const blindingFactorValue = canonical_UINT256();
150 auto const zKProofValue = canonical_VL();
151
152 // Build an initial transaction
153 ConfidentialMPTConvertBuilder initialBuilder{
154 accountValue,
155 mPTokenIssuanceIDValue,
156 mPTAmountValue,
157 holderEncryptedAmountValue,
158 issuerEncryptedAmountValue,
159 blindingFactorValue,
160 sequenceValue,
161 feeValue
162 };
163
164 initialBuilder.setHolderEncryptionKey(holderEncryptionKeyValue);
165 initialBuilder.setAuditorEncryptedAmount(auditorEncryptedAmountValue);
166 initialBuilder.setZKProof(zKProofValue);
167
168 auto initialTx = initialBuilder.build(publicKey, secretKey);
169
170 // Create builder from existing STTx
171 ConfidentialMPTConvertBuilder builderFromTx{initialTx.getSTTx()};
172
173 auto rebuiltTx = builderFromTx.build(publicKey, secretKey);
174
175 std::string reason;
176 EXPECT_TRUE(rebuiltTx.validate(reason)) << reason;
177
178 // Verify common fields
179 EXPECT_EQ(rebuiltTx.getAccount(), accountValue);
180 EXPECT_EQ(rebuiltTx.getSequence(), sequenceValue);
181 EXPECT_EQ(rebuiltTx.getFee(), feeValue);
182
183 // Verify required fields
184 {
185 auto const& expected = mPTokenIssuanceIDValue;
186 auto const actual = rebuiltTx.getMPTokenIssuanceID();
187 expectEqualField(expected, actual, "sfMPTokenIssuanceID");
188 }
189
190 {
191 auto const& expected = mPTAmountValue;
192 auto const actual = rebuiltTx.getMPTAmount();
193 expectEqualField(expected, actual, "sfMPTAmount");
194 }
195
196 {
197 auto const& expected = holderEncryptedAmountValue;
198 auto const actual = rebuiltTx.getHolderEncryptedAmount();
199 expectEqualField(expected, actual, "sfHolderEncryptedAmount");
200 }
201
202 {
203 auto const& expected = issuerEncryptedAmountValue;
204 auto const actual = rebuiltTx.getIssuerEncryptedAmount();
205 expectEqualField(expected, actual, "sfIssuerEncryptedAmount");
206 }
207
208 {
209 auto const& expected = blindingFactorValue;
210 auto const actual = rebuiltTx.getBlindingFactor();
211 expectEqualField(expected, actual, "sfBlindingFactor");
212 }
213
214 // Verify optional fields
215 {
216 auto const& expected = holderEncryptionKeyValue;
217 auto const actualOpt = rebuiltTx.getHolderEncryptionKey();
218 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfHolderEncryptionKey should be present";
219 expectEqualField(expected, *actualOpt, "sfHolderEncryptionKey");
220 }
221
222 {
223 auto const& expected = auditorEncryptedAmountValue;
224 auto const actualOpt = rebuiltTx.getAuditorEncryptedAmount();
225 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfAuditorEncryptedAmount should be present";
226 expectEqualField(expected, *actualOpt, "sfAuditorEncryptedAmount");
227 }
228
229 {
230 auto const& expected = zKProofValue;
231 auto const actualOpt = rebuiltTx.getZKProof();
232 ASSERT_TRUE(actualOpt.has_value()) << "Optional field sfZKProof should be present";
233 expectEqualField(expected, *actualOpt, "sfZKProof");
234 }
235
236}
237
238// 3) Verify wrapper throws when constructed from wrong transaction type.
239TEST(TransactionsConfidentialMPTConvertTests, WrapperThrowsOnWrongTxType)
240{
241 // Build a valid transaction of a different type
242 auto const [pk, sk] =
244 auto const account = calcAccountID(pk);
245
246 AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()};
247 auto wrongTx = wrongBuilder.build(pk, sk);
248
249 EXPECT_THROW(ConfidentialMPTConvert{wrongTx.getSTTx()}, std::runtime_error);
250}
251
252// 4) Verify builder throws when constructed from wrong transaction type.
253TEST(TransactionsConfidentialMPTConvertTests, BuilderThrowsOnWrongTxType)
254{
255 // Build a valid transaction of a different type
256 auto const [pk, sk] =
257 generateKeyPair(KeyType::Secp256k1, generateSeed("testWrongTypeBuilder"));
258 auto const account = calcAccountID(pk);
259
260 AccountSetBuilder wrongBuilder{account, 1, canonical_AMOUNT()};
261 auto wrongTx = wrongBuilder.build(pk, sk);
262
263 EXPECT_THROW(ConfidentialMPTConvertBuilder{wrongTx.getSTTx()}, std::runtime_error);
264}
265
266// 5) Build with only required fields and verify optional fields return nullopt.
267TEST(TransactionsConfidentialMPTConvertTests, OptionalFieldsReturnNullopt)
268{
269 // Generate a deterministic keypair for signing
270 auto const [publicKey, secretKey] =
271 generateKeyPair(KeyType::Secp256k1, generateSeed("testConfidentialMPTConvertNullopt"));
272
273 // Common transaction fields
274 auto const accountValue = calcAccountID(publicKey);
275 std::uint32_t const sequenceValue = 3;
276 auto const feeValue = canonical_AMOUNT();
277
278 // Transaction-specific required field values
279 auto const mPTokenIssuanceIDValue = canonical_UINT192();
280 auto const mPTAmountValue = canonical_UINT64();
281 auto const holderEncryptedAmountValue = canonical_VL();
282 auto const issuerEncryptedAmountValue = canonical_VL();
283 auto const blindingFactorValue = canonical_UINT256();
284
286 accountValue,
287 mPTokenIssuanceIDValue,
288 mPTAmountValue,
289 holderEncryptedAmountValue,
290 issuerEncryptedAmountValue,
291 blindingFactorValue,
292 sequenceValue,
293 feeValue
294 };
295
296 // Do NOT set optional fields
297
298 auto tx = builder.build(publicKey, secretKey);
299
300 // Verify optional fields are not present
301 EXPECT_FALSE(tx.hasHolderEncryptionKey());
302 EXPECT_FALSE(tx.getHolderEncryptionKey().has_value());
303 EXPECT_FALSE(tx.hasAuditorEncryptedAmount());
304 EXPECT_FALSE(tx.getAuditorEncryptedAmount().has_value());
305 EXPECT_FALSE(tx.hasZKProof());
306 EXPECT_FALSE(tx.getZKProof().has_value());
307}
308
309}
AccountSet build(PublicKey const &publicKey, SecretKey const &secretKey)
Build and return the AccountSet wrapper.
ConfidentialMPTConvertBuilder & setZKProof(std::decay_t< typename SF_VL::type::value_type > const &value)
Set sfZKProof (SoeOptional).
ConfidentialMPTConvertBuilder & setAuditorEncryptedAmount(std::decay_t< typename SF_VL::type::value_type > const &value)
Set sfAuditorEncryptedAmount (SoeOptional).
ConfidentialMPTConvertBuilder & setHolderEncryptionKey(std::decay_t< typename SF_VL::type::value_type > const &value)
Set sfHolderEncryptionKey (SoeOptional).
ConfidentialMPTConvert build(PublicKey const &publicKey, SecretKey const &secretKey)
Build and return the ConfidentialMPTConvert wrapper.
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)