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{
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) && tie(claimID, dst) == tie(rhs.claimID, rhs.dst);
231}
232
233bool
235{
236 return AttestationClaim::equalHelper(lhs, rhs) && tie(lhs.claimID, lhs.dst) == tie(rhs.claimID, rhs.dst);
237}
238
240 : AttestationBase(o)
241 , createCount{o[sfXChainAccountCreateCount]}
242 , toCreate{o[sfDestination]}
243 , rewardAmount{o[sfSignatureReward]}
244{
245}
246
248 : AttestationBase{v}
249 , createCount{Json::getOrThrow<std::uint64_t>(v, sfXChainAccountCreateCount)}
250 , toCreate{Json::getOrThrow<AccountID>(v, sfDestination)}
251 , rewardAmount{Json::getOrThrow<STAmount>(v, sfSignatureReward)}
252{
253}
254
256 AccountID attestationSignerAccount_,
257 PublicKey const& publicKey_,
258 Buffer signature_,
259 AccountID const& sendingAccount_,
260 STAmount const& sendingAmount_,
261 STAmount const& rewardAmount_,
262 AccountID const& rewardAccount_,
263 bool wasLockingChainSend_,
264 std::uint64_t createCount_,
265 AccountID const& toCreate_)
267 attestationSignerAccount_,
268 publicKey_,
269 std::move(signature_),
270 sendingAccount_,
271 sendingAmount_,
272 rewardAccount_,
273 wasLockingChainSend_)
274 , createCount{createCount_}
275 , toCreate{toCreate_}
276 , rewardAmount{rewardAmount_}
277{
278}
279
281 STXChainBridge const& bridge,
282 AccountID attestationSignerAccount_,
283 PublicKey const& publicKey_,
284 SecretKey const& secretKey_,
285 AccountID const& sendingAccount_,
286 STAmount const& sendingAmount_,
287 STAmount const& rewardAmount_,
288 AccountID const& rewardAccount_,
289 bool wasLockingChainSend_,
290 std::uint64_t createCount_,
291 AccountID const& toCreate_)
293 attestationSignerAccount_,
294 publicKey_,
295 Buffer{},
296 sendingAccount_,
297 sendingAmount_,
298 rewardAmount_,
299 rewardAccount_,
300 wasLockingChainSend_,
301 createCount_,
302 toCreate_}
303{
304 auto const toSign = message(bridge);
305 signature = sign(publicKey_, secretKey_, makeSlice(toSign));
306}
307
310{
311 STObject o = STObject::makeInnerObject(sfXChainCreateAccountAttestationCollectionElement);
312 addHelper(o);
313
314 o[sfXChainAccountCreateCount] = createCount;
315 o[sfDestination] = toCreate;
316 o[sfSignatureReward] = rewardAmount;
317
318 return o;
319}
320
323 STXChainBridge const& bridge,
324 AccountID const& sendingAccount,
325 STAmount const& sendingAmount,
326 STAmount const& rewardAmount,
327 AccountID const& rewardAccount,
328 bool wasLockingChainSend,
329 std::uint64_t createCount,
330 AccountID const& dst)
331{
333 // Serialize in SField order to make python serializers easier to write
334 o[sfXChainAccountCreateCount] = createCount;
335 o[sfAmount] = sendingAmount;
336 o[sfSignatureReward] = rewardAmount;
337 o[sfDestination] = dst;
338 o[sfOtherChainSource] = sendingAccount;
339 o[sfAttestationRewardAccount] = rewardAccount;
340 o[sfWasLockingChainSend] = wasLockingChainSend ? 1 : 0;
341 o[sfXChainBridge] = bridge;
342
343 Serializer s;
344 o.add(s);
345
346 return std::move(s.modData());
347}
348
355
356bool
361
362bool
368
369bool
371{
373 std::tie(lhs.createCount, lhs.toCreate, lhs.rewardAmount) ==
375}
376
377} // namespace Attestations
378
379SField const& XChainClaimAttestation::ArrayFieldName{sfXChainClaimAttestations};
380SField const& XChainCreateAccountAttestation::ArrayFieldName{sfXChainCreateAccountAttestations};
381
383 AccountID const& keyAccount_,
384 PublicKey const& publicKey_,
385 STAmount const& amount_,
386 AccountID const& rewardAccount_,
387 bool wasLockingChainSend_,
388 std::optional<AccountID> const& dst_)
389 : keyAccount(keyAccount_)
390 , publicKey(publicKey_)
391 , amount(sfAmount, amount_)
392 , rewardAccount(rewardAccount_)
393 , wasLockingChainSend(wasLockingChainSend_)
394 , dst(dst_)
395{
396}
397
399 STAccount const& keyAccount_,
400 PublicKey const& publicKey_,
401 STAmount const& amount_,
402 STAccount const& rewardAccount_,
403 bool wasLockingChainSend_,
404 std::optional<STAccount> const& dst_)
406 keyAccount_.value(),
407 publicKey_,
408 amount_,
409 rewardAccount_.value(),
410 wasLockingChainSend_,
411 dst_ ? std::optional<AccountID>{dst_->value()} : std::nullopt}
412{
413}
414
415XChainClaimAttestation::XChainClaimAttestation(STObject const& o)
417 o[sfAttestationSignerAccount],
418 PublicKey{o[sfPublicKey]},
419 o[sfAmount],
420 o[sfAttestationRewardAccount],
421 o[sfWasLockingChainSend] != 0,
422 o[~sfDestination]} {};
423
426 Json::getOrThrow<AccountID>(v, sfAttestationSignerAccount),
427 Json::getOrThrow<PublicKey>(v, sfPublicKey),
428 Json::getOrThrow<STAmount>(v, sfAmount),
429 Json::getOrThrow<AccountID>(v, sfAttestationRewardAccount),
430 Json::getOrThrow<bool>(v, sfWasLockingChainSend),
431 std::nullopt}
432{
433 if (v.isMember(sfDestination.getJsonName()))
434 dst = Json::getOrThrow<AccountID>(v, sfDestination);
435};
436
439 claimAtt.attestationSignerAccount,
440 claimAtt.publicKey,
441 claimAtt.sendingAmount,
442 claimAtt.rewardAccount,
443 claimAtt.wasLockingChainSend,
444 claimAtt.dst}
445{
446}
447
450{
451 STObject o = STObject::makeInnerObject(sfXChainClaimProofSig);
452 o[sfAttestationSignerAccount] = STAccount{sfAttestationSignerAccount, keyAccount};
453 o[sfPublicKey] = publicKey;
454 o[sfAmount] = STAmount{sfAmount, amount};
455 o[sfAttestationRewardAccount] = STAccount{sfAttestationRewardAccount, rewardAccount};
456 o[sfWasLockingChainSend] = wasLockingChainSend;
457 if (dst)
458 o[sfDestination] = STAccount{sfDestination, *dst};
459 return o;
460}
461
462bool
464{
465 return std::tie(lhs.keyAccount, lhs.publicKey, lhs.amount, lhs.rewardAccount, lhs.wasLockingChainSend, lhs.dst) ==
467}
468
470 : amount{att.sendingAmount}, wasLockingChainSend{att.wasLockingChainSend}, dst{att.dst}
471{
472}
473
483
484//------------------------------------------------------------------------------
485
487 AccountID const& keyAccount_,
488 PublicKey const& publicKey_,
489 STAmount const& amount_,
490 STAmount const& rewardAmount_,
491 AccountID const& rewardAccount_,
492 bool wasLockingChainSend_,
493 AccountID const& dst_)
494 : keyAccount(keyAccount_)
495 , publicKey(publicKey_)
496 , amount(sfAmount, amount_)
497 , rewardAmount(sfSignatureReward, rewardAmount_)
498 , rewardAccount(rewardAccount_)
499 , wasLockingChainSend(wasLockingChainSend_)
500 , dst(dst_)
501{
502}
503
506 o[sfAttestationSignerAccount],
507 PublicKey{o[sfPublicKey]},
508 o[sfAmount],
509 o[sfSignatureReward],
510 o[sfAttestationRewardAccount],
511 o[sfWasLockingChainSend] != 0,
512 o[sfDestination]} {};
513
514XChainCreateAccountAttestation ::XChainCreateAccountAttestation(Json::Value const& v)
516 Json::getOrThrow<AccountID>(v, sfAttestationSignerAccount),
517 Json::getOrThrow<PublicKey>(v, sfPublicKey),
518 Json::getOrThrow<STAmount>(v, sfAmount),
519 Json::getOrThrow<STAmount>(v, sfSignatureReward),
520 Json::getOrThrow<AccountID>(v, sfAttestationRewardAccount),
521 Json::getOrThrow<bool>(v, sfWasLockingChainSend),
522 Json::getOrThrow<AccountID>(v, sfDestination)}
523{
524}
525
529 createAtt.attestationSignerAccount,
530 createAtt.publicKey,
531 createAtt.sendingAmount,
532 createAtt.rewardAmount,
533 createAtt.rewardAccount,
534 createAtt.wasLockingChainSend,
535 createAtt.toCreate}
536{
537}
538
541{
542 STObject o = STObject::makeInnerObject(sfXChainCreateAccountProofSig);
543
544 o[sfAttestationSignerAccount] = STAccount{sfAttestationSignerAccount, keyAccount};
545 o[sfPublicKey] = publicKey;
546 o[sfAmount] = STAmount{sfAmount, amount};
547 o[sfSignatureReward] = STAmount{sfSignatureReward, rewardAmount};
548 o[sfAttestationRewardAccount] = STAccount{sfAttestationRewardAccount, rewardAccount};
549 o[sfWasLockingChainSend] = wasLockingChainSend;
550 o[sfDestination] = STAccount{sfDestination, dst};
551
552 return o;
553}
554
556 : amount{att.sendingAmount}
557 , rewardAmount(att.rewardAmount)
558 , wasLockingChainSend{att.wasLockingChainSend}
559 , dst{att.toCreate}
560{
561}
562
573
574bool
576{
577 return std::tie(
578 lhs.keyAccount,
579 lhs.publicKey,
580 lhs.amount,
581 lhs.rewardAmount,
582 lhs.rewardAccount,
584 lhs.dst) ==
585 std::tie(
586 rhs.keyAccount,
587 rhs.publicKey,
588 rhs.amount,
589 rhs.rewardAmount,
590 rhs.rewardAccount,
592 rhs.dst);
593}
594
595//------------------------------------------------------------------------------
596//
597template <class TAttestation>
599 : attestations_{std::move(atts)}
600{
601}
602
603template <class TAttestation>
604typename XChainAttestationsBase<TAttestation>::AttCollection::const_iterator
606{
607 return attestations_.begin();
608}
609
610template <class TAttestation>
613{
614 return attestations_.end();
615}
616
617template <class TAttestation>
620{
621 return attestations_.begin();
622}
623
624template <class TAttestation>
627{
628 return attestations_.end();
629}
630
631template <class TAttestation>
633{
634 if (!v.isObject())
635 {
636 Throw<std::runtime_error>(
637 "XChainAttestationsBase can only be specified with an 'object' "
638 "Json value");
639 }
640
641 attestations_ = [&] {
642 auto const jAtts = v[jss::attestations];
643
644 if (jAtts.size() > maxAttestations)
645 Throw<std::runtime_error>("XChainAttestationsBase exceeded max number of attestations");
646
648 r.reserve(jAtts.size());
649 for (auto const& a : jAtts)
650 r.emplace_back(a);
651 return r;
652 }();
653}
654
655template <class TAttestation>
657{
658 if (arr.size() > maxAttestations)
659 Throw<std::runtime_error>("XChainAttestationsBase exceeded max number of attestations");
660
661 attestations_.reserve(arr.size());
662 for (auto const& o : arr)
663 attestations_.emplace_back(o);
664}
665
666template <class TAttestation>
669{
670 STArray r{TAttestation::ArrayFieldName, attestations_.size()};
671 for (auto const& e : attestations_)
672 r.emplace_back(e.toSTObject());
673 return r;
674}
675
678
679} // 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:223
static STObject makeInnerObject(SField const &name)
Definition STObject.cpp:72
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:566
SField const sfGeneric
constexpr bool operator==(base_uint< Bits, Tag > const &lhs, base_uint< Bits, Tag > const &rhs)
Definition base_uint.h:552
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:213
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)