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>
26namespace Attestations {
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_}
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])}
103 sfAttestationSignerAccount)}
105 , signature{
Json::getOrThrow<
Buffer>(v, sfSignature)}
107 , sendingAmount{
Json::getOrThrow<
STAmount>(v, sfAmount)}
108 , rewardAccount{
Json::getOrThrow<
AccountID>(v, sfAttestationRewardAccount)}
109 , wasLockingChainSend{
Json::getOrThrow<bool>(v, sfWasLockingChainSend)}
132 bool wasLockingChainSend_,
136 attestationSignerAccount_,
138 std::move(signature_),
142 wasLockingChainSend_)
156 bool wasLockingChainSend_,
160 attestationSignerAccount_,
166 wasLockingChainSend_,
170 auto const toSign =
message(bridge);
175 :
AttestationBase(o), claimID{o[sfXChainClaimID]}, dst{o[~sfDestination]}
181 , claimID{
Json::getOrThrow<
std::uint64_t>(v, sfXChainClaimID)}
183 if (v.
isMember(sfDestination.getJsonName()))
184 dst = Json::getOrThrow<AccountID>(v, sfDestination);
195 o[sfDestination] = *
dst;
205 bool wasLockingChainSend,
214 o[sfDestination] = *
dst;
218 o[sfXChainBridge] = bridge;
261 , createCount{o[sfXChainAccountCreateCount]}
262 , toCreate{o[sfDestination]}
263 , rewardAmount{o[sfSignatureReward]}
269 , createCount{
Json::getOrThrow<
std::uint64_t>(
271 sfXChainAccountCreateCount)}
273 , rewardAmount{
Json::getOrThrow<
STAmount>(v, sfSignatureReward)}
285 bool wasLockingChainSend_,
289 attestationSignerAccount_,
291 std::move(signature_),
295 wasLockingChainSend_)
296 , createCount{createCount_}
297 , toCreate{toCreate_}
298 , rewardAmount{rewardAmount_}
311 bool wasLockingChainSend_,
315 attestationSignerAccount_,
322 wasLockingChainSend_,
326 auto const toSign =
message(bridge);
334 sfXChainCreateAccountAttestationCollectionElement);
351 bool wasLockingChainSend,
360 o[sfDestination] = dst;
364 o[sfXChainBridge] = bridge;
402 AttestationCreateAccount
const& lhs,
403 AttestationCreateAccount
const& rhs)
406 std::tie(lhs.createCount, lhs.toCreate, lhs.rewardAmount) ==
407 std::tie(rhs.createCount, rhs.toCreate, rhs.rewardAmount);
414 sfXChainCreateAccountAttestations};
421 bool wasLockingChainSend_,
423 : keyAccount(keyAccount_)
424 , publicKey(publicKey_)
425 , amount(sfAmount, amount_)
426 , rewardAccount(rewardAccount_)
427 , wasLockingChainSend(wasLockingChainSend_)
437 bool wasLockingChainSend_,
443 rewardAccount_.value(),
444 wasLockingChainSend_,
449XChainClaimAttestation::XChainClaimAttestation(
STObject const& o)
451 o[sfAttestationSignerAccount],
454 o[sfAttestationRewardAccount],
455 o[sfWasLockingChainSend] != 0,
456 o[~sfDestination]} {};
464 Json::getOrThrow<bool>(v, sfWasLockingChainSend),
467 if (v.
isMember(sfDestination.getJsonName()))
468 dst = Json::getOrThrow<AccountID>(v, sfDestination);
474 claimAtt.attestationSignerAccount,
476 claimAtt.sendingAmount,
477 claimAtt.rewardAccount,
478 claimAtt.wasLockingChainSend,
487 o[sfAttestationSignerAccount] =
491 o[sfAttestationRewardAccount] =
520 : amount{att.sendingAmount}
521 , wasLockingChainSend{att.wasLockingChainSend}
546 bool wasLockingChainSend_,
550 ,
amount(sfAmount, amount_)
551 , rewardAmount(sfSignatureReward, rewardAmount_)
561 o[sfAttestationSignerAccount],
564 o[sfSignatureReward],
565 o[sfAttestationRewardAccount],
566 o[sfWasLockingChainSend] != 0,
567 o[sfDestination]} {};
569XChainCreateAccountAttestation ::XChainCreateAccountAttestation(
577 Json::getOrThrow<bool>(v, sfWasLockingChainSend),
585 createAtt.attestationSignerAccount,
587 createAtt.sendingAmount,
588 createAtt.rewardAmount,
589 createAtt.rewardAccount,
590 createAtt.wasLockingChainSend,
600 o[sfAttestationSignerAccount] =
605 o[sfAttestationRewardAccount] =
615 : amount{att.sendingAmount}
616 , rewardAmount(att.rewardAmount)
617 , wasLockingChainSend{att.wasLockingChainSend}
659template <
class TAttestation>
662 : attestations_{
std::move(atts)}
666template <
class TAttestation>
667typename XChainAttestationsBase<TAttestation>::AttCollection::const_iterator
670 return attestations_.begin();
673template <
class TAttestation>
677 return attestations_.
end();
680template <
class TAttestation>
684 return attestations_.
begin();
687template <
class TAttestation>
691 return attestations_.
end();
694template <
class TAttestation>
700 Throw<std::runtime_error>(
701 "XChainAttestationsBase can only be specified with an 'object' "
705 attestations_ = [&] {
706 auto const jAtts = v[jss::attestations];
708 if (jAtts.size() > maxAttestations)
709 Throw<std::runtime_error>(
710 "XChainAttestationsBase exceeded max number of attestations");
714 for (
auto const& a : jAtts)
720template <
class TAttestation>
723 if (arr.
size() > maxAttestations)
724 Throw<std::runtime_error>(
725 "XChainAttestationsBase exceeded max number of attestations");
727 attestations_.reserve(arr.
size());
728 for (
auto const& o : arr)
729 attestations_.emplace_back(o);
732template <
class TAttestation>
736 STArray r{TAttestation::ArrayFieldName, attestations_.
size()};
737 for (
auto const& e : attestations_)
738 r.emplace_back(e.toSTObject());
bool isMember(char const *key) const
Return true if the object has a member named key.
Like std::vector<char> but better.
static STObject makeInnerObject(SField const &name)
XChainAttestationsBase()=default
AttCollection::const_iterator end() const
AttCollection::const_iterator begin() const
STArray toSTArray() const
T emplace_back(T... args)
JSON (JavaScript Object Notation).
bool operator==(AttestationClaim const &lhs, AttestationClaim const &rhs)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
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)
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)
constexpr bool operator==(base_uint< Bits, Tag > const &lhs, base_uint< Bits, Tag > const &rhs)
static bool equalHelper(AttestationBase const &lhs, AttestationBase const &rhs)
virtual std::vector< std::uint8_t > message(STXChainBridge const &bridge) const =0
AccountID attestationSignerAccount
void addHelper(STObject &o) const
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 validAmounts() const
std::optional< AccountID > dst
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_)
STObject toSTObject() 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)
AttestationCreateAccount(STObject const &o)
bool validAmounts() 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::uint64_t createCount
STObject toSTObject() const
bool sameEvent(AttestationCreateAccount const &rhs) const
std::optional< AccountID > dst
MatchFields(TSignedAttestation const &att)
STObject toSTObject() 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)
MatchFields(TSignedAttestation const &att)
static SField const & ArrayFieldName
STObject toSTObject() const
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)