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, sk, stBridge, sendingAccount, sendingAmount.value, rewardAccount, wasLockingChainSend, claimID, dst);
187
188 Json::Value result;
189
190 result[sfAccount.getJsonName()] = submittingAccount.human();
191 result[sfXChainBridge.getJsonName()] = jvBridge;
192
193 result[sfAttestationSignerAccount.getJsonName()] = signer.account.human();
194 result[sfPublicKey.getJsonName()] = strHex(pk.slice());
195 result[sfSignature.getJsonName()] = strHex(sig);
196 result[sfOtherChainSource.getJsonName()] = toBase58(sendingAccount);
197 result[sfAmount.getJsonName()] = sendingAmount.value.getJson(JsonOptions::none);
198 result[sfAttestationRewardAccount.getJsonName()] = toBase58(rewardAccount);
199 result[sfWasLockingChainSend.getJsonName()] = wasLockingChainSend ? 1 : 0;
200
201 result[sfXChainClaimID.getJsonName()] = STUInt64{claimID}.getJson(JsonOptions::none);
202 if (dst)
203 result[sfDestination.getJsonName()] = toBase58(*dst);
204
205 result[jss::TransactionType] = jss::XChainAddClaimAttestation;
206
207 return result;
208}
209
212 jtx::Account const& submittingAccount,
213 Json::Value const& jvBridge,
214 jtx::Account const& sendingAccount,
215 jtx::AnyAmount const& sendingAmount,
216 jtx::AnyAmount const& rewardAmount,
217 jtx::Account const& rewardAccount,
218 bool wasLockingChainSend,
219 std::uint64_t createCount,
220 jtx::Account const& dst,
221 jtx::signer const& signer)
222{
223 STXChainBridge const stBridge(jvBridge);
224
225 auto const& pk = signer.account.pk();
226 auto const& sk = signer.account.sk();
228 pk,
229 sk,
230 stBridge,
231 sendingAccount,
232 sendingAmount.value,
233 rewardAmount.value,
234 rewardAccount,
235 wasLockingChainSend,
236 createCount,
237 dst);
238
239 Json::Value result;
240
241 result[sfAccount.getJsonName()] = submittingAccount.human();
242 result[sfXChainBridge.getJsonName()] = jvBridge;
243
244 result[sfAttestationSignerAccount.getJsonName()] = signer.account.human();
245 result[sfPublicKey.getJsonName()] = strHex(pk.slice());
246 result[sfSignature.getJsonName()] = strHex(sig);
247 result[sfOtherChainSource.getJsonName()] = toBase58(sendingAccount);
248 result[sfAmount.getJsonName()] = sendingAmount.value.getJson(JsonOptions::none);
249 result[sfAttestationRewardAccount.getJsonName()] = toBase58(rewardAccount);
250 result[sfWasLockingChainSend.getJsonName()] = wasLockingChainSend ? 1 : 0;
251
252 result[sfXChainAccountCreateCount.getJsonName()] = STUInt64{createCount}.getJson(JsonOptions::none);
253 result[sfDestination.getJsonName()] = toBase58(dst);
254 result[sfSignatureReward.getJsonName()] = rewardAmount.value.getJson(JsonOptions::none);
255
256 result[jss::TransactionType] = jss::XChainAddAccountCreateAttestation;
257
258 return result;
259}
260
263 jtx::Account const& submittingAccount,
264 Json::Value const& jvBridge,
265 jtx::Account const& sendingAccount,
266 jtx::AnyAmount const& sendingAmount,
267 std::vector<jtx::Account> const& rewardAccounts,
268 bool wasLockingChainSend,
269 std::uint64_t claimID,
272 std::size_t const numAtts,
273 std::size_t const fromIdx)
274{
275 assert(fromIdx + numAtts <= rewardAccounts.size());
276 assert(fromIdx + numAtts <= signers.size());
277 JValueVec vec;
278 vec.reserve(numAtts);
279 for (auto i = fromIdx; i < fromIdx + numAtts; ++i)
281 submittingAccount,
282 jvBridge,
283 sendingAccount,
284 sendingAmount,
285 rewardAccounts[i],
286 wasLockingChainSend,
287 claimID,
288 dst,
289 signers[i]));
290 return vec;
291}
292
295 jtx::Account const& submittingAccount,
296 Json::Value const& jvBridge,
297 jtx::Account const& sendingAccount,
298 jtx::AnyAmount const& sendingAmount,
299 jtx::AnyAmount const& rewardAmount,
300 std::vector<jtx::Account> const& rewardAccounts,
301 bool wasLockingChainSend,
302 std::uint64_t createCount,
303 jtx::Account const& dst,
305 std::size_t const numAtts,
306 std::size_t const fromIdx)
307{
308 assert(fromIdx + numAtts <= rewardAccounts.size());
309 assert(fromIdx + numAtts <= signers.size());
310 JValueVec vec;
311 vec.reserve(numAtts);
312 for (auto i = fromIdx; i < fromIdx + numAtts; ++i)
314 submittingAccount,
315 jvBridge,
316 sendingAccount,
317 sendingAmount,
318 rewardAmount,
319 rewardAccounts[i],
320 wasLockingChainSend,
321 createCount,
322 dst,
323 signers[i]));
324 return vec;
325}
326
328 : mcDoor("mcDoor")
329 , mcAlice("mcAlice")
330 , mcBob("mcBob")
331 , mcCarol("mcCarol")
332 , mcGw("mcGw")
333 , scDoor("scDoor")
334 , scAlice("scAlice")
335 , scBob("scBob")
336 , scCarol("scCarol")
337 , scGw("scGw")
338 , scAttester("scAttester")
339 , scReward("scReward")
340 , mcuDoor("mcuDoor")
341 , mcuAlice("mcuAlice")
342 , mcuBob("mcuBob")
343 , mcuCarol("mcuCarol")
344 , mcuGw("mcuGw")
345 , scuDoor("scuDoor")
346 , scuAlice("scuAlice")
347 , scuBob("scuBob")
348 , scuCarol("scuCarol")
349 , scuGw("scuGw")
350 , mcUSD(mcGw["USD"])
351 , scUSD(scGw["USD"])
352 , jvXRPBridgeRPC(bridge_rpc(mcDoor, xrpIssue(), Account::master, xrpIssue()))
353 , jvb(bridge(mcDoor, xrpIssue(), Account::master, xrpIssue()))
354 , jvub(bridge(mcuDoor, xrpIssue(), Account::master, xrpIssue()))
355 , features(testable_amendments() | FeatureBitset{featureXChainBridge})
356 , signers([] {
357 constexpr int numSigners = UT_XCHAIN_DEFAULT_NUM_SIGNERS;
358 std::vector<signer> result;
359 result.reserve(numSigners);
360 for (int i = 0; i < numSigners; ++i)
361 {
362 using namespace std::literals;
363 auto const a = Account("signer_"s + std::to_string(i), (i % 2) ? KeyType::ed25519 : KeyType::secp256k1);
364 result.emplace_back(a);
365 }
366 return result;
367 }())
368 , alt_signers([] {
369 constexpr int numSigners = UT_XCHAIN_DEFAULT_NUM_SIGNERS;
370 std::vector<signer> result;
371 result.reserve(numSigners);
372 for (int i = 0; i < numSigners; ++i)
373 {
374 using namespace std::literals;
375 auto const a = Account("alt_signer_"s + std::to_string(i), (i % 2) ? KeyType::ed25519 : KeyType::secp256k1);
376 result.emplace_back(a);
377 }
378 return result;
379 }())
380 , payee([&] {
382 r.reserve(signers.size());
383 for (int i = 0, e = signers.size(); i != e; ++i)
384 {
385 r.push_back(scReward);
386 }
387 return r;
388 }())
389 , payees([&] {
391 r.reserve(signers.size());
392 for (int i = 0, e = signers.size(); i != e; ++i)
393 {
394 using namespace std::literals;
395 auto const a = Account("reward_"s + std::to_string(i));
396 r.push_back(a);
397 }
398 return r;
399 }())
401 , reward(XRP(1))
402 , split_reward_quorum(divide(reward, STAmount(UT_XCHAIN_DEFAULT_QUORUM), reward.issue()))
403 , split_reward_everyone(divide(reward, STAmount(UT_XCHAIN_DEFAULT_NUM_SIGNERS), reward.issue()))
404 , tiny_reward(drops(37))
405 , tiny_reward_split((divide(tiny_reward, STAmount(UT_XCHAIN_DEFAULT_QUORUM), tiny_reward.issue())))
406 , tiny_reward_remainder(
407 tiny_reward - multiply(tiny_reward_split, STAmount(UT_XCHAIN_DEFAULT_QUORUM), tiny_reward.issue()))
408 , one_xrp(XRP(1))
409 , xrp_dust(divide(one_xrp, STAmount(10000), one_xrp.issue()))
410{
411}
412
413void
415{
416 STAmount xrp_funds{XRP(10000)};
417 mcEnv.fund(xrp_funds, mcDoor, mcAlice, mcBob, mcCarol, mcGw);
418
419 // Signer's list must match the attestation signers
420 mcEnv(jtx::signers(mcDoor, signers.size(), signers));
421
422 // create XRP bridges in both direction
423 auto const reward = XRP(1);
424 STAmount const minCreate = XRP(20);
425
426 mcEnv(bridge_create(mcDoor, jvb, reward, minCreate));
427 mcEnv.close();
428}
429
430void
432{
433 STAmount xrp_funds{XRP(10000)};
434 scEnv.fund(xrp_funds, scDoor, scAlice, scBob, scCarol, scGw, scAttester, scReward);
435
436 // Signer's list must match the attestation signers
438
439 // create XRP bridges in both direction
440 auto const reward = XRP(1);
441 STAmount const minCreate = XRP(20);
442
443 scEnv(bridge_create(Account::master, jvb, reward, minCreate));
444 scEnv.close();
445}
446
447void
453} // namespace jtx
454} // namespace test
455} // 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:721
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:119
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition Env.cpp:98
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition Env.cpp:261
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:90
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:76
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)
T size(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)