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;
243 , createCount{o[sfXChainAccountCreateCount]}
244 , toCreate{o[sfDestination]}
245 , rewardAmount{o[sfSignatureReward]}
251 , createCount{
Json::getOrThrow<
std::uint64_t>(v, sfXChainAccountCreateCount)}
253 , rewardAmount{
Json::getOrThrow<
STAmount>(v, sfSignatureReward)}
265 bool wasLockingChainSend_,
269 attestationSignerAccount_,
271 std::move(signature_),
275 wasLockingChainSend_)
276 , createCount{createCount_}
277 , toCreate{toCreate_}
278 , rewardAmount{rewardAmount_}
291 bool wasLockingChainSend_,
295 attestationSignerAccount_,
302 wasLockingChainSend_,
306 auto const toSign =
message(bridge);
330 bool wasLockingChainSend,
339 o[sfDestination] = dst;
343 o[sfXChainBridge] = bridge;
397 bool wasLockingChainSend_,
399 : keyAccount(keyAccount_)
400 , publicKey(publicKey_)
401 , amount(sfAmount, amount_)
402 , rewardAccount(rewardAccount_)
403 , wasLockingChainSend(wasLockingChainSend_)
413 bool wasLockingChainSend_,
419 rewardAccount_.value(),
420 wasLockingChainSend_,
425XChainClaimAttestation::XChainClaimAttestation(
STObject const& o)
427 o[sfAttestationSignerAccount],
430 o[sfAttestationRewardAccount],
431 o[sfWasLockingChainSend] != 0,
432 o[~sfDestination]} {};
440 Json::getOrThrow<bool>(v, sfWasLockingChainSend),
443 if (v.
isMember(sfDestination.getJsonName()))
444 dst = Json::getOrThrow<AccountID>(v, sfDestination);
450 claimAtt.attestationSignerAccount,
452 claimAtt.sendingAmount,
453 claimAtt.rewardAccount,
454 claimAtt.wasLockingChainSend,
494 : amount{att.sendingAmount}, wasLockingChainSend{att.wasLockingChainSend}, dst{att.dst}
516 bool wasLockingChainSend_,
520 ,
amount(sfAmount, amount_)
521 , rewardAmount(sfSignatureReward, rewardAmount_)
530 o[sfAttestationSignerAccount],
533 o[sfSignatureReward],
534 o[sfAttestationRewardAccount],
535 o[sfWasLockingChainSend] != 0,
536 o[sfDestination]} {};
538XChainCreateAccountAttestation ::XChainCreateAccountAttestation(
Json::Value const& v)
545 Json::getOrThrow<bool>(v, sfWasLockingChainSend),
553 createAtt.attestationSignerAccount,
555 createAtt.sendingAmount,
556 createAtt.rewardAmount,
557 createAtt.rewardAccount,
558 createAtt.wasLockingChainSend,
581 : amount{att.sendingAmount}
582 , rewardAmount(att.rewardAmount)
583 , wasLockingChainSend{att.wasLockingChainSend}
622template <
class TAttestation>
625 : attestations_{
std::move(atts)}
629template <
class TAttestation>
630typename XChainAttestationsBase<TAttestation>::AttCollection::const_iterator
633 return attestations_.begin();
636template <
class TAttestation>
640 return attestations_.
end();
643template <
class TAttestation>
647 return attestations_.
begin();
650template <
class TAttestation>
654 return attestations_.
end();
657template <
class TAttestation>
662 Throw<std::runtime_error>(
663 "XChainAttestationsBase can only be specified with an 'object' "
667 attestations_ = [&] {
668 auto const jAtts = v[jss::attestations];
670 if (jAtts.size() > maxAttestations)
671 Throw<std::runtime_error>(
"XChainAttestationsBase exceeded max number of attestations");
675 for (
auto const& a : jAtts)
681template <
class TAttestation>
684 if (arr.
size() > maxAttestations)
685 Throw<std::runtime_error>(
"XChainAttestationsBase exceeded max number of attestations");
687 attestations_.reserve(arr.
size());
688 for (
auto const& o : arr)
689 attestations_.emplace_back(o);
692template <
class TAttestation>
696 STArray r{TAttestation::ArrayFieldName, attestations_.
size()};
697 for (
auto const& e : attestations_)
698 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_)