xrpld
Loading...
Searching...
No Matches
XChainAttestations.cpp
1#include <xrpl/protocol/XChainAttestations.h>
2
3#include <xrpl/basics/Buffer.h>
4#include <xrpl/basics/Slice.h>
5#include <xrpl/basics/contract.h>
6#include <xrpl/json/json_value.h>
7#include <xrpl/protocol/AccountID.h>
8#include <xrpl/protocol/PublicKey.h>
9#include <xrpl/protocol/SField.h>
10#include <xrpl/protocol/STAccount.h>
11#include <xrpl/protocol/STAmount.h>
12#include <xrpl/protocol/STArray.h>
13#include <xrpl/protocol/STObject.h>
14#include <xrpl/protocol/SecretKey.h>
15#include <xrpl/protocol/Serializer.h>
16#include <xrpl/protocol/json_get_or_throw.h>
17#include <xrpl/protocol/jss.h>
18
19#include <cstdint>
20#include <optional>
21#include <stdexcept>
22#include <tuple>
23#include <utility>
24#include <vector>
25
26namespace xrpl {
27namespace Attestations {
28
46
47bool
67
68bool
74
75bool
77{
78 std::vector<std::uint8_t> const msg = message(bridge);
80}
81
83 : attestationSignerAccount{o[sfAttestationSignerAccount]}
84 , publicKey{o[sfPublicKey]}
85 , signature{o[sfSignature]}
86 , sendingAccount{o[sfAccount]}
87 , sendingAmount{o[sfAmount]}
88 , rewardAccount{o[sfAttestationRewardAccount]}
89 , wasLockingChainSend{bool(o[sfWasLockingChainSend])}
90{
91}
92
94 : attestationSignerAccount{json::getOrThrow<AccountID>(v, sfAttestationSignerAccount)}
95 , publicKey{json::getOrThrow<PublicKey>(v, sfPublicKey)}
96 , signature{json::getOrThrow<Buffer>(v, sfSignature)}
97 , sendingAccount{json::getOrThrow<AccountID>(v, sfAccount)}
98 , sendingAmount{json::getOrThrow<STAmount>(v, sfAmount)}
99 , rewardAccount{json::getOrThrow<AccountID>(v, sfAttestationRewardAccount)}
100 , wasLockingChainSend{json::getOrThrow<bool>(v, sfWasLockingChainSend)}
101{
102}
103
104void
106{
107 o[sfAttestationSignerAccount] = attestationSignerAccount;
108 o[sfPublicKey] = publicKey;
109 o[sfSignature] = signature;
110 o[sfAmount] = sendingAmount;
111 o[sfAccount] = sendingAccount;
112 o[sfAttestationRewardAccount] = rewardAccount;
113 o[sfWasLockingChainSend] = wasLockingChainSend;
114}
115
138
140 STXChainBridge const& bridge,
142 PublicKey const& publicKey,
143 SecretKey const& secretKey,
145 STAmount const& sendingAmount,
148 std::uint64_t claimId,
152 publicKey,
153 Buffer{},
158 claimId,
159 dst}
160{
161 auto const toSign = message(bridge);
162 signature = sign(publicKey, secretKey, makeSlice(toSign));
163}
164
166 : AttestationBase(o), claimID{o[sfXChainClaimID]}, dst{o[~sfDestination]}
167{
168}
169
171 : AttestationBase{v}, claimID{json::getOrThrow<std::uint64_t>(v, sfXChainClaimID)}
172{
173 if (v.isMember(sfDestination.getJsonName()))
174 dst = json::getOrThrow<AccountID>(v, sfDestination);
175}
176
179{
180 STObject o = STObject::makeInnerObject(sfXChainClaimAttestationCollectionElement);
181 addHelper(o);
182 o[sfXChainClaimID] = claimID;
183 if (dst)
184 o[sfDestination] = *dst;
185 return o;
186}
187
190 STXChainBridge const& bridge,
192 STAmount const& sendingAmount,
197{
199 // Serialize in SField order to make python serializers easier to write
200 o[sfXChainClaimID] = claimID;
201 o[sfAmount] = sendingAmount;
202 if (dst)
203 o[sfDestination] = *dst;
204 o[sfOtherChainSource] = sendingAccount;
205 o[sfAttestationRewardAccount] = rewardAccount;
206 o[sfWasLockingChainSend] = wasLockingChainSend ? 1 : 0;
207 o[sfXChainBridge] = bridge;
208
209 Serializer s;
210 o.add(s);
211
212 return std::move(s.modData());
213}
214
221
222bool
227
228bool
230{
231 return AttestationClaim::sameEventHelper(*this, rhs) &&
232 tie(claimID, dst) == tie(rhs.claimID, rhs.dst);
233}
234
235bool
237{
238 return AttestationClaim::equalHelper(lhs, rhs) &&
239 tie(lhs.claimID, lhs.dst) == tie(rhs.claimID, rhs.dst);
240}
241
243 : AttestationBase(o)
244 , createCount{o[sfXChainAccountCreateCount]}
245 , toCreate{o[sfDestination]}
246 , rewardAmount{o[sfSignatureReward]}
247{
248}
249
251 : AttestationBase{v}
252 , createCount{json::getOrThrow<std::uint64_t>(v, sfXChainAccountCreateCount)}
253 , toCreate{json::getOrThrow<AccountID>(v, sfDestination)}
254 , rewardAmount{json::getOrThrow<STAmount>(v, sfSignatureReward)}
255{
256}
257
282
310
313{
314 STObject o = STObject::makeInnerObject(sfXChainCreateAccountAttestationCollectionElement);
315 addHelper(o);
316
317 o[sfXChainAccountCreateCount] = createCount;
318 o[sfDestination] = toCreate;
319 o[sfSignatureReward] = rewardAmount;
320
321 return o;
322}
323
326 STXChainBridge const& bridge,
328 STAmount const& sendingAmount,
329 STAmount const& rewardAmount,
333 AccountID const& dst)
334{
336 // Serialize in SField order to make python serializers easier to write
337 o[sfXChainAccountCreateCount] = createCount;
338 o[sfAmount] = sendingAmount;
339 o[sfSignatureReward] = rewardAmount;
340 o[sfDestination] = dst;
341 o[sfOtherChainSource] = sendingAccount;
342 o[sfAttestationRewardAccount] = rewardAccount;
343 o[sfWasLockingChainSend] = wasLockingChainSend ? 1 : 0;
344 o[sfXChainBridge] = bridge;
345
346 Serializer s;
347 o.add(s);
348
349 return std::move(s.modData());
350}
351
365
366bool
371
372bool
379
380bool
387
388} // namespace Attestations
389
390SField const& XChainClaimAttestation::arrayFieldName{sfXChainClaimAttestations};
391SField const& XChainCreateAccountAttestation::arrayFieldName{sfXChainCreateAccountAttestations};
392
408
410 STAccount const& keyAccount,
411 PublicKey const& publicKey,
412 STAmount const& amount,
417 keyAccount.value(),
418 publicKey,
419 amount,
420 rewardAccount.value(),
422 dst ? std::optional<AccountID>{dst->value()} : std::nullopt}
423{
424}
425
428 o[sfAttestationSignerAccount],
429 PublicKey{o[sfPublicKey]},
430 o[sfAmount],
431 o[sfAttestationRewardAccount],
432 o[sfWasLockingChainSend] != 0,
433 o[~sfDestination]} {};
434
437 json::getOrThrow<AccountID>(v, sfAttestationSignerAccount),
438 json::getOrThrow<PublicKey>(v, sfPublicKey),
439 json::getOrThrow<STAmount>(v, sfAmount),
440 json::getOrThrow<AccountID>(v, sfAttestationRewardAccount),
441 json::getOrThrow<bool>(v, sfWasLockingChainSend),
442 std::nullopt}
443{
444 if (v.isMember(sfDestination.getJsonName()))
445 dst = json::getOrThrow<AccountID>(v, sfDestination);
446};
447
451 claimAtt.attestationSignerAccount,
452 claimAtt.publicKey,
453 claimAtt.sendingAmount,
454 claimAtt.rewardAccount,
455 claimAtt.wasLockingChainSend,
456 claimAtt.dst}
457{
458}
459
462{
463 STObject o = STObject::makeInnerObject(sfXChainClaimProofSig);
464 o[sfAttestationSignerAccount] = STAccount{sfAttestationSignerAccount, keyAccount};
465 o[sfPublicKey] = publicKey;
466 o[sfAmount] = STAmount{sfAmount, amount};
467 o[sfAttestationRewardAccount] = STAccount{sfAttestationRewardAccount, rewardAccount};
468 o[sfWasLockingChainSend] = wasLockingChainSend;
469 if (dst)
470 o[sfDestination] = STAccount{sfDestination, *dst};
471 return o;
472}
473
474bool
476{
477 return std::tie(
478 lhs.keyAccount,
479 lhs.publicKey,
480 lhs.amount,
481 lhs.rewardAccount,
483 lhs.dst) ==
484 std::tie(
485 rhs.keyAccount,
486 rhs.publicKey,
487 rhs.amount,
488 rhs.rewardAccount,
490 rhs.dst);
491}
492
498
508
509//------------------------------------------------------------------------------
510
528
531 o[sfAttestationSignerAccount],
532 PublicKey{o[sfPublicKey]},
533 o[sfAmount],
534 o[sfSignatureReward],
535 o[sfAttestationRewardAccount],
536 o[sfWasLockingChainSend] != 0,
537 o[sfDestination]} {};
538
539XChainCreateAccountAttestation ::XChainCreateAccountAttestation(json::Value const& v)
541 json::getOrThrow<AccountID>(v, sfAttestationSignerAccount),
542 json::getOrThrow<PublicKey>(v, sfPublicKey),
543 json::getOrThrow<STAmount>(v, sfAmount),
544 json::getOrThrow<STAmount>(v, sfSignatureReward),
545 json::getOrThrow<AccountID>(v, sfAttestationRewardAccount),
546 json::getOrThrow<bool>(v, sfWasLockingChainSend),
547 json::getOrThrow<AccountID>(v, sfDestination)}
548{
549}
550
554 createAtt.attestationSignerAccount,
555 createAtt.publicKey,
556 createAtt.sendingAmount,
557 createAtt.rewardAmount,
558 createAtt.rewardAccount,
559 createAtt.wasLockingChainSend,
560 createAtt.toCreate}
561{
562}
563
566{
567 STObject o = STObject::makeInnerObject(sfXChainCreateAccountProofSig);
568
569 o[sfAttestationSignerAccount] = STAccount{sfAttestationSignerAccount, keyAccount};
570 o[sfPublicKey] = publicKey;
571 o[sfAmount] = STAmount{sfAmount, amount};
572 o[sfSignatureReward] = STAmount{sfSignatureReward, rewardAmount};
573 o[sfAttestationRewardAccount] = STAccount{sfAttestationRewardAccount, rewardAccount};
574 o[sfWasLockingChainSend] = wasLockingChainSend;
575 o[sfDestination] = STAccount{sfDestination, dst};
576
577 return o;
578}
579
588
599
600bool
602{
603 return std::tie(
604 lhs.keyAccount,
605 lhs.publicKey,
606 lhs.amount,
607 lhs.rewardAmount,
608 lhs.rewardAccount,
610 lhs.dst) ==
611 std::tie(
612 rhs.keyAccount,
613 rhs.publicKey,
614 rhs.amount,
615 rhs.rewardAmount,
616 rhs.rewardAccount,
618 rhs.dst);
619}
620
621//------------------------------------------------------------------------------
622//
623template <class TAttestation>
626 : attestations_{std::move(atts)}
627{
628}
629
630template <class TAttestation>
631XChainAttestationsBase<TAttestation>::AttCollection::const_iterator
633{
634 return attestations_.begin();
635}
636
637template <class TAttestation>
638XChainAttestationsBase<TAttestation>::AttCollection::const_iterator
643
644template <class TAttestation>
645XChainAttestationsBase<TAttestation>::AttCollection::iterator
650
651template <class TAttestation>
652XChainAttestationsBase<TAttestation>::AttCollection::iterator
657
658template <class TAttestation>
660{
661 if (!v.isObject())
662 {
664 "XChainAttestationsBase can only be specified with an 'object' "
665 "Json value");
666 }
667
668 attestations_ = [&] {
669 auto const jAtts = v[jss::attestations];
670
671 if (jAtts.size() > kMaxAttestations)
672 Throw<std::runtime_error>("XChainAttestationsBase exceeded max number of attestations");
673
675 r.reserve(jAtts.size());
676 for (auto const& a : jAtts)
677 r.emplace_back(a);
678 return r;
679 }();
680}
681
682template <class TAttestation>
684{
685 if (arr.size() > kMaxAttestations)
686 Throw<std::runtime_error>("XChainAttestationsBase exceeded max number of attestations");
687
688 attestations_.reserve(arr.size());
689 for (auto const& o : arr)
690 attestations_.emplace_back(o);
691}
692
693template <class TAttestation>
696{
697 STArray r{TAttestation::arrayFieldName, attestations_.size()};
698 for (auto const& e : attestations_)
699 r.emplaceBack(e.toSTObject());
700 return r;
701}
702
705
706} // 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:130
void emplaceBack(Args &&... args)
Definition STArray.h:198
size_type size() const
Definition STArray.h:240
void add(Serializer &s) const override
Definition STObject.cpp:120
static STObject makeInnerObject(SField const &name)
Definition STObject.cpp:74
A secret key.
Definition SecretKey.h:18
std::vector< TAttestation > AttCollection
AttCollection::const_iterator end() const
static constexpr std::uint32_t kMaxAttestations
AttCollection::const_iterator begin() const
T emplace_back(T... args)
JSON (JavaScript Object Notation).
Definition json_errors.h:5
xrpl::AccountID getOrThrow(json::Value const &v, xrpl::SField const &field)
Definition AccountID.h:111
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
constexpr bool operator==(BaseUInt< Bits, Tag > const &lhs, BaseUInt< Bits, Tag > const &rhs)
Definition base_uint.h:588
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:598
SField const sfGeneric
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:28
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &message)
Generate a signature for a message.
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:49
std::enable_if_t< std::is_same_v< T, char >||std::is_same_v< T, unsigned char >, 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 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
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)
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)
std::optional< AccountID > dst
Attestations::AttestationClaim TSignedAttestation
XChainClaimAttestation(AccountID const &keyAccount, PublicKey const &publicKey, STAmount const &amount, AccountID const &rewardAccount, bool wasLockingChainSend, std::optional< AccountID > const &dst)
static SField const & arrayFieldName
AttestationMatch match(MatchFields const &rhs) const
Attestations::AttestationCreateAccount TSignedAttestation
XChainCreateAccountAttestation(AccountID const &keyAccount, PublicKey const &publicKey, STAmount const &amount, STAmount const &rewardAmount, AccountID const &rewardAccount, bool wasLockingChainSend, AccountID const &dst)
friend bool operator==(XChainCreateAccountAttestation const &lhs, XChainCreateAccountAttestation const &rhs)
AttestationMatch match(MatchFields const &rhs) const
T tie(T... args)