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 xrpl {
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()] = minAccountCreate->getJson(JsonOptions::none);
65
66 jv[jss::TransactionType] = jss::XChainCreateBridge;
67 return jv;
68}
69
72 Account const& acc,
73 Json::Value const& bridge,
74 std::optional<STAmount> const& reward,
75 std::optional<STAmount> const& minAccountCreate)
76{
77 Json::Value jv;
78
79 jv[jss::Account] = acc.human();
80 jv[sfXChainBridge.getJsonName()] = bridge;
81 if (reward)
82 jv[sfSignatureReward.getJsonName()] = reward->getJson(JsonOptions::none);
83 if (minAccountCreate)
84 jv[sfMinAccountCreateAmount.getJsonName()] = minAccountCreate->getJson(JsonOptions::none);
85
86 jv[jss::TransactionType] = jss::XChainModifyBridge;
87 return jv;
88}
89
92 Account const& acc,
93 Json::Value const& bridge,
94 STAmount const& reward,
95 Account const& otherChainSource)
96{
97 Json::Value jv;
98
99 jv[jss::Account] = acc.human();
100 jv[sfXChainBridge.getJsonName()] = bridge;
101 jv[sfSignatureReward.getJsonName()] = reward.getJson(JsonOptions::none);
102 jv[sfOtherChainSource.getJsonName()] = otherChainSource.human();
103
104 jv[jss::TransactionType] = jss::XChainCreateClaimID;
105 return jv;
106}
107
110 Account const& acc,
111 Json::Value const& bridge,
112 std::uint32_t claimID,
113 AnyAmount const& amt,
114 std::optional<Account> const& dst)
115{
116 Json::Value jv;
117
118 jv[jss::Account] = acc.human();
119 jv[sfXChainBridge.getJsonName()] = bridge;
120 jv[sfXChainClaimID.getJsonName()] = claimID;
121 jv[jss::Amount] = amt.value.getJson(JsonOptions::none);
122 if (dst)
123 jv[sfOtherChainDestination.getJsonName()] = dst->human();
124
125 jv[jss::TransactionType] = jss::XChainCommit;
126 return jv;
127}
128
131 Account const& acc,
132 Json::Value const& bridge,
133 std::uint32_t claimID,
134 AnyAmount const& amt,
135 Account const& dst)
136{
137 Json::Value jv;
138
139 jv[sfAccount.getJsonName()] = acc.human();
140 jv[sfXChainBridge.getJsonName()] = bridge;
141 jv[sfXChainClaimID.getJsonName()] = claimID;
142 jv[sfDestination.getJsonName()] = dst.human();
143 jv[sfAmount.getJsonName()] = amt.value.getJson(JsonOptions::none);
144
145 jv[jss::TransactionType] = jss::XChainClaim;
146 return jv;
147}
148
151 Account const& acc,
152 Json::Value const& bridge,
153 Account const& dst,
154 AnyAmount const& amt,
155 AnyAmount const& reward)
156{
157 Json::Value jv;
158
159 jv[sfAccount.getJsonName()] = acc.human();
160 jv[sfXChainBridge.getJsonName()] = bridge;
161 jv[sfDestination.getJsonName()] = dst.human();
162 jv[sfAmount.getJsonName()] = amt.value.getJson(JsonOptions::none);
163 jv[sfSignatureReward.getJsonName()] = reward.value.getJson(JsonOptions::none);
164
165 jv[jss::TransactionType] = jss::XChainAccountCreateCommit;
166 return jv;
167}
168
171 jtx::Account const& submittingAccount,
172 Json::Value const& jvBridge,
173 jtx::Account const& sendingAccount,
174 jtx::AnyAmount const& sendingAmount,
175 jtx::Account const& rewardAccount,
176 bool wasLockingChainSend,
177 std::uint64_t claimID,
179 jtx::signer const& signer)
180{
181 STXChainBridge const stBridge(jvBridge);
182
183 auto const& pk = signer.account.pk();
184 auto const& sk = signer.account.sk();
185 auto const sig = sign_claim_attestation(
186 pk,
187 sk,
188 stBridge,
189 sendingAccount,
190 sendingAmount.value,
191 rewardAccount,
192 wasLockingChainSend,
193 claimID,
194 dst);
195
196 Json::Value result;
197
198 result[sfAccount.getJsonName()] = submittingAccount.human();
199 result[sfXChainBridge.getJsonName()] = jvBridge;
200
201 result[sfAttestationSignerAccount.getJsonName()] = signer.account.human();
202 result[sfPublicKey.getJsonName()] = strHex(pk.slice());
203 result[sfSignature.getJsonName()] = strHex(sig);
204 result[sfOtherChainSource.getJsonName()] = toBase58(sendingAccount);
205 result[sfAmount.getJsonName()] = sendingAmount.value.getJson(JsonOptions::none);
206 result[sfAttestationRewardAccount.getJsonName()] = toBase58(rewardAccount);
207 result[sfWasLockingChainSend.getJsonName()] = wasLockingChainSend ? 1 : 0;
208
209 result[sfXChainClaimID.getJsonName()] = STUInt64{claimID}.getJson(JsonOptions::none);
210 if (dst)
211 result[sfDestination.getJsonName()] = toBase58(*dst);
212
213 result[jss::TransactionType] = jss::XChainAddClaimAttestation;
214
215 return result;
216}
217
220 jtx::Account const& submittingAccount,
221 Json::Value const& jvBridge,
222 jtx::Account const& sendingAccount,
223 jtx::AnyAmount const& sendingAmount,
224 jtx::AnyAmount const& rewardAmount,
225 jtx::Account const& rewardAccount,
226 bool wasLockingChainSend,
227 std::uint64_t createCount,
228 jtx::Account const& dst,
229 jtx::signer const& signer)
230{
231 STXChainBridge const stBridge(jvBridge);
232
233 auto const& pk = signer.account.pk();
234 auto const& sk = signer.account.sk();
236 pk,
237 sk,
238 stBridge,
239 sendingAccount,
240 sendingAmount.value,
241 rewardAmount.value,
242 rewardAccount,
243 wasLockingChainSend,
244 createCount,
245 dst);
246
247 Json::Value result;
248
249 result[sfAccount.getJsonName()] = submittingAccount.human();
250 result[sfXChainBridge.getJsonName()] = jvBridge;
251
252 result[sfAttestationSignerAccount.getJsonName()] = signer.account.human();
253 result[sfPublicKey.getJsonName()] = strHex(pk.slice());
254 result[sfSignature.getJsonName()] = strHex(sig);
255 result[sfOtherChainSource.getJsonName()] = toBase58(sendingAccount);
256 result[sfAmount.getJsonName()] = sendingAmount.value.getJson(JsonOptions::none);
257 result[sfAttestationRewardAccount.getJsonName()] = toBase58(rewardAccount);
258 result[sfWasLockingChainSend.getJsonName()] = wasLockingChainSend ? 1 : 0;
259
260 result[sfXChainAccountCreateCount.getJsonName()] =
261 STUInt64{createCount}.getJson(JsonOptions::none);
262 result[sfDestination.getJsonName()] = toBase58(dst);
263 result[sfSignatureReward.getJsonName()] = rewardAmount.value.getJson(JsonOptions::none);
264
265 result[jss::TransactionType] = jss::XChainAddAccountCreateAttestation;
266
267 return result;
268}
269
272 jtx::Account const& submittingAccount,
273 Json::Value const& jvBridge,
274 jtx::Account const& sendingAccount,
275 jtx::AnyAmount const& sendingAmount,
276 std::vector<jtx::Account> const& rewardAccounts,
277 bool wasLockingChainSend,
278 std::uint64_t claimID,
281 std::size_t const numAtts,
282 std::size_t const fromIdx)
283{
284 assert(fromIdx + numAtts <= rewardAccounts.size());
285 assert(fromIdx + numAtts <= signers.size());
286 JValueVec vec;
287 vec.reserve(numAtts);
288 for (auto i = fromIdx; i < fromIdx + numAtts; ++i)
289 {
291 submittingAccount,
292 jvBridge,
293 sendingAccount,
294 sendingAmount,
295 rewardAccounts[i],
296 wasLockingChainSend,
297 claimID,
298 dst,
299 signers[i]));
300 }
301 return vec;
302}
303
306 jtx::Account const& submittingAccount,
307 Json::Value const& jvBridge,
308 jtx::Account const& sendingAccount,
309 jtx::AnyAmount const& sendingAmount,
310 jtx::AnyAmount const& rewardAmount,
311 std::vector<jtx::Account> const& rewardAccounts,
312 bool wasLockingChainSend,
313 std::uint64_t createCount,
314 jtx::Account const& dst,
316 std::size_t const numAtts,
317 std::size_t const fromIdx)
318{
319 assert(fromIdx + numAtts <= rewardAccounts.size());
320 assert(fromIdx + numAtts <= signers.size());
321 JValueVec vec;
322 vec.reserve(numAtts);
323 for (auto i = fromIdx; i < fromIdx + numAtts; ++i)
324 {
326 submittingAccount,
327 jvBridge,
328 sendingAccount,
329 sendingAmount,
330 rewardAmount,
331 rewardAccounts[i],
332 wasLockingChainSend,
333 createCount,
334 dst,
335 signers[i]));
336 }
337 return vec;
338}
339
341 : mcDoor("mcDoor")
342 , mcAlice("mcAlice")
343 , mcBob("mcBob")
344 , mcCarol("mcCarol")
345 , mcGw("mcGw")
346 , scDoor("scDoor")
347 , scAlice("scAlice")
348 , scBob("scBob")
349 , scCarol("scCarol")
350 , scGw("scGw")
351 , scAttester("scAttester")
352 , scReward("scReward")
353 , mcuDoor("mcuDoor")
354 , mcuAlice("mcuAlice")
355 , mcuBob("mcuBob")
356 , mcuCarol("mcuCarol")
357 , mcuGw("mcuGw")
358 , scuDoor("scuDoor")
359 , scuAlice("scuAlice")
360 , scuBob("scuBob")
361 , scuCarol("scuCarol")
362 , scuGw("scuGw")
363 , mcUSD(mcGw["USD"])
364 , scUSD(scGw["USD"])
365 , jvXRPBridgeRPC(bridge_rpc(mcDoor, xrpIssue(), Account::master, xrpIssue()))
366 , jvb(bridge(mcDoor, xrpIssue(), Account::master, xrpIssue()))
367 , jvub(bridge(mcuDoor, xrpIssue(), Account::master, xrpIssue()))
368 , features(testable_amendments() | FeatureBitset{featureXChainBridge})
369 , signers([] {
370 constexpr int numSigners = UT_XCHAIN_DEFAULT_NUM_SIGNERS;
371 std::vector<signer> result;
372 result.reserve(numSigners);
373 for (int i = 0; i < numSigners; ++i)
374 {
375 using namespace std::literals;
376 auto const a = Account(
377 "signer_"s + std::to_string(i), (i % 2) ? KeyType::ed25519 : KeyType::secp256k1);
378 result.emplace_back(a);
379 }
380 return result;
381 }())
382 , alt_signers([] {
383 constexpr int numSigners = UT_XCHAIN_DEFAULT_NUM_SIGNERS;
384 std::vector<signer> result;
385 result.reserve(numSigners);
386 for (int i = 0; i < numSigners; ++i)
387 {
388 using namespace std::literals;
389 auto const a = Account(
390 "alt_signer_"s + std::to_string(i),
391 (i % 2) ? KeyType::ed25519 : KeyType::secp256k1);
392 result.emplace_back(a);
393 }
394 return result;
395 }())
396 , payee([&] {
398 r.reserve(signers.size());
399 for (int i = 0, e = signers.size(); i != e; ++i)
400 {
401 r.push_back(scReward);
402 }
403 return r;
404 }())
405 , payees([&] {
407 r.reserve(signers.size());
408 for (int i = 0, e = signers.size(); i != e; ++i)
409 {
410 using namespace std::literals;
411 auto const a = Account("reward_"s + std::to_string(i));
412 r.push_back(a);
413 }
414 return r;
415 }())
416 , reward(XRP(1))
417 , split_reward_quorum(divide(reward, STAmount(UT_XCHAIN_DEFAULT_QUORUM), reward.issue()))
418 , split_reward_everyone(divide(reward, STAmount(UT_XCHAIN_DEFAULT_NUM_SIGNERS), reward.issue()))
419 , tiny_reward(drops(37))
420 , tiny_reward_split(
421 (divide(tiny_reward, STAmount(UT_XCHAIN_DEFAULT_QUORUM), tiny_reward.issue())))
422 , tiny_reward_remainder(
423 tiny_reward -
424 multiply(tiny_reward_split, STAmount(UT_XCHAIN_DEFAULT_QUORUM), tiny_reward.issue()))
425 , one_xrp(XRP(1))
426 , xrp_dust(divide(one_xrp, STAmount(10000), one_xrp.issue()))
427{
428}
429
430void
432{
433 STAmount const xrp_funds{XRP(10000)};
434 mcEnv.fund(xrp_funds, mcDoor, mcAlice, mcBob, mcCarol, mcGw);
435
436 // Signer's list must match the attestation signers
437 mcEnv(jtx::signers(mcDoor, signers.size(), signers));
438
439 // create XRP bridges in both direction
440 auto const reward = XRP(1);
441 STAmount const minCreate = XRP(20);
442
443 mcEnv(bridge_create(mcDoor, jvb, reward, minCreate));
444 mcEnv.close();
445}
446
447void
449{
450 STAmount const xrp_funds{XRP(10000)};
451 scEnv.fund(xrp_funds, scDoor, scAlice, scBob, scCarol, scGw, scAttester, scReward);
452
453 // Signer's list must match the attestation signers
455
456 // create XRP bridges in both direction
457 auto const reward = XRP(1);
458 STAmount const minCreate = XRP(20);
459
460 scEnv(bridge_create(Account::master, jvb, reward, minCreate));
461 scEnv.close();
462}
463
464void
470} // namespace jtx
471} // namespace test
472} // namespace xrpl
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:13
Json::Value getJson(JsonOptions=JsonOptions::none) const override
Definition STAmount.cpp:744
Immutable cryptographic account descriptor.
Definition Account.h:19
SecretKey const & sk() const
Return the secret key.
Definition Account.h:77
std::string const & human() const
Returns the human readable public key.
Definition Account.h:94
PublicKey const & pk() const
Return the public key.
Definition Account.h:70
static Account const master
The master account.
Definition Account.h:28
A transaction testing environment.
Definition Env.h:122
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition Env.cpp:100
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition Env.cpp:270
Set the regular signature on a JTx.
Definition sig.h:15
T emplace_back(T... args)
Json::Value sidechain_xchain_account_create(Account const &acc, Json::Value const &bridge, Account const &dst, AnyAmount const &amt, AnyAmount const &reward)
constexpr std::size_t UT_XCHAIN_DEFAULT_NUM_SIGNERS
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 bridge_create(Account const &acc, Json::Value const &bridge, STAmount const &reward, std::optional< STAmount > const &minAccountCreate)
Json::Value signers(Account const &account, std::uint32_t quorum, std::vector< signer > const &v)
Definition multisign.cpp:15
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_rpc(Account const &lockingChainDoor, Issue const &lockingChainIssue, Account const &issuingChainDoor, Issue const &issuingChainIssue)
Json::Value xchain_claim(Account const &acc, Json::Value const &bridge, std::uint32_t claimID, AnyAmount const &amt, Account const &dst)
XRP_t const XRP
Converts to XRP Issue or STAmount.
Definition amount.cpp:95
Json::Value bridge_modify(Account const &acc, Json::Value const &bridge, std::optional< STAmount > const &reward, std::optional< STAmount > const &minAccountCreate)
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)
Json::Value xchain_create_claim_id(Account const &acc, Json::Value const &bridge, STAmount const &reward, Account const &otherChainSource)
FeatureBitset testable_amendments()
Definition Env.h:78
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:30
Json::Value xchain_commit(Account const &acc, Json::Value const &bridge, std::uint32_t claimID, AnyAmount const &amt, std::optional< Account > const &dst)
Json::Value bridge(Account const &lockingChainDoor, Issue const &lockingChainIssue, Account const &issuingChainDoor, Issue const &issuingChainIssue)
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)
constexpr std::size_t UT_XCHAIN_DEFAULT_QUORUM
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
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)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
STAmount divide(STAmount const &amount, Rate const &rate)
Definition Rate2.cpp:69
KeyType
Definition KeyType.h:8
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
Definition Issue.h:97
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:10
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition AccountID.cpp:92
STAmount multiply(STAmount const &amount, Rate const &rate)
Definition Rate2.cpp:34
Json::Value to_json(Asset const &asset)
Definition Asset.h:121
T push_back(T... args)
T reserve(T... args)
Amount specifier with an option for any issuer.
void createBridgeObjects(Env &mcEnv, Env &scEnv)
std::vector< signer > const signers
A signer in a SignerList.
Definition multisign.h:19
T to_string(T... args)