rippled
Loading...
Searching...
No Matches
xchain_bridge.cpp
1#include <test/jtx/Env.h>
2#include <test/jtx/attester.h>
3#include <test/jtx/xchain_bridge.h>
4
5#include <xrpl/json/json_value.h>
6#include <xrpl/protocol/Issue.h>
7#include <xrpl/protocol/SField.h>
8#include <xrpl/protocol/STBase.h>
9#include <xrpl/protocol/STInteger.h>
10#include <xrpl/protocol/STObject.h>
11#include <xrpl/protocol/TxFlags.h>
12#include <xrpl/protocol/XChainAttestations.h>
13#include <xrpl/protocol/jss.h>
14
15namespace ripple {
16namespace test {
17namespace jtx {
18
19// use this for creating a bridge for a transaction
22 Account const& lockingChainDoor,
23 Issue const& lockingChainIssue,
24 Account const& issuingChainDoor,
25 Issue const& issuingChainIssue)
26{
27 Json::Value jv;
28 jv[jss::LockingChainDoor] = lockingChainDoor.human();
29 jv[jss::LockingChainIssue] = to_json(lockingChainIssue);
30 jv[jss::IssuingChainDoor] = issuingChainDoor.human();
31 jv[jss::IssuingChainIssue] = to_json(issuingChainIssue);
32 return jv;
33}
34
35// use this for creating a bridge for a rpc query
38 Account const& lockingChainDoor,
39 Issue const& lockingChainIssue,
40 Account const& issuingChainDoor,
41 Issue const& issuingChainIssue)
42{
43 Json::Value jv;
44 jv[jss::LockingChainDoor] = lockingChainDoor.human();
45 jv[jss::LockingChainIssue] = to_json(lockingChainIssue);
46 jv[jss::IssuingChainDoor] = issuingChainDoor.human();
47 jv[jss::IssuingChainIssue] = to_json(issuingChainIssue);
48 return jv;
49}
50
53 Account const& acc,
54 Json::Value const& bridge,
55 STAmount const& reward,
56 std::optional<STAmount> const& minAccountCreate)
57{
58 Json::Value jv;
59
60 jv[jss::Account] = acc.human();
61 jv[sfXChainBridge.getJsonName()] = bridge;
62 jv[sfSignatureReward.getJsonName()] = reward.getJson(JsonOptions::none);
63 if (minAccountCreate)
64 jv[sfMinAccountCreateAmount.getJsonName()] =
65 minAccountCreate->getJson(JsonOptions::none);
66
67 jv[jss::TransactionType] = jss::XChainCreateBridge;
68 return jv;
69}
70
73 Account const& acc,
74 Json::Value const& bridge,
75 std::optional<STAmount> const& reward,
76 std::optional<STAmount> const& minAccountCreate)
77{
78 Json::Value jv;
79
80 jv[jss::Account] = acc.human();
81 jv[sfXChainBridge.getJsonName()] = bridge;
82 if (reward)
83 jv[sfSignatureReward.getJsonName()] =
84 reward->getJson(JsonOptions::none);
85 if (minAccountCreate)
86 jv[sfMinAccountCreateAmount.getJsonName()] =
87 minAccountCreate->getJson(JsonOptions::none);
88
89 jv[jss::TransactionType] = jss::XChainModifyBridge;
90 return jv;
91}
92
95 Account const& acc,
96 Json::Value const& bridge,
97 STAmount const& reward,
98 Account const& otherChainSource)
99{
100 Json::Value jv;
101
102 jv[jss::Account] = acc.human();
103 jv[sfXChainBridge.getJsonName()] = bridge;
104 jv[sfSignatureReward.getJsonName()] = reward.getJson(JsonOptions::none);
105 jv[sfOtherChainSource.getJsonName()] = otherChainSource.human();
106
107 jv[jss::TransactionType] = jss::XChainCreateClaimID;
108 return jv;
109}
110
113 Account const& acc,
114 Json::Value const& bridge,
115 std::uint32_t claimID,
116 AnyAmount const& amt,
117 std::optional<Account> const& dst)
118{
119 Json::Value jv;
120
121 jv[jss::Account] = acc.human();
122 jv[sfXChainBridge.getJsonName()] = bridge;
123 jv[sfXChainClaimID.getJsonName()] = claimID;
124 jv[jss::Amount] = amt.value.getJson(JsonOptions::none);
125 if (dst)
126 jv[sfOtherChainDestination.getJsonName()] = dst->human();
127
128 jv[jss::TransactionType] = jss::XChainCommit;
129 return jv;
130}
131
134 Account const& acc,
135 Json::Value const& bridge,
136 std::uint32_t claimID,
137 AnyAmount const& amt,
138 Account const& dst)
139{
140 Json::Value jv;
141
142 jv[sfAccount.getJsonName()] = acc.human();
143 jv[sfXChainBridge.getJsonName()] = bridge;
144 jv[sfXChainClaimID.getJsonName()] = claimID;
145 jv[sfDestination.getJsonName()] = dst.human();
146 jv[sfAmount.getJsonName()] = amt.value.getJson(JsonOptions::none);
147
148 jv[jss::TransactionType] = jss::XChainClaim;
149 return jv;
150}
151
154 Account const& acc,
155 Json::Value const& bridge,
156 Account const& dst,
157 AnyAmount const& amt,
158 AnyAmount const& reward)
159{
160 Json::Value jv;
161
162 jv[sfAccount.getJsonName()] = acc.human();
163 jv[sfXChainBridge.getJsonName()] = bridge;
164 jv[sfDestination.getJsonName()] = dst.human();
165 jv[sfAmount.getJsonName()] = amt.value.getJson(JsonOptions::none);
166 jv[sfSignatureReward.getJsonName()] =
168
169 jv[jss::TransactionType] = jss::XChainAccountCreateCommit;
170 return jv;
171}
172
175 jtx::Account const& submittingAccount,
176 Json::Value const& jvBridge,
177 jtx::Account const& sendingAccount,
178 jtx::AnyAmount const& sendingAmount,
179 jtx::Account const& rewardAccount,
180 bool wasLockingChainSend,
181 std::uint64_t claimID,
183 jtx::signer const& signer)
184{
185 STXChainBridge const stBridge(jvBridge);
186
187 auto const& pk = signer.account.pk();
188 auto const& sk = signer.account.sk();
189 auto const sig = sign_claim_attestation(
190 pk,
191 sk,
192 stBridge,
193 sendingAccount,
194 sendingAmount.value,
195 rewardAccount,
196 wasLockingChainSend,
197 claimID,
198 dst);
199
200 Json::Value result;
201
202 result[sfAccount.getJsonName()] = submittingAccount.human();
203 result[sfXChainBridge.getJsonName()] = jvBridge;
204
205 result[sfAttestationSignerAccount.getJsonName()] = signer.account.human();
206 result[sfPublicKey.getJsonName()] = strHex(pk.slice());
207 result[sfSignature.getJsonName()] = strHex(sig);
208 result[sfOtherChainSource.getJsonName()] = toBase58(sendingAccount);
209 result[sfAmount.getJsonName()] =
210 sendingAmount.value.getJson(JsonOptions::none);
211 result[sfAttestationRewardAccount.getJsonName()] = toBase58(rewardAccount);
212 result[sfWasLockingChainSend.getJsonName()] = wasLockingChainSend ? 1 : 0;
213
214 result[sfXChainClaimID.getJsonName()] =
215 STUInt64{claimID}.getJson(JsonOptions::none);
216 if (dst)
217 result[sfDestination.getJsonName()] = toBase58(*dst);
218
219 result[jss::TransactionType] = jss::XChainAddClaimAttestation;
220
221 return result;
222}
223
226 jtx::Account const& submittingAccount,
227 Json::Value const& jvBridge,
228 jtx::Account const& sendingAccount,
229 jtx::AnyAmount const& sendingAmount,
230 jtx::AnyAmount const& rewardAmount,
231 jtx::Account const& rewardAccount,
232 bool wasLockingChainSend,
233 std::uint64_t createCount,
234 jtx::Account const& dst,
235 jtx::signer const& signer)
236{
237 STXChainBridge const stBridge(jvBridge);
238
239 auto const& pk = signer.account.pk();
240 auto const& sk = signer.account.sk();
242 pk,
243 sk,
244 stBridge,
245 sendingAccount,
246 sendingAmount.value,
247 rewardAmount.value,
248 rewardAccount,
249 wasLockingChainSend,
250 createCount,
251 dst);
252
253 Json::Value result;
254
255 result[sfAccount.getJsonName()] = submittingAccount.human();
256 result[sfXChainBridge.getJsonName()] = jvBridge;
257
258 result[sfAttestationSignerAccount.getJsonName()] = signer.account.human();
259 result[sfPublicKey.getJsonName()] = strHex(pk.slice());
260 result[sfSignature.getJsonName()] = strHex(sig);
261 result[sfOtherChainSource.getJsonName()] = toBase58(sendingAccount);
262 result[sfAmount.getJsonName()] =
263 sendingAmount.value.getJson(JsonOptions::none);
264 result[sfAttestationRewardAccount.getJsonName()] = toBase58(rewardAccount);
265 result[sfWasLockingChainSend.getJsonName()] = wasLockingChainSend ? 1 : 0;
266
267 result[sfXChainAccountCreateCount.getJsonName()] =
268 STUInt64{createCount}.getJson(JsonOptions::none);
269 result[sfDestination.getJsonName()] = toBase58(dst);
270 result[sfSignatureReward.getJsonName()] =
271 rewardAmount.value.getJson(JsonOptions::none);
272
273 result[jss::TransactionType] = jss::XChainAddAccountCreateAttestation;
274
275 return result;
276}
277
280 jtx::Account const& submittingAccount,
281 Json::Value const& jvBridge,
282 jtx::Account const& sendingAccount,
283 jtx::AnyAmount const& sendingAmount,
284 std::vector<jtx::Account> const& rewardAccounts,
285 bool wasLockingChainSend,
286 std::uint64_t claimID,
289 std::size_t const numAtts,
290 std::size_t const fromIdx)
291{
292 assert(fromIdx + numAtts <= rewardAccounts.size());
293 assert(fromIdx + numAtts <= signers.size());
294 JValueVec vec;
295 vec.reserve(numAtts);
296 for (auto i = fromIdx; i < fromIdx + numAtts; ++i)
298 submittingAccount,
299 jvBridge,
300 sendingAccount,
301 sendingAmount,
302 rewardAccounts[i],
303 wasLockingChainSend,
304 claimID,
305 dst,
306 signers[i]));
307 return vec;
308}
309
312 jtx::Account const& submittingAccount,
313 Json::Value const& jvBridge,
314 jtx::Account const& sendingAccount,
315 jtx::AnyAmount const& sendingAmount,
316 jtx::AnyAmount const& rewardAmount,
317 std::vector<jtx::Account> const& rewardAccounts,
318 bool wasLockingChainSend,
319 std::uint64_t createCount,
320 jtx::Account const& dst,
322 std::size_t const numAtts,
323 std::size_t const fromIdx)
324{
325 assert(fromIdx + numAtts <= rewardAccounts.size());
326 assert(fromIdx + numAtts <= signers.size());
327 JValueVec vec;
328 vec.reserve(numAtts);
329 for (auto i = fromIdx; i < fromIdx + numAtts; ++i)
331 submittingAccount,
332 jvBridge,
333 sendingAccount,
334 sendingAmount,
335 rewardAmount,
336 rewardAccounts[i],
337 wasLockingChainSend,
338 createCount,
339 dst,
340 signers[i]));
341 return vec;
342}
343
345 : mcDoor("mcDoor")
346 , mcAlice("mcAlice")
347 , mcBob("mcBob")
348 , mcCarol("mcCarol")
349 , mcGw("mcGw")
350 , scDoor("scDoor")
351 , scAlice("scAlice")
352 , scBob("scBob")
353 , scCarol("scCarol")
354 , scGw("scGw")
355 , scAttester("scAttester")
356 , scReward("scReward")
357 , mcuDoor("mcuDoor")
358 , mcuAlice("mcuAlice")
359 , mcuBob("mcuBob")
360 , mcuCarol("mcuCarol")
361 , mcuGw("mcuGw")
362 , scuDoor("scuDoor")
363 , scuAlice("scuAlice")
364 , scuBob("scuBob")
365 , scuCarol("scuCarol")
366 , scuGw("scuGw")
367 , mcUSD(mcGw["USD"])
368 , scUSD(scGw["USD"])
369 , jvXRPBridgeRPC(
370 bridge_rpc(mcDoor, xrpIssue(), Account::master, xrpIssue()))
371 , jvb(bridge(mcDoor, xrpIssue(), Account::master, xrpIssue()))
372 , jvub(bridge(mcuDoor, xrpIssue(), Account::master, xrpIssue()))
373 , features(testable_amendments() | FeatureBitset{featureXChainBridge})
374 , signers([] {
375 constexpr int numSigners = UT_XCHAIN_DEFAULT_NUM_SIGNERS;
376 std::vector<signer> result;
377 result.reserve(numSigners);
378 for (int i = 0; i < numSigners; ++i)
379 {
380 using namespace std::literals;
381 auto const a = Account(
382 "signer_"s + std::to_string(i),
384 result.emplace_back(a);
385 }
386 return result;
387 }())
388 , alt_signers([] {
389 constexpr int numSigners = UT_XCHAIN_DEFAULT_NUM_SIGNERS;
390 std::vector<signer> result;
391 result.reserve(numSigners);
392 for (int i = 0; i < numSigners; ++i)
393 {
394 using namespace std::literals;
395 auto const a = Account(
396 "alt_signer_"s + std::to_string(i),
397 (i % 2) ? KeyType::ed25519 : KeyType::secp256k1);
398 result.emplace_back(a);
399 }
400 return result;
401 }())
402 , payee([&] {
404 r.reserve(signers.size());
405 for (int i = 0, e = signers.size(); i != e; ++i)
406 {
407 r.push_back(scReward);
408 }
409 return r;
410 }())
411 , payees([&] {
413 r.reserve(signers.size());
414 for (int i = 0, e = signers.size(); i != e; ++i)
415 {
416 using namespace std::literals;
417 auto const a = Account("reward_"s + std::to_string(i));
418 r.push_back(a);
419 }
420 return r;
421 }())
423 , reward(XRP(1))
424 , split_reward_quorum(
425 divide(reward, STAmount(UT_XCHAIN_DEFAULT_QUORUM), reward.issue()))
426 , split_reward_everyone(divide(
427 reward,
429 reward.issue()))
430 , tiny_reward(drops(37))
431 , tiny_reward_split((divide(
432 tiny_reward,
433 STAmount(UT_XCHAIN_DEFAULT_QUORUM),
434 tiny_reward.issue())))
435 , tiny_reward_remainder(
436 tiny_reward -
437 multiply(
438 tiny_reward_split,
439 STAmount(UT_XCHAIN_DEFAULT_QUORUM),
440 tiny_reward.issue()))
441 , one_xrp(XRP(1))
442 , xrp_dust(divide(one_xrp, STAmount(10000), one_xrp.issue()))
443{
444}
445
446void
448{
449 STAmount xrp_funds{XRP(10000)};
450 mcEnv.fund(xrp_funds, mcDoor, mcAlice, mcBob, mcCarol, mcGw);
451
452 // Signer's list must match the attestation signers
453 mcEnv(jtx::signers(mcDoor, signers.size(), signers));
454
455 // create XRP bridges in both direction
456 auto const reward = XRP(1);
457 STAmount const minCreate = XRP(20);
458
459 mcEnv(bridge_create(mcDoor, jvb, reward, minCreate));
460 mcEnv.close();
461}
462
463void
465{
466 STAmount xrp_funds{XRP(10000)};
467 scEnv.fund(
469
470 // Signer's list must match the attestation signers
472
473 // create XRP bridges in both direction
474 auto const reward = XRP(1);
475 STAmount const minCreate = XRP(20);
476
477 scEnv(bridge_create(Account::master, jvb, reward, minCreate));
478 scEnv.close();
479}
480
481void
487} // namespace jtx
488} // namespace test
489} // namespace ripple
Represents a JSON value.
Definition json_value.h:130
UInt size() const
Number of values in array or object.
A currency issued by an account.
Definition Issue.h:14
Json::Value getJson(JsonOptions=JsonOptions::none) const override
Definition STAmount.cpp:753
Immutable cryptographic account descriptor.
Definition Account.h:20
PublicKey const & pk() const
Return the public key.
Definition Account.h:75
static Account const master
The master account.
Definition Account.h:29
SecretKey const & sk() const
Return the secret key.
Definition Account.h:82
std::string const & human() const
Returns the human readable public key.
Definition Account.h:99
A transaction testing environment.
Definition Env.h:102
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition Env.cpp:103
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition Env.cpp:271
Set the regular signature on a JTx.
Definition sig.h:16
T emplace_back(T... args)
constexpr std::size_t UT_XCHAIN_DEFAULT_QUORUM
Json::Value create_account_attestation(jtx::Account const &submittingAccount, Json::Value const &jvBridge, jtx::Account const &sendingAccount, jtx::AnyAmount const &sendingAmount, jtx::AnyAmount const &rewardAmount, jtx::Account const &rewardAccount, bool wasLockingChainSend, std::uint64_t createCount, jtx::Account const &dst, jtx::signer const &signer)
JValueVec claim_attestations(jtx::Account const &submittingAccount, Json::Value const &jvBridge, jtx::Account const &sendingAccount, jtx::AnyAmount const &sendingAmount, std::vector< jtx::Account > const &rewardAccounts, bool wasLockingChainSend, std::uint64_t claimID, std::optional< jtx::Account > const &dst, std::vector< jtx::signer > const &signers, std::size_t const numAtts, std::size_t const fromIdx)
Json::Value bridge_create(Account const &acc, Json::Value const &bridge, STAmount const &reward, std::optional< STAmount > const &minAccountCreate)
Json::Value claim_attestation(jtx::Account const &submittingAccount, Json::Value const &jvBridge, jtx::Account const &sendingAccount, jtx::AnyAmount const &sendingAmount, jtx::Account const &rewardAccount, bool wasLockingChainSend, std::uint64_t claimID, std::optional< jtx::Account > const &dst, jtx::signer const &signer)
Json::Value bridge(Account const &lockingChainDoor, Issue const &lockingChainIssue, Account const &issuingChainDoor, Issue const &issuingChainIssue)
Json::Value signers(Account const &account, std::uint32_t quorum, std::vector< signer > const &v)
Definition multisign.cpp:15
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Json::Value sidechain_xchain_account_create(Account const &acc, Json::Value const &bridge, Account const &dst, AnyAmount const &amt, AnyAmount const &reward)
Json::Value xchain_claim(Account const &acc, Json::Value const &bridge, std::uint32_t claimID, AnyAmount const &amt, Account const &dst)
constexpr std::size_t UT_XCHAIN_DEFAULT_NUM_SIGNERS
JValueVec create_account_attestations(jtx::Account const &submittingAccount, Json::Value const &jvBridge, jtx::Account const &sendingAccount, jtx::AnyAmount const &sendingAmount, jtx::AnyAmount const &rewardAmount, std::vector< jtx::Account > const &rewardAccounts, bool wasLockingChainSend, std::uint64_t createCount, jtx::Account const &dst, std::vector< jtx::signer > const &signers, std::size_t const numAtts, std::size_t const fromIdx)
FeatureBitset testable_amendments()
Definition Env.h:55
Json::Value xchain_create_claim_id(Account const &acc, Json::Value const &bridge, STAmount const &reward, Account const &otherChainSource)
Json::Value bridge_modify(Account const &acc, Json::Value const &bridge, std::optional< STAmount > const &reward, std::optional< STAmount > const &minAccountCreate)
Buffer sign_claim_attestation(PublicKey const &pk, SecretKey const &sk, STXChainBridge const &bridge, AccountID const &sendingAccount, STAmount const &sendingAmount, AccountID const &rewardAccount, bool wasLockingChainSend, std::uint64_t claimID, std::optional< AccountID > const &dst)
Definition attester.cpp:13
Json::Value xchain_commit(Account const &acc, Json::Value const &bridge, std::uint32_t claimID, AnyAmount const &amt, std::optional< Account > const &dst)
Buffer sign_create_account_attestation(PublicKey const &pk, SecretKey const &sk, STXChainBridge const &bridge, AccountID const &sendingAccount, STAmount const &sendingAmount, STAmount const &rewardAmount, AccountID const &rewardAccount, bool wasLockingChainSend, std::uint64_t createCount, AccountID const &dst)
Definition attester.cpp:36
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:92
Json::Value bridge_rpc(Account const &lockingChainDoor, Issue const &lockingChainIssue, Account const &issuingChainDoor, Issue const &issuingChainIssue)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition Issue.h:96
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition AccountID.cpp:95
STAmount divide(STAmount const &amount, Rate const &rate)
Definition Rate2.cpp:74
STAmount multiply(STAmount const &amount, Rate const &rate)
Definition Rate2.cpp:34
Json::Value to_json(Asset const &asset)
Definition Asset.h:104
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:11
KeyType
Definition KeyType.h:9
T push_back(T... args)
T reserve(T... args)
Amount specifier with an option for any issuer.
std::vector< signer > const signers
void createBridgeObjects(Env &mcEnv, Env &scEnv)
A signer in a SignerList.
Definition multisign.h:20
T to_string(T... args)