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 xrpl {
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
66
67bool
73
74bool
76{
77 std::vector<std::uint8_t> const msg = message(bridge);
79}
80
82 : attestationSignerAccount{o[sfAttestationSignerAccount]}
83 , publicKey{o[sfPublicKey]}
84 , signature{o[sfSignature]}
85 , sendingAccount{o[sfAccount]}
86 , sendingAmount{o[sfAmount]}
87 , rewardAccount{o[sfAttestationRewardAccount]}
88 , wasLockingChainSend{bool(o[sfWasLockingChainSend])}
89{
90}
91
93 : attestationSignerAccount{Json::getOrThrow<AccountID>(v, sfAttestationSignerAccount)}
94 , publicKey{Json::getOrThrow<PublicKey>(v, sfPublicKey)}
95 , signature{Json::getOrThrow<Buffer>(v, sfSignature)}
96 , sendingAccount{Json::getOrThrow<AccountID>(v, sfAccount)}
97 , sendingAmount{Json::getOrThrow<STAmount>(v, sfAmount)}
98 , rewardAccount{Json::getOrThrow<AccountID>(v, sfAttestationRewardAccount)}
99 , wasLockingChainSend{Json::getOrThrow<bool>(v, sfWasLockingChainSend)}
100{
101}
102
103void
105{
106 o[sfAttestationSignerAccount] = attestationSignerAccount;
107 o[sfPublicKey] = publicKey;
108 o[sfSignature] = signature;
109 o[sfAmount] = sendingAmount;
110 o[sfAccount] = sendingAccount;
111 o[sfAttestationRewardAccount] = rewardAccount;
112 o[sfWasLockingChainSend] = wasLockingChainSend;
113}
114
116 AccountID attestationSignerAccount_,
117 PublicKey const& publicKey_,
118 Buffer signature_,
119 AccountID const& sendingAccount_,
120 STAmount const& sendingAmount_,
121 AccountID const& rewardAccount_,
122 bool wasLockingChainSend_,
123 std::uint64_t claimID_,
124 std::optional<AccountID> const& dst_)
126 attestationSignerAccount_,
127 publicKey_,
128 std::move(signature_),
129 sendingAccount_,
130 sendingAmount_,
131 rewardAccount_,
132 wasLockingChainSend_)
133 , claimID{claimID_}
134 , dst{dst_}
135{
136}
137
139 STXChainBridge const& bridge,
140 AccountID attestationSignerAccount_,
141 PublicKey const& publicKey_,
142 SecretKey const& secretKey_,
143 AccountID const& sendingAccount_,
144 STAmount const& sendingAmount_,
145 AccountID const& rewardAccount_,
146 bool wasLockingChainSend_,
147 std::uint64_t claimID_,
148 std::optional<AccountID> const& dst_)
150 attestationSignerAccount_,
151 publicKey_,
152 Buffer{},
153 sendingAccount_,
154 sendingAmount_,
155 rewardAccount_,
156 wasLockingChainSend_,
157 claimID_,
158 dst_}
159{
160 auto const toSign = message(bridge);
161 signature = sign(publicKey_, secretKey_, makeSlice(toSign));
162}
163
165 : AttestationBase(o), claimID{o[sfXChainClaimID]}, dst{o[~sfDestination]}
166{
167}
168
170 : AttestationBase{v}, claimID{Json::getOrThrow<std::uint64_t>(v, sfXChainClaimID)}
171{
172 if (v.isMember(sfDestination.getJsonName()))
173 dst = Json::getOrThrow<AccountID>(v, sfDestination);
174}
175
178{
179 STObject o = STObject::makeInnerObject(sfXChainClaimAttestationCollectionElement);
180 addHelper(o);
181 o[sfXChainClaimID] = claimID;
182 if (dst)
183 o[sfDestination] = *dst;
184 return o;
185}
186
189 STXChainBridge const& bridge,
190 AccountID const& sendingAccount,
191 STAmount const& sendingAmount,
192 AccountID const& rewardAccount,
193 bool wasLockingChainSend,
194 std::uint64_t claimID,
195 std::optional<AccountID> const& dst)
196{
198 // Serialize in SField order to make python serializers easier to write
199 o[sfXChainClaimID] = claimID;
200 o[sfAmount] = sendingAmount;
201 if (dst)
202 o[sfDestination] = *dst;
203 o[sfOtherChainSource] = sendingAccount;
204 o[sfAttestationRewardAccount] = rewardAccount;
205 o[sfWasLockingChainSend] = wasLockingChainSend ? 1 : 0;
206 o[sfXChainBridge] = bridge;
207
208 Serializer s;
209 o.add(s);
210
211 return std::move(s.modData());
212}
213
220
221bool
226
227bool
229{
230 return AttestationClaim::sameEventHelper(*this, rhs) &&
231 tie(claimID, dst) == tie(rhs.claimID, rhs.dst);
232}
233
234bool
236{
237 return AttestationClaim::equalHelper(lhs, rhs) &&
238 tie(lhs.claimID, lhs.dst) == tie(rhs.claimID, rhs.dst);
239}
240
242 : AttestationBase(o)
243 , createCount{o[sfXChainAccountCreateCount]}
244 , toCreate{o[sfDestination]}
245 , rewardAmount{o[sfSignatureReward]}
246{
247}
248
250 : AttestationBase{v}
251 , createCount{Json::getOrThrow<std::uint64_t>(v, sfXChainAccountCreateCount)}
252 , toCreate{Json::getOrThrow<AccountID>(v, sfDestination)}
253 , rewardAmount{Json::getOrThrow<STAmount>(v, sfSignatureReward)}
254{
255}
256
258 AccountID attestationSignerAccount_,
259 PublicKey const& publicKey_,
260 Buffer signature_,
261 AccountID const& sendingAccount_,
262 STAmount const& sendingAmount_,
263 STAmount const& rewardAmount_,
264 AccountID const& rewardAccount_,
265 bool wasLockingChainSend_,
266 std::uint64_t createCount_,
267 AccountID const& toCreate_)
269 attestationSignerAccount_,
270 publicKey_,
271 std::move(signature_),
272 sendingAccount_,
273 sendingAmount_,
274 rewardAccount_,
275 wasLockingChainSend_)
276 , createCount{createCount_}
277 , toCreate{toCreate_}
278 , rewardAmount{rewardAmount_}
279{
280}
281
283 STXChainBridge const& bridge,
284 AccountID attestationSignerAccount_,
285 PublicKey const& publicKey_,
286 SecretKey const& secretKey_,
287 AccountID const& sendingAccount_,
288 STAmount const& sendingAmount_,
289 STAmount const& rewardAmount_,
290 AccountID const& rewardAccount_,
291 bool wasLockingChainSend_,
292 std::uint64_t createCount_,
293 AccountID const& toCreate_)
295 attestationSignerAccount_,
296 publicKey_,
297 Buffer{},
298 sendingAccount_,
299 sendingAmount_,
300 rewardAmount_,
301 rewardAccount_,
302 wasLockingChainSend_,
303 createCount_,
304 toCreate_}
305{
306 auto const toSign = message(bridge);
307 signature = sign(publicKey_, secretKey_, makeSlice(toSign));
308}
309
312{
313 STObject o = STObject::makeInnerObject(sfXChainCreateAccountAttestationCollectionElement);
314 addHelper(o);
315
316 o[sfXChainAccountCreateCount] = createCount;
317 o[sfDestination] = toCreate;
318 o[sfSignatureReward] = rewardAmount;
319
320 return o;
321}
322
325 STXChainBridge const& bridge,
326 AccountID const& sendingAccount,
327 STAmount const& sendingAmount,
328 STAmount const& rewardAmount,
329 AccountID const& rewardAccount,
330 bool wasLockingChainSend,
331 std::uint64_t createCount,
332 AccountID const& dst)
333{
335 // Serialize in SField order to make python serializers easier to write
336 o[sfXChainAccountCreateCount] = createCount;
337 o[sfAmount] = sendingAmount;
338 o[sfSignatureReward] = rewardAmount;
339 o[sfDestination] = dst;
340 o[sfOtherChainSource] = sendingAccount;
341 o[sfAttestationRewardAccount] = rewardAccount;
342 o[sfWasLockingChainSend] = wasLockingChainSend ? 1 : 0;
343 o[sfXChainBridge] = bridge;
344
345 Serializer s;
346 o.add(s);
347
348 return std::move(s.modData());
349}
350
364
365bool
370
371bool
373{
377}
378
379bool
381{
383 std::tie(lhs.createCount, lhs.toCreate, lhs.rewardAmount) ==
386
387} // namespace Attestations
389SField const& XChainClaimAttestation::ArrayFieldName{sfXChainClaimAttestations};
390SField const& XChainCreateAccountAttestation::ArrayFieldName{sfXChainCreateAccountAttestations};
393 AccountID const& keyAccount_,
394 PublicKey const& publicKey_,
395 STAmount const& amount_,
396 AccountID const& rewardAccount_,
397 bool wasLockingChainSend_,
398 std::optional<AccountID> const& dst_)
399 : keyAccount(keyAccount_)
400 , publicKey(publicKey_)
401 , amount(sfAmount, amount_)
402 , rewardAccount(rewardAccount_)
403 , wasLockingChainSend(wasLockingChainSend_)
404 , dst(dst_)
405{
406}
407
409 STAccount const& keyAccount_,
410 PublicKey const& publicKey_,
411 STAmount const& amount_,
412 STAccount const& rewardAccount_,
413 bool wasLockingChainSend_,
414 std::optional<STAccount> const& dst_)
416 keyAccount_.value(),
417 publicKey_,
418 amount_,
419 rewardAccount_.value(),
420 wasLockingChainSend_,
421 dst_ ? std::optional<AccountID>{dst_->value()} : std::nullopt}
422{
423}
424
425XChainClaimAttestation::XChainClaimAttestation(STObject const& o)
427 o[sfAttestationSignerAccount],
428 PublicKey{o[sfPublicKey]},
429 o[sfAmount],
430 o[sfAttestationRewardAccount],
431 o[sfWasLockingChainSend] != 0,
432 o[~sfDestination]} {};
433
436 Json::getOrThrow<AccountID>(v, sfAttestationSignerAccount),
437 Json::getOrThrow<PublicKey>(v, sfPublicKey),
438 Json::getOrThrow<STAmount>(v, sfAmount),
439 Json::getOrThrow<AccountID>(v, sfAttestationRewardAccount),
440 Json::getOrThrow<bool>(v, sfWasLockingChainSend),
441 std::nullopt}
442{
443 if (v.isMember(sfDestination.getJsonName()))
444 dst = Json::getOrThrow<AccountID>(v, sfDestination);
445};
446
450 claimAtt.attestationSignerAccount,
451 claimAtt.publicKey,
452 claimAtt.sendingAmount,
453 claimAtt.rewardAccount,
454 claimAtt.wasLockingChainSend,
455 claimAtt.dst}
456{
457}
458
461{
462 STObject o = STObject::makeInnerObject(sfXChainClaimProofSig);
463 o[sfAttestationSignerAccount] = STAccount{sfAttestationSignerAccount, keyAccount};
464 o[sfPublicKey] = publicKey;
465 o[sfAmount] = STAmount{sfAmount, amount};
466 o[sfAttestationRewardAccount] = STAccount{sfAttestationRewardAccount, rewardAccount};
467 o[sfWasLockingChainSend] = wasLockingChainSend;
468 if (dst)
469 o[sfDestination] = STAccount{sfDestination, *dst};
470 return o;
471}
472
473bool
475{
476 return std::tie(
477 lhs.keyAccount,
478 lhs.publicKey,
479 lhs.amount,
480 lhs.rewardAccount,
482 lhs.dst) ==
483 std::tie(
484 rhs.keyAccount,
485 rhs.publicKey,
486 rhs.amount,
487 rhs.rewardAccount,
489 rhs.dst);
490}
491
494 : amount{att.sendingAmount}, wasLockingChainSend{att.wasLockingChainSend}, dst{att.dst}
495{
496}
497
507
508//------------------------------------------------------------------------------
509
511 AccountID const& keyAccount_,
512 PublicKey const& publicKey_,
513 STAmount const& amount_,
514 STAmount const& rewardAmount_,
515 AccountID const& rewardAccount_,
516 bool wasLockingChainSend_,
517 AccountID const& dst_)
518 : keyAccount(keyAccount_)
519 , publicKey(publicKey_)
520 , amount(sfAmount, amount_)
521 , rewardAmount(sfSignatureReward, rewardAmount_)
522 , rewardAccount(rewardAccount_)
523 , wasLockingChainSend(wasLockingChainSend_)
524 , dst(dst_)
525{
526}
527
530 o[sfAttestationSignerAccount],
531 PublicKey{o[sfPublicKey]},
532 o[sfAmount],
533 o[sfSignatureReward],
534 o[sfAttestationRewardAccount],
535 o[sfWasLockingChainSend] != 0,
536 o[sfDestination]} {};
537
538XChainCreateAccountAttestation ::XChainCreateAccountAttestation(Json::Value const& v)
540 Json::getOrThrow<AccountID>(v, sfAttestationSignerAccount),
541 Json::getOrThrow<PublicKey>(v, sfPublicKey),
542 Json::getOrThrow<STAmount>(v, sfAmount),
543 Json::getOrThrow<STAmount>(v, sfSignatureReward),
544 Json::getOrThrow<AccountID>(v, sfAttestationRewardAccount),
545 Json::getOrThrow<bool>(v, sfWasLockingChainSend),
546 Json::getOrThrow<AccountID>(v, sfDestination)}
547{
548}
549
553 createAtt.attestationSignerAccount,
554 createAtt.publicKey,
555 createAtt.sendingAmount,
556 createAtt.rewardAmount,
557 createAtt.rewardAccount,
558 createAtt.wasLockingChainSend,
559 createAtt.toCreate}
560{
561}
562
565{
566 STObject o = STObject::makeInnerObject(sfXChainCreateAccountProofSig);
567
568 o[sfAttestationSignerAccount] = STAccount{sfAttestationSignerAccount, keyAccount};
569 o[sfPublicKey] = publicKey;
570 o[sfAmount] = STAmount{sfAmount, amount};
571 o[sfSignatureReward] = STAmount{sfSignatureReward, rewardAmount};
572 o[sfAttestationRewardAccount] = STAccount{sfAttestationRewardAccount, rewardAccount};
573 o[sfWasLockingChainSend] = wasLockingChainSend;
574 o[sfDestination] = STAccount{sfDestination, dst};
575
576 return o;
577}
578
581 : amount{att.sendingAmount}
582 , rewardAmount(att.rewardAmount)
583 , wasLockingChainSend{att.wasLockingChainSend}
584 , dst{att.toCreate}
585{
586}
587
598
599bool
601{
602 return std::tie(
603 lhs.keyAccount,
604 lhs.publicKey,
605 lhs.amount,
606 lhs.rewardAmount,
607 lhs.rewardAccount,
609 lhs.dst) ==
610 std::tie(
611 rhs.keyAccount,
612 rhs.publicKey,
613 rhs.amount,
614 rhs.rewardAmount,
615 rhs.rewardAccount,
617 rhs.dst);
618}
619
620//------------------------------------------------------------------------------
621//
622template <class TAttestation>
625 : attestations_{std::move(atts)}
626{
627}
628
629template <class TAttestation>
630typename XChainAttestationsBase<TAttestation>::AttCollection::const_iterator
632{
633 return attestations_.begin();
634}
635
636template <class TAttestation>
639{
640 return attestations_.end();
641}
642
643template <class TAttestation>
646{
647 return attestations_.begin();
648}
649
650template <class TAttestation>
653{
654 return attestations_.end();
655}
656
657template <class TAttestation>
659{
660 if (!v.isObject())
661 {
662 Throw<std::runtime_error>(
663 "XChainAttestationsBase can only be specified with an 'object' "
664 "Json value");
665 }
666
667 attestations_ = [&] {
668 auto const jAtts = v[jss::attestations];
669
670 if (jAtts.size() > maxAttestations)
671 Throw<std::runtime_error>("XChainAttestationsBase exceeded max number of attestations");
672
674 r.reserve(jAtts.size());
675 for (auto const& a : jAtts)
676 r.emplace_back(a);
677 return r;
678 }();
679}
680
681template <class TAttestation>
683{
684 if (arr.size() > maxAttestations)
685 Throw<std::runtime_error>("XChainAttestationsBase exceeded max number of attestations");
686
687 attestations_.reserve(arr.size());
688 for (auto const& o : arr)
689 attestations_.emplace_back(o);
690}
691
692template <class TAttestation>
695{
696 STArray r{TAttestation::ArrayFieldName, attestations_.size()};
697 for (auto const& e : attestations_)
698 r.emplace_back(e.toSTObject());
699 return r;
700}
701
704
705} // namespace xrpl
Represents a JSON value.
Definition json_value.h:130
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:16
A public key.
Definition PublicKey.h:42
Identifies fields.
Definition SField.h:126
size_type size() const
Definition STArray.h:225
static STObject makeInnerObject(SField const &name)
Definition STObject.cpp:73
A secret key.
Definition SecretKey.h:18
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:5
STL namespace.
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:5
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig) noexcept
Verify a signature on a message.
bool isLegalNet(STAmount const &value)
Definition STAmount.h:584
SField const sfGeneric
constexpr bool operator==(base_uint< Bits, Tag > const &lhs, base_uint< Bits, Tag > const &rhs)
Definition base_uint.h:557
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:215
T reserve(T... args)
AttestationBase(AccountID attestationSignerAccount_, PublicKey const &publicKey_, Buffer signature_, AccountID const &sendingAccount_, STAmount const &sendingAmount_, AccountID const &rewardAccount_, bool wasLockingChainSend_)
bool verify(STXChainBridge const &bridge) const
static bool equalHelper(AttestationBase const &lhs, AttestationBase const &rhs)
static bool sameEventHelper(AttestationBase const &lhs, AttestationBase const &rhs)
virtual std::vector< std::uint8_t > message(STXChainBridge const &bridge) const =0
bool sameEvent(AttestationClaim const &rhs) const
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)
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_)
bool sameEvent(AttestationCreateAccount const &rhs) const
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)
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)
AttestationMatch match(MatchFields const &rhs) const
friend bool operator==(XChainCreateAccountAttestation const &lhs, XChainCreateAccountAttestation const &rhs)
AttestationMatch match(MatchFields const &rhs) const
XChainCreateAccountAttestation(AccountID const &keyAccount_, PublicKey const &publicKey_, STAmount const &amount_, STAmount const &rewardAmount_, AccountID const &rewardAccount_, bool wasLockingChainSend_, AccountID const &dst_)
T tie(T... args)
T value(T... args)