mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-19 18:45:52 +00:00
Per XLS-0095, we are taking steps to rename ripple(d) to xrpl(d). This change specifically removes all copyright notices referencing Ripple, XRPLF, and certain affiliated contributors upon mutual agreement, so the notice in the LICENSE.md file applies throughout. Copyright notices referencing external contributions remain as-is. Duplicate verbiage is also removed.
484 lines
13 KiB
C++
484 lines
13 KiB
C++
#ifndef XRPL_PROTOCOL_STXATTESTATIONS_H_INCLUDED
|
|
#define XRPL_PROTOCOL_STXATTESTATIONS_H_INCLUDED
|
|
|
|
#include <xrpl/basics/Buffer.h>
|
|
#include <xrpl/basics/Expected.h>
|
|
#include <xrpl/protocol/AccountID.h>
|
|
#include <xrpl/protocol/Issue.h>
|
|
#include <xrpl/protocol/PublicKey.h>
|
|
#include <xrpl/protocol/SField.h>
|
|
#include <xrpl/protocol/STBase.h>
|
|
#include <xrpl/protocol/STXChainBridge.h>
|
|
#include <xrpl/protocol/SecretKey.h>
|
|
#include <xrpl/protocol/TER.h>
|
|
|
|
#include <boost/container/flat_set.hpp>
|
|
#include <boost/container/vector.hpp>
|
|
|
|
#include <cstddef>
|
|
#include <vector>
|
|
|
|
namespace ripple {
|
|
|
|
namespace Attestations {
|
|
|
|
struct AttestationBase
|
|
{
|
|
// Account associated with the public key
|
|
AccountID attestationSignerAccount;
|
|
// Public key from the witness server attesting to the event
|
|
PublicKey publicKey;
|
|
// Signature from the witness server attesting to the event
|
|
Buffer signature;
|
|
// Account on the sending chain that triggered the event (sent the
|
|
// transaction)
|
|
AccountID sendingAccount;
|
|
// Amount transfered on the sending chain
|
|
STAmount sendingAmount;
|
|
// Account on the destination chain that collects a share of the attestation
|
|
// reward
|
|
AccountID rewardAccount;
|
|
// Amount was transfered on the locking chain
|
|
bool wasLockingChainSend;
|
|
|
|
explicit AttestationBase(
|
|
AccountID attestationSignerAccount_,
|
|
PublicKey const& publicKey_,
|
|
Buffer signature_,
|
|
AccountID const& sendingAccount_,
|
|
STAmount const& sendingAmount_,
|
|
AccountID const& rewardAccount_,
|
|
bool wasLockingChainSend_);
|
|
|
|
AttestationBase(AttestationBase const&) = default;
|
|
|
|
virtual ~AttestationBase() = default;
|
|
|
|
AttestationBase&
|
|
operator=(AttestationBase const&) = default;
|
|
|
|
// verify that the signature attests to the data.
|
|
bool
|
|
verify(STXChainBridge const& bridge) const;
|
|
|
|
protected:
|
|
explicit AttestationBase(STObject const& o);
|
|
explicit AttestationBase(Json::Value const& v);
|
|
|
|
[[nodiscard]] static bool
|
|
equalHelper(AttestationBase const& lhs, AttestationBase const& rhs);
|
|
|
|
[[nodiscard]] static bool
|
|
sameEventHelper(AttestationBase const& lhs, AttestationBase const& rhs);
|
|
|
|
void
|
|
addHelper(STObject& o) const;
|
|
|
|
private:
|
|
[[nodiscard]] virtual std::vector<std::uint8_t>
|
|
message(STXChainBridge const& bridge) const = 0;
|
|
};
|
|
|
|
// Attest to a regular cross-chain transfer
|
|
struct AttestationClaim : AttestationBase
|
|
{
|
|
std::uint64_t claimID;
|
|
std::optional<AccountID> dst;
|
|
|
|
explicit 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_);
|
|
|
|
explicit AttestationClaim(
|
|
STXChainBridge const& bridge,
|
|
AccountID attestationSignerAccount_,
|
|
PublicKey const& publicKey_,
|
|
SecretKey const& secretKey_,
|
|
AccountID const& sendingAccount_,
|
|
STAmount const& sendingAmount_,
|
|
AccountID const& rewardAccount_,
|
|
bool wasLockingChainSend_,
|
|
std::uint64_t claimID_,
|
|
std::optional<AccountID> const& dst_);
|
|
|
|
explicit AttestationClaim(STObject const& o);
|
|
explicit AttestationClaim(Json::Value const& v);
|
|
|
|
[[nodiscard]] STObject
|
|
toSTObject() const;
|
|
|
|
// return true if the two attestations attest to the same thing
|
|
[[nodiscard]] bool
|
|
sameEvent(AttestationClaim const& rhs) const;
|
|
|
|
[[nodiscard]] 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);
|
|
|
|
[[nodiscard]] bool
|
|
validAmounts() const;
|
|
|
|
private:
|
|
[[nodiscard]] std::vector<std::uint8_t>
|
|
message(STXChainBridge const& bridge) const override;
|
|
|
|
friend bool
|
|
operator==(AttestationClaim const& lhs, AttestationClaim const& rhs);
|
|
};
|
|
|
|
struct CmpByClaimID
|
|
{
|
|
bool
|
|
operator()(AttestationClaim const& lhs, AttestationClaim const& rhs) const
|
|
{
|
|
return lhs.claimID < rhs.claimID;
|
|
}
|
|
};
|
|
|
|
// Attest to a cross-chain transfer that creates an account
|
|
struct AttestationCreateAccount : AttestationBase
|
|
{
|
|
// createCount on the sending chain. This is the value of the `CreateCount`
|
|
// field of the bridge on the sending chain when the transaction was
|
|
// executed.
|
|
std::uint64_t createCount;
|
|
// Account to create on the destination chain
|
|
AccountID toCreate;
|
|
// Total amount of the reward pool
|
|
STAmount rewardAmount;
|
|
|
|
explicit AttestationCreateAccount(STObject const& o);
|
|
|
|
explicit AttestationCreateAccount(Json::Value const& v);
|
|
|
|
explicit AttestationCreateAccount(
|
|
AccountID attestationSignerAccount_,
|
|
PublicKey const& publicKey_,
|
|
Buffer signature_,
|
|
AccountID const& sendingAccount_,
|
|
STAmount const& sendingAmount_,
|
|
STAmount const& rewardAmount_,
|
|
AccountID const& rewardAccount_,
|
|
bool wasLockingChainSend_,
|
|
std::uint64_t createCount_,
|
|
AccountID const& toCreate_);
|
|
|
|
explicit AttestationCreateAccount(
|
|
STXChainBridge const& bridge,
|
|
AccountID attestationSignerAccount_,
|
|
PublicKey const& publicKey_,
|
|
SecretKey const& secretKey_,
|
|
AccountID const& sendingAccount_,
|
|
STAmount const& sendingAmount_,
|
|
STAmount const& rewardAmount_,
|
|
AccountID const& rewardAccount_,
|
|
bool wasLockingChainSend_,
|
|
std::uint64_t createCount_,
|
|
AccountID const& toCreate_);
|
|
|
|
[[nodiscard]] STObject
|
|
toSTObject() const;
|
|
|
|
// return true if the two attestations attest to the same thing
|
|
[[nodiscard]] bool
|
|
sameEvent(AttestationCreateAccount const& rhs) const;
|
|
|
|
friend bool
|
|
operator==(
|
|
AttestationCreateAccount const& lhs,
|
|
AttestationCreateAccount const& rhs);
|
|
|
|
[[nodiscard]] 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);
|
|
|
|
[[nodiscard]] bool
|
|
validAmounts() const;
|
|
|
|
private:
|
|
[[nodiscard]] std::vector<std::uint8_t>
|
|
message(STXChainBridge const& bridge) const override;
|
|
};
|
|
|
|
struct CmpByCreateCount
|
|
{
|
|
bool
|
|
operator()(
|
|
AttestationCreateAccount const& lhs,
|
|
AttestationCreateAccount const& rhs) const
|
|
{
|
|
return lhs.createCount < rhs.createCount;
|
|
}
|
|
};
|
|
|
|
}; // namespace Attestations
|
|
|
|
// Result when checking when two attestation match.
|
|
enum class AttestationMatch {
|
|
// One of the fields doesn't match, and it isn't the dst field
|
|
nonDstMismatch,
|
|
// all of the fields match, except the dst field
|
|
matchExceptDst,
|
|
// all of the fields match
|
|
match
|
|
};
|
|
|
|
struct XChainClaimAttestation
|
|
{
|
|
using TSignedAttestation = Attestations::AttestationClaim;
|
|
static SField const& ArrayFieldName;
|
|
|
|
AccountID keyAccount;
|
|
PublicKey publicKey;
|
|
STAmount amount;
|
|
AccountID rewardAccount;
|
|
bool wasLockingChainSend;
|
|
std::optional<AccountID> dst;
|
|
|
|
struct MatchFields
|
|
{
|
|
STAmount amount;
|
|
bool wasLockingChainSend;
|
|
std::optional<AccountID> dst;
|
|
MatchFields(TSignedAttestation const& att);
|
|
MatchFields(
|
|
STAmount const& a,
|
|
bool b,
|
|
std::optional<AccountID> const& d)
|
|
: amount{a}, wasLockingChainSend{b}, dst{d}
|
|
{
|
|
}
|
|
};
|
|
|
|
explicit XChainClaimAttestation(
|
|
AccountID const& keyAccount_,
|
|
PublicKey const& publicKey_,
|
|
STAmount const& amount_,
|
|
AccountID const& rewardAccount_,
|
|
bool wasLockingChainSend_,
|
|
std::optional<AccountID> const& dst);
|
|
|
|
explicit XChainClaimAttestation(
|
|
STAccount const& keyAccount_,
|
|
PublicKey const& publicKey_,
|
|
STAmount const& amount_,
|
|
STAccount const& rewardAccount_,
|
|
bool wasLockingChainSend_,
|
|
std::optional<STAccount> const& dst);
|
|
|
|
explicit XChainClaimAttestation(TSignedAttestation const& claimAtt);
|
|
|
|
explicit XChainClaimAttestation(STObject const& o);
|
|
|
|
explicit XChainClaimAttestation(Json::Value const& v);
|
|
|
|
AttestationMatch
|
|
match(MatchFields const& rhs) const;
|
|
|
|
[[nodiscard]] STObject
|
|
toSTObject() const;
|
|
|
|
friend bool
|
|
operator==(
|
|
XChainClaimAttestation const& lhs,
|
|
XChainClaimAttestation const& rhs);
|
|
};
|
|
|
|
struct XChainCreateAccountAttestation
|
|
{
|
|
using TSignedAttestation = Attestations::AttestationCreateAccount;
|
|
static SField const& ArrayFieldName;
|
|
|
|
AccountID keyAccount;
|
|
PublicKey publicKey;
|
|
STAmount amount;
|
|
STAmount rewardAmount;
|
|
AccountID rewardAccount;
|
|
bool wasLockingChainSend;
|
|
AccountID dst;
|
|
|
|
struct MatchFields
|
|
{
|
|
STAmount amount;
|
|
STAmount rewardAmount;
|
|
bool wasLockingChainSend;
|
|
AccountID dst;
|
|
|
|
MatchFields(TSignedAttestation const& att);
|
|
};
|
|
|
|
explicit XChainCreateAccountAttestation(
|
|
AccountID const& keyAccount_,
|
|
PublicKey const& publicKey_,
|
|
STAmount const& amount_,
|
|
STAmount const& rewardAmount_,
|
|
AccountID const& rewardAccount_,
|
|
bool wasLockingChainSend_,
|
|
AccountID const& dst_);
|
|
|
|
explicit XChainCreateAccountAttestation(TSignedAttestation const& claimAtt);
|
|
|
|
explicit XChainCreateAccountAttestation(STObject const& o);
|
|
|
|
explicit XChainCreateAccountAttestation(Json::Value const& v);
|
|
|
|
[[nodiscard]] STObject
|
|
toSTObject() const;
|
|
|
|
AttestationMatch
|
|
match(MatchFields const& rhs) const;
|
|
|
|
friend bool
|
|
operator==(
|
|
XChainCreateAccountAttestation const& lhs,
|
|
XChainCreateAccountAttestation const& rhs);
|
|
};
|
|
|
|
// Attestations from witness servers for a particular claimid and bridge.
|
|
// Only one attestation per signature is allowed.
|
|
template <class TAttestation>
|
|
class XChainAttestationsBase
|
|
{
|
|
public:
|
|
using AttCollection = std::vector<TAttestation>;
|
|
|
|
private:
|
|
// Set a max number of allowed attestations to limit the amount of memory
|
|
// allocated and processing time. This number is much larger than the actual
|
|
// number of attestation a server would ever expect.
|
|
static constexpr std::uint32_t maxAttestations = 256;
|
|
AttCollection attestations_;
|
|
|
|
protected:
|
|
// Prevent slicing to the base class
|
|
~XChainAttestationsBase() = default;
|
|
|
|
public:
|
|
XChainAttestationsBase() = default;
|
|
XChainAttestationsBase(XChainAttestationsBase const& rhs) = default;
|
|
XChainAttestationsBase&
|
|
operator=(XChainAttestationsBase const& rhs) = default;
|
|
|
|
explicit XChainAttestationsBase(AttCollection&& sigs);
|
|
|
|
explicit XChainAttestationsBase(Json::Value const& v);
|
|
|
|
explicit XChainAttestationsBase(STArray const& arr);
|
|
|
|
[[nodiscard]] STArray
|
|
toSTArray() const;
|
|
|
|
typename AttCollection::const_iterator
|
|
begin() const;
|
|
|
|
typename AttCollection::const_iterator
|
|
end() const;
|
|
|
|
typename AttCollection::iterator
|
|
begin();
|
|
|
|
typename AttCollection::iterator
|
|
end();
|
|
|
|
template <class F>
|
|
std::size_t
|
|
erase_if(F&& f);
|
|
|
|
std::size_t
|
|
size() const;
|
|
|
|
bool
|
|
empty() const;
|
|
|
|
AttCollection const&
|
|
attestations() const;
|
|
|
|
template <class T>
|
|
void
|
|
emplace_back(T&& att);
|
|
};
|
|
|
|
template <class TAttestation>
|
|
[[nodiscard]] inline bool
|
|
operator==(
|
|
XChainAttestationsBase<TAttestation> const& lhs,
|
|
XChainAttestationsBase<TAttestation> const& rhs)
|
|
{
|
|
return lhs.attestations() == rhs.attestations();
|
|
}
|
|
|
|
template <class TAttestation>
|
|
inline typename XChainAttestationsBase<TAttestation>::AttCollection const&
|
|
XChainAttestationsBase<TAttestation>::attestations() const
|
|
{
|
|
return attestations_;
|
|
};
|
|
|
|
template <class TAttestation>
|
|
template <class T>
|
|
inline void
|
|
XChainAttestationsBase<TAttestation>::emplace_back(T&& att)
|
|
{
|
|
attestations_.emplace_back(std::forward<T>(att));
|
|
};
|
|
|
|
template <class TAttestation>
|
|
template <class F>
|
|
inline std::size_t
|
|
XChainAttestationsBase<TAttestation>::erase_if(F&& f)
|
|
{
|
|
return std::erase_if(attestations_, std::forward<F>(f));
|
|
}
|
|
|
|
template <class TAttestation>
|
|
inline std::size_t
|
|
XChainAttestationsBase<TAttestation>::size() const
|
|
{
|
|
return attestations_.size();
|
|
}
|
|
|
|
template <class TAttestation>
|
|
inline bool
|
|
XChainAttestationsBase<TAttestation>::empty() const
|
|
{
|
|
return attestations_.empty();
|
|
}
|
|
|
|
class XChainClaimAttestations final
|
|
: public XChainAttestationsBase<XChainClaimAttestation>
|
|
{
|
|
using TBase = XChainAttestationsBase<XChainClaimAttestation>;
|
|
using TBase::TBase;
|
|
};
|
|
|
|
class XChainCreateAccountAttestations final
|
|
: public XChainAttestationsBase<XChainCreateAccountAttestation>
|
|
{
|
|
using TBase = XChainAttestationsBase<XChainCreateAccountAttestation>;
|
|
using TBase::TBase;
|
|
};
|
|
|
|
} // namespace ripple
|
|
|
|
#endif // STXCHAINATTESTATIONS_H_
|