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_}
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])}
93 : attestationSignerAccount{
Json::getOrThrow<
AccountID>(v, sfAttestationSignerAccount)}
95 , signature{
Json::getOrThrow<
Buffer>(v, sfSignature)}
98 , rewardAccount{
Json::getOrThrow<
AccountID>(v, sfAttestationRewardAccount)}
99 , wasLockingChainSend{
Json::getOrThrow<bool>(v, sfWasLockingChainSend)}
122 bool wasLockingChainSend_,
126 attestationSignerAccount_,
128 std::move(signature_),
132 wasLockingChainSend_)
146 bool wasLockingChainSend_,
150 attestationSignerAccount_,
156 wasLockingChainSend_,
160 auto const toSign =
message(bridge);
165 :
AttestationBase(o), claimID{o[sfXChainClaimID]}, dst{o[~sfDestination]}
172 if (v.
isMember(sfDestination.getJsonName()))
173 dst = Json::getOrThrow<AccountID>(v, sfDestination);
183 o[sfDestination] = *
dst;
193 bool wasLockingChainSend,
202 o[sfDestination] = *
dst;
206 o[sfXChainBridge] = bridge;
241 , createCount{o[sfXChainAccountCreateCount]}
242 , toCreate{o[sfDestination]}
243 , rewardAmount{o[sfSignatureReward]}
249 , createCount{
Json::getOrThrow<
std::uint64_t>(v, sfXChainAccountCreateCount)}
251 , rewardAmount{
Json::getOrThrow<
STAmount>(v, sfSignatureReward)}
263 bool wasLockingChainSend_,
267 attestationSignerAccount_,
269 std::move(signature_),
273 wasLockingChainSend_)
274 , createCount{createCount_}
275 , toCreate{toCreate_}
276 , rewardAmount{rewardAmount_}
289 bool wasLockingChainSend_,
293 attestationSignerAccount_,
300 wasLockingChainSend_,
304 auto const toSign =
message(bridge);
328 bool wasLockingChainSend,
337 o[sfDestination] = dst;
341 o[sfXChainBridge] = bridge;
387 bool wasLockingChainSend_,
389 : keyAccount(keyAccount_)
390 , publicKey(publicKey_)
391 , amount(sfAmount, amount_)
392 , rewardAccount(rewardAccount_)
393 , wasLockingChainSend(wasLockingChainSend_)
403 bool wasLockingChainSend_,
409 rewardAccount_.value(),
410 wasLockingChainSend_,
415XChainClaimAttestation::XChainClaimAttestation(
STObject const& o)
417 o[sfAttestationSignerAccount],
420 o[sfAttestationRewardAccount],
421 o[sfWasLockingChainSend] != 0,
422 o[~sfDestination]} {};
430 Json::getOrThrow<bool>(v, sfWasLockingChainSend),
433 if (v.
isMember(sfDestination.getJsonName()))
434 dst = Json::getOrThrow<AccountID>(v, sfDestination);
439 claimAtt.attestationSignerAccount,
441 claimAtt.sendingAmount,
442 claimAtt.rewardAccount,
443 claimAtt.wasLockingChainSend,
470 : amount{att.sendingAmount}, wasLockingChainSend{att.wasLockingChainSend}, dst{att.dst}
492 bool wasLockingChainSend_,
496 ,
amount(sfAmount, amount_)
497 , rewardAmount(sfSignatureReward, rewardAmount_)
506 o[sfAttestationSignerAccount],
509 o[sfSignatureReward],
510 o[sfAttestationRewardAccount],
511 o[sfWasLockingChainSend] != 0,
512 o[sfDestination]} {};
514XChainCreateAccountAttestation ::XChainCreateAccountAttestation(
Json::Value const& v)
521 Json::getOrThrow<bool>(v, sfWasLockingChainSend),
529 createAtt.attestationSignerAccount,
531 createAtt.sendingAmount,
532 createAtt.rewardAmount,
533 createAtt.rewardAccount,
534 createAtt.wasLockingChainSend,
556 : amount{att.sendingAmount}
557 , rewardAmount(att.rewardAmount)
558 , wasLockingChainSend{att.wasLockingChainSend}
597template <
class TAttestation>
599 : attestations_{
std::move(atts)}
603template <
class TAttestation>
604typename XChainAttestationsBase<TAttestation>::AttCollection::const_iterator
607 return attestations_.begin();
610template <
class TAttestation>
614 return attestations_.
end();
617template <
class TAttestation>
621 return attestations_.
begin();
624template <
class TAttestation>
628 return attestations_.
end();
631template <
class TAttestation>
636 Throw<std::runtime_error>(
637 "XChainAttestationsBase can only be specified with an 'object' "
641 attestations_ = [&] {
642 auto const jAtts = v[jss::attestations];
644 if (jAtts.size() > maxAttestations)
645 Throw<std::runtime_error>(
"XChainAttestationsBase exceeded max number of attestations");
649 for (
auto const& a : jAtts)
655template <
class TAttestation>
658 if (arr.
size() > maxAttestations)
659 Throw<std::runtime_error>(
"XChainAttestationsBase exceeded max number of attestations");
661 attestations_.reserve(arr.
size());
662 for (
auto const& o : arr)
663 attestations_.emplace_back(o);
666template <
class TAttestation>
670 STArray r{TAttestation::ArrayFieldName, attestations_.
size()};
671 for (
auto const& e : attestations_)
672 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)
STArray toSTArray() const
AttCollection::const_iterator end() const
AttCollection::const_iterator begin() const
XChainAttestationsBase()=default
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) noexcept
Verify a signature on a message.
bool isLegalNet(STAmount const &value)
constexpr bool operator==(base_uint< Bits, Tag > const &lhs, base_uint< Bits, Tag > const &rhs)
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)
AccountID attestationSignerAccount
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
void addHelper(STObject &o) const
bool sameEvent(AttestationClaim const &rhs) const
bool validAmounts() const
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)
std::optional< AccountID > 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 validAmounts() const
STObject toSTObject() const
bool sameEvent(AttestationCreateAccount const &rhs) const
std::uint64_t createCount
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)
AttestationCreateAccount(STObject const &o)
MatchFields(TSignedAttestation const &att)
std::optional< AccountID > 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)
STObject toSTObject() const
AttestationMatch match(MatchFields const &rhs) const
MatchFields(TSignedAttestation const &att)
static SField const & ArrayFieldName
STObject toSTObject() 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_)