rippled
Loading...
Searching...
No Matches
XChainAttestations.cpp
1#include <xrpl/basics/Buffer.h>
2#include <xrpl/basics/Slice.h>
3#include <xrpl/basics/contract.h>
4#include <xrpl/json/json_value.h>
5#include <xrpl/protocol/AccountID.h>
6#include <xrpl/protocol/PublicKey.h>
7#include <xrpl/protocol/SField.h>
8#include <xrpl/protocol/STAccount.h>
9#include <xrpl/protocol/STAmount.h>
10#include <xrpl/protocol/STArray.h>
11#include <xrpl/protocol/STObject.h>
12#include <xrpl/protocol/SecretKey.h>
13#include <xrpl/protocol/Serializer.h>
14#include <xrpl/protocol/XChainAttestations.h>
15#include <xrpl/protocol/json_get_or_throw.h>
16#include <xrpl/protocol/jss.h>
17
18#include <cstdint>
19#include <optional>
20#include <stdexcept>
21#include <tuple>
22#include <utility>
23#include <vector>
24
25namespace ripple {
26namespace Attestations {
27
29 AccountID attestationSignerAccount_,
30 PublicKey const& publicKey_,
31 Buffer signature_,
32 AccountID const& sendingAccount_,
33 STAmount const& sendingAmount_,
34 AccountID const& rewardAccount_,
35 bool wasLockingChainSend_)
36 : attestationSignerAccount{attestationSignerAccount_}
37 , publicKey{publicKey_}
38 , signature{std::move(signature_)}
39 , sendingAccount{sendingAccount_}
40 , sendingAmount{sendingAmount_}
41 , rewardAccount{rewardAccount_}
42 , wasLockingChainSend{wasLockingChainSend_}
43{
44}
45
46bool
48 AttestationBase const& lhs,
49 AttestationBase const& rhs)
50{
51 return std::tie(
53 lhs.publicKey,
54 lhs.signature,
56 lhs.sendingAmount,
57 lhs.rewardAccount,
61 rhs.publicKey,
62 rhs.signature,
64 rhs.sendingAmount,
65 rhs.rewardAccount,
67}
68
69bool
81
82bool
88
90 : attestationSignerAccount{o[sfAttestationSignerAccount]}
91 , publicKey{o[sfPublicKey]}
92 , signature{o[sfSignature]}
93 , sendingAccount{o[sfAccount]}
94 , sendingAmount{o[sfAmount]}
95 , rewardAccount{o[sfAttestationRewardAccount]}
96 , wasLockingChainSend{bool(o[sfWasLockingChainSend])}
97{
98}
99
101 : attestationSignerAccount{Json::getOrThrow<AccountID>(
102 v,
103 sfAttestationSignerAccount)}
104 , publicKey{Json::getOrThrow<PublicKey>(v, sfPublicKey)}
105 , signature{Json::getOrThrow<Buffer>(v, sfSignature)}
106 , sendingAccount{Json::getOrThrow<AccountID>(v, sfAccount)}
107 , sendingAmount{Json::getOrThrow<STAmount>(v, sfAmount)}
108 , rewardAccount{Json::getOrThrow<AccountID>(v, sfAttestationRewardAccount)}
109 , wasLockingChainSend{Json::getOrThrow<bool>(v, sfWasLockingChainSend)}
110{
111}
112
113void
115{
116 o[sfAttestationSignerAccount] = attestationSignerAccount;
117 o[sfPublicKey] = publicKey;
118 o[sfSignature] = signature;
119 o[sfAmount] = sendingAmount;
120 o[sfAccount] = sendingAccount;
121 o[sfAttestationRewardAccount] = rewardAccount;
122 o[sfWasLockingChainSend] = wasLockingChainSend;
123}
124
126 AccountID attestationSignerAccount_,
127 PublicKey const& publicKey_,
128 Buffer signature_,
129 AccountID const& sendingAccount_,
130 STAmount const& sendingAmount_,
131 AccountID const& rewardAccount_,
132 bool wasLockingChainSend_,
133 std::uint64_t claimID_,
134 std::optional<AccountID> const& dst_)
136 attestationSignerAccount_,
137 publicKey_,
138 std::move(signature_),
139 sendingAccount_,
140 sendingAmount_,
141 rewardAccount_,
142 wasLockingChainSend_)
143 , claimID{claimID_}
144 , dst{dst_}
145{
146}
147
149 STXChainBridge const& bridge,
150 AccountID attestationSignerAccount_,
151 PublicKey const& publicKey_,
152 SecretKey const& secretKey_,
153 AccountID const& sendingAccount_,
154 STAmount const& sendingAmount_,
155 AccountID const& rewardAccount_,
156 bool wasLockingChainSend_,
157 std::uint64_t claimID_,
158 std::optional<AccountID> const& dst_)
160 attestationSignerAccount_,
161 publicKey_,
162 Buffer{},
163 sendingAccount_,
164 sendingAmount_,
165 rewardAccount_,
166 wasLockingChainSend_,
167 claimID_,
168 dst_}
169{
170 auto const toSign = message(bridge);
171 signature = sign(publicKey_, secretKey_, makeSlice(toSign));
172}
173
175 : AttestationBase(o), claimID{o[sfXChainClaimID]}, dst{o[~sfDestination]}
176{
177}
178
180 : AttestationBase{v}
181 , claimID{Json::getOrThrow<std::uint64_t>(v, sfXChainClaimID)}
182{
183 if (v.isMember(sfDestination.getJsonName()))
184 dst = Json::getOrThrow<AccountID>(v, sfDestination);
185}
186
189{
190 STObject o =
191 STObject::makeInnerObject(sfXChainClaimAttestationCollectionElement);
192 addHelper(o);
193 o[sfXChainClaimID] = claimID;
194 if (dst)
195 o[sfDestination] = *dst;
196 return o;
197}
198
201 STXChainBridge const& bridge,
202 AccountID const& sendingAccount,
203 STAmount const& sendingAmount,
204 AccountID const& rewardAccount,
205 bool wasLockingChainSend,
206 std::uint64_t claimID,
207 std::optional<AccountID> const& dst)
208{
210 // Serialize in SField order to make python serializers easier to write
211 o[sfXChainClaimID] = claimID;
212 o[sfAmount] = sendingAmount;
213 if (dst)
214 o[sfDestination] = *dst;
215 o[sfOtherChainSource] = sendingAccount;
216 o[sfAttestationRewardAccount] = rewardAccount;
217 o[sfWasLockingChainSend] = wasLockingChainSend ? 1 : 0;
218 o[sfXChainBridge] = bridge;
219
220 Serializer s;
221 o.add(s);
222
223 return std::move(s.modData());
224}
225
228{
230 bridge,
235 claimID,
236 dst);
237}
238
239bool
244
245bool
247{
248 return AttestationClaim::sameEventHelper(*this, rhs) &&
249 tie(claimID, dst) == tie(rhs.claimID, rhs.dst);
250}
251
252bool
254{
255 return AttestationClaim::equalHelper(lhs, rhs) &&
256 tie(lhs.claimID, lhs.dst) == tie(rhs.claimID, rhs.dst);
257}
258
260 : AttestationBase(o)
261 , createCount{o[sfXChainAccountCreateCount]}
262 , toCreate{o[sfDestination]}
263 , rewardAmount{o[sfSignatureReward]}
264{
265}
266
268 : AttestationBase{v}
269 , createCount{Json::getOrThrow<std::uint64_t>(
270 v,
271 sfXChainAccountCreateCount)}
272 , toCreate{Json::getOrThrow<AccountID>(v, sfDestination)}
273 , rewardAmount{Json::getOrThrow<STAmount>(v, sfSignatureReward)}
274{
275}
276
278 AccountID attestationSignerAccount_,
279 PublicKey const& publicKey_,
280 Buffer signature_,
281 AccountID const& sendingAccount_,
282 STAmount const& sendingAmount_,
283 STAmount const& rewardAmount_,
284 AccountID const& rewardAccount_,
285 bool wasLockingChainSend_,
286 std::uint64_t createCount_,
287 AccountID const& toCreate_)
289 attestationSignerAccount_,
290 publicKey_,
291 std::move(signature_),
292 sendingAccount_,
293 sendingAmount_,
294 rewardAccount_,
295 wasLockingChainSend_)
296 , createCount{createCount_}
297 , toCreate{toCreate_}
298 , rewardAmount{rewardAmount_}
299{
300}
301
303 STXChainBridge const& bridge,
304 AccountID attestationSignerAccount_,
305 PublicKey const& publicKey_,
306 SecretKey const& secretKey_,
307 AccountID const& sendingAccount_,
308 STAmount const& sendingAmount_,
309 STAmount const& rewardAmount_,
310 AccountID const& rewardAccount_,
311 bool wasLockingChainSend_,
312 std::uint64_t createCount_,
313 AccountID const& toCreate_)
315 attestationSignerAccount_,
316 publicKey_,
317 Buffer{},
318 sendingAccount_,
319 sendingAmount_,
320 rewardAmount_,
321 rewardAccount_,
322 wasLockingChainSend_,
323 createCount_,
324 toCreate_}
325{
326 auto const toSign = message(bridge);
327 signature = sign(publicKey_, secretKey_, makeSlice(toSign));
328}
329
332{
334 sfXChainCreateAccountAttestationCollectionElement);
335 addHelper(o);
336
337 o[sfXChainAccountCreateCount] = createCount;
338 o[sfDestination] = toCreate;
339 o[sfSignatureReward] = rewardAmount;
340
341 return o;
342}
343
346 STXChainBridge const& bridge,
347 AccountID const& sendingAccount,
348 STAmount const& sendingAmount,
349 STAmount const& rewardAmount,
350 AccountID const& rewardAccount,
351 bool wasLockingChainSend,
352 std::uint64_t createCount,
353 AccountID const& dst)
354{
356 // Serialize in SField order to make python serializers easier to write
357 o[sfXChainAccountCreateCount] = createCount;
358 o[sfAmount] = sendingAmount;
359 o[sfSignatureReward] = rewardAmount;
360 o[sfDestination] = dst;
361 o[sfOtherChainSource] = sendingAccount;
362 o[sfAttestationRewardAccount] = rewardAccount;
363 o[sfWasLockingChainSend] = wasLockingChainSend ? 1 : 0;
364 o[sfXChainBridge] = bridge;
365
366 Serializer s;
367 o.add(s);
368
369 return std::move(s.modData());
370}
371
385
386bool
388{
390}
391
392bool
394{
399
400bool
402 AttestationCreateAccount const& lhs,
403 AttestationCreateAccount const& rhs)
404{
405 return AttestationCreateAccount::equalHelper(lhs, rhs) &&
406 std::tie(lhs.createCount, lhs.toCreate, lhs.rewardAmount) ==
407 std::tie(rhs.createCount, rhs.toCreate, rhs.rewardAmount);
408}
409
410} // namespace Attestations
411
412SField const& XChainClaimAttestation::ArrayFieldName{sfXChainClaimAttestations};
414 sfXChainCreateAccountAttestations};
415
417 AccountID const& keyAccount_,
418 PublicKey const& publicKey_,
419 STAmount const& amount_,
420 AccountID const& rewardAccount_,
421 bool wasLockingChainSend_,
422 std::optional<AccountID> const& dst_)
423 : keyAccount(keyAccount_)
424 , publicKey(publicKey_)
425 , amount(sfAmount, amount_)
426 , rewardAccount(rewardAccount_)
427 , wasLockingChainSend(wasLockingChainSend_)
428 , dst(dst_)
429{
430}
431
433 STAccount const& keyAccount_,
434 PublicKey const& publicKey_,
435 STAmount const& amount_,
436 STAccount const& rewardAccount_,
437 bool wasLockingChainSend_,
438 std::optional<STAccount> const& dst_)
440 keyAccount_.value(),
441 publicKey_,
442 amount_,
443 rewardAccount_.value(),
444 wasLockingChainSend_,
445 dst_ ? std::optional<AccountID>{dst_->value()} : std::nullopt}
446{
447}
448
449XChainClaimAttestation::XChainClaimAttestation(STObject const& o)
451 o[sfAttestationSignerAccount],
452 PublicKey{o[sfPublicKey]},
453 o[sfAmount],
454 o[sfAttestationRewardAccount],
455 o[sfWasLockingChainSend] != 0,
456 o[~sfDestination]} {};
457
460 Json::getOrThrow<AccountID>(v, sfAttestationSignerAccount),
461 Json::getOrThrow<PublicKey>(v, sfPublicKey),
462 Json::getOrThrow<STAmount>(v, sfAmount),
463 Json::getOrThrow<AccountID>(v, sfAttestationRewardAccount),
464 Json::getOrThrow<bool>(v, sfWasLockingChainSend),
465 std::nullopt}
466{
467 if (v.isMember(sfDestination.getJsonName()))
468 dst = Json::getOrThrow<AccountID>(v, sfDestination);
469};
470
474 claimAtt.attestationSignerAccount,
475 claimAtt.publicKey,
476 claimAtt.sendingAmount,
477 claimAtt.rewardAccount,
478 claimAtt.wasLockingChainSend,
479 claimAtt.dst}
480{
481}
482
485{
486 STObject o = STObject::makeInnerObject(sfXChainClaimProofSig);
487 o[sfAttestationSignerAccount] =
488 STAccount{sfAttestationSignerAccount, keyAccount};
489 o[sfPublicKey] = publicKey;
490 o[sfAmount] = STAmount{sfAmount, amount};
491 o[sfAttestationRewardAccount] =
492 STAccount{sfAttestationRewardAccount, rewardAccount};
493 o[sfWasLockingChainSend] = wasLockingChainSend;
494 if (dst)
495 o[sfDestination] = STAccount{sfDestination, *dst};
496 return o;
497}
498
499bool
501{
502 return std::tie(
503 lhs.keyAccount,
504 lhs.publicKey,
505 lhs.amount,
506 lhs.rewardAccount,
508 lhs.dst) ==
509 std::tie(
510 rhs.keyAccount,
511 rhs.publicKey,
512 rhs.amount,
513 rhs.rewardAccount,
515 rhs.dst);
516}
517
520 : amount{att.sendingAmount}
521 , wasLockingChainSend{att.wasLockingChainSend}
522 , dst{att.dst}
523{
524}
525
537
538//------------------------------------------------------------------------------
539
541 AccountID const& keyAccount_,
542 PublicKey const& publicKey_,
543 STAmount const& amount_,
544 STAmount const& rewardAmount_,
545 AccountID const& rewardAccount_,
546 bool wasLockingChainSend_,
547 AccountID const& dst_)
548 : keyAccount(keyAccount_)
549 , publicKey(publicKey_)
550 , amount(sfAmount, amount_)
551 , rewardAmount(sfSignatureReward, rewardAmount_)
552 , rewardAccount(rewardAccount_)
553 , wasLockingChainSend(wasLockingChainSend_)
554 , dst(dst_)
555{
556}
557
559 STObject const& o)
561 o[sfAttestationSignerAccount],
562 PublicKey{o[sfPublicKey]},
563 o[sfAmount],
564 o[sfSignatureReward],
565 o[sfAttestationRewardAccount],
566 o[sfWasLockingChainSend] != 0,
567 o[sfDestination]} {};
568
569XChainCreateAccountAttestation ::XChainCreateAccountAttestation(
570 Json::Value const& v)
572 Json::getOrThrow<AccountID>(v, sfAttestationSignerAccount),
573 Json::getOrThrow<PublicKey>(v, sfPublicKey),
574 Json::getOrThrow<STAmount>(v, sfAmount),
575 Json::getOrThrow<STAmount>(v, sfSignatureReward),
576 Json::getOrThrow<AccountID>(v, sfAttestationRewardAccount),
577 Json::getOrThrow<bool>(v, sfWasLockingChainSend),
578 Json::getOrThrow<AccountID>(v, sfDestination)}
579{
580}
581
585 createAtt.attestationSignerAccount,
586 createAtt.publicKey,
587 createAtt.sendingAmount,
588 createAtt.rewardAmount,
589 createAtt.rewardAccount,
590 createAtt.wasLockingChainSend,
591 createAtt.toCreate}
592{
593}
594
597{
598 STObject o = STObject::makeInnerObject(sfXChainCreateAccountProofSig);
599
600 o[sfAttestationSignerAccount] =
601 STAccount{sfAttestationSignerAccount, keyAccount};
602 o[sfPublicKey] = publicKey;
603 o[sfAmount] = STAmount{sfAmount, amount};
604 o[sfSignatureReward] = STAmount{sfSignatureReward, rewardAmount};
605 o[sfAttestationRewardAccount] =
606 STAccount{sfAttestationRewardAccount, rewardAccount};
607 o[sfWasLockingChainSend] = wasLockingChainSend;
608 o[sfDestination] = STAccount{sfDestination, dst};
609
610 return o;
611}
612
615 : amount{att.sendingAmount}
616 , rewardAmount(att.rewardAmount)
617 , wasLockingChainSend{att.wasLockingChainSend}
618 , dst{att.toCreate}
619{
620}
621
633
634bool
638{
639 return std::tie(
640 lhs.keyAccount,
641 lhs.publicKey,
642 lhs.amount,
643 lhs.rewardAmount,
644 lhs.rewardAccount,
646 lhs.dst) ==
647 std::tie(
648 rhs.keyAccount,
649 rhs.publicKey,
650 rhs.amount,
651 rhs.rewardAmount,
652 rhs.rewardAccount,
654 rhs.dst);
655}
656
657//------------------------------------------------------------------------------
658//
659template <class TAttestation>
662 : attestations_{std::move(atts)}
663{
664}
665
666template <class TAttestation>
667typename XChainAttestationsBase<TAttestation>::AttCollection::const_iterator
669{
670 return attestations_.begin();
671}
672
673template <class TAttestation>
676{
677 return attestations_.end();
678}
679
680template <class TAttestation>
683{
684 return attestations_.begin();
685}
686
687template <class TAttestation>
690{
691 return attestations_.end();
692}
693
694template <class TAttestation>
696 Json::Value const& v)
697{
698 if (!v.isObject())
699 {
700 Throw<std::runtime_error>(
701 "XChainAttestationsBase can only be specified with an 'object' "
702 "Json value");
703 }
704
705 attestations_ = [&] {
706 auto const jAtts = v[jss::attestations];
707
708 if (jAtts.size() > maxAttestations)
709 Throw<std::runtime_error>(
710 "XChainAttestationsBase exceeded max number of attestations");
711
713 r.reserve(jAtts.size());
714 for (auto const& a : jAtts)
715 r.emplace_back(a);
716 return r;
717 }();
718}
719
720template <class TAttestation>
722{
723 if (arr.size() > maxAttestations)
724 Throw<std::runtime_error>(
725 "XChainAttestationsBase exceeded max number of attestations");
726
727 attestations_.reserve(arr.size());
728 for (auto const& o : arr)
729 attestations_.emplace_back(o);
730}
731
732template <class TAttestation>
735{
736 STArray r{TAttestation::ArrayFieldName, attestations_.size()};
737 for (auto const& e : attestations_)
738 r.emplace_back(e.toSTObject());
739 return r;
740}
741
744
745} // namespace ripple
Represents a JSON value.
Definition json_value.h:131
bool isObject() const
bool isMember(char const *key) const
Return true if the object has a member named key.
Like std::vector<char> but better.
Definition Buffer.h:17
A public key.
Definition PublicKey.h:43
size_type size() const
Definition STArray.h:229
static STObject makeInnerObject(SField const &name)
Definition STObject.cpp:76
A secret key.
Definition SecretKey.h:19
AttCollection::const_iterator end() const
AttCollection::const_iterator begin() const
T emplace_back(T... args)
T is_same_v
JSON (JavaScript Object Notation).
Definition json_errors.h:6
bool operator==(AttestationClaim const &lhs, AttestationClaim const &rhs)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig, bool mustBeFullyCanonical=true) noexcept
Verify a signature on a message.
bool isLegalNet(STAmount const &value)
Definition STAmount.h:581
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &message)
Generate a signature for a message.
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition Slice.h:225
SField const sfGeneric
constexpr bool operator==(base_uint< Bits, Tag > const &lhs, base_uint< Bits, Tag > const &rhs)
Definition base_uint.h:566
STL namespace.
T reserve(T... args)
static bool equalHelper(AttestationBase const &lhs, AttestationBase const &rhs)
virtual std::vector< std::uint8_t > message(STXChainBridge const &bridge) const =0
AttestationBase(AccountID attestationSignerAccount_, PublicKey const &publicKey_, Buffer signature_, AccountID const &sendingAccount_, STAmount const &sendingAmount_, AccountID const &rewardAccount_, bool wasLockingChainSend_)
static bool sameEventHelper(AttestationBase const &lhs, AttestationBase const &rhs)
bool verify(STXChainBridge const &bridge) const
bool sameEvent(AttestationClaim const &rhs) const
AttestationClaim(AccountID attestationSignerAccount_, PublicKey const &publicKey_, Buffer signature_, AccountID const &sendingAccount_, STAmount const &sendingAmount_, AccountID const &rewardAccount_, bool wasLockingChainSend_, std::uint64_t claimID_, std::optional< AccountID > const &dst_)
static std::vector< std::uint8_t > message(STXChainBridge const &bridge, AccountID const &sendingAccount, STAmount const &sendingAmount, AccountID const &rewardAccount, bool wasLockingChainSend, std::uint64_t claimID, std::optional< AccountID > const &dst)
static std::vector< std::uint8_t > message(STXChainBridge const &bridge, AccountID const &sendingAccount, STAmount const &sendingAmount, STAmount const &rewardAmount, AccountID const &rewardAccount, bool wasLockingChainSend, std::uint64_t createCount, AccountID const &dst)
bool sameEvent(AttestationCreateAccount const &rhs) const
AttestationMatch match(MatchFields const &rhs) const
static SField const & ArrayFieldName
std::optional< AccountID > dst
XChainClaimAttestation(AccountID const &keyAccount_, PublicKey const &publicKey_, STAmount const &amount_, AccountID const &rewardAccount_, bool wasLockingChainSend_, std::optional< AccountID > const &dst)
XChainCreateAccountAttestation(AccountID const &keyAccount_, PublicKey const &publicKey_, STAmount const &amount_, STAmount const &rewardAmount_, AccountID const &rewardAccount_, bool wasLockingChainSend_, AccountID const &dst_)
AttestationMatch match(MatchFields const &rhs) const
friend bool operator==(XChainCreateAccountAttestation const &lhs, XChainCreateAccountAttestation const &rhs)
T tie(T... args)
T value(T... args)