mirror of
https://github.com/XRPLF/rippled.git
synced 2026-09-27 23:38:08 +00:00
Merge remote-tracking branch 'Transia-RnD-rippled/feature-p256' into develop
# Conflicts: # include/xrpl/protocol/Indexes.h # include/xrpl/protocol/KeyType.h # include/xrpl/protocol/PublicKey.h # src/libxrpl/protocol/Indexes.cpp # src/libxrpl/protocol/PublicKey.cpp # src/libxrpl/protocol/SecretKey.cpp
This commit is contained in:
@@ -82,4 +82,10 @@ base64Encode(std::string_view s)
|
||||
std::string
|
||||
base64Decode(std::string_view data);
|
||||
|
||||
/** Decode a base64url-encoded string (RFC 4648 S5).
|
||||
Converts '-' to '+' and '_' to '/', adds padding, then decodes.
|
||||
*/
|
||||
std::string
|
||||
base64urlDecode(std::string_view data);
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
@@ -408,6 +408,8 @@ contract(uint256 const& contractID)
|
||||
Keylet
|
||||
contractData(AccountID const& owner, AccountID const& contractAccount) noexcept;
|
||||
|
||||
Keylet
|
||||
passkeyList(AccountID const& account) noexcept;
|
||||
} // namespace keylet
|
||||
|
||||
// Everything below is deprecated and should be removed in favor of keylets:
|
||||
|
||||
@@ -9,6 +9,7 @@ enum class KeyType {
|
||||
Secp256k1 = 0,
|
||||
Ed25519 = 1,
|
||||
Dilithium = 2,
|
||||
P256 = 3,
|
||||
};
|
||||
|
||||
inline std::optional<KeyType>
|
||||
@@ -23,6 +24,9 @@ keyTypeFromString(std::string const& s)
|
||||
if (s == "dilithium")
|
||||
return KeyType::Dilithium;
|
||||
|
||||
if (s == "p256")
|
||||
return KeyType::P256;
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -38,6 +42,9 @@ to_string(KeyType type)
|
||||
if (type == KeyType::Dilithium)
|
||||
return "dilithium";
|
||||
|
||||
if (type == KeyType::P256)
|
||||
return "p256";
|
||||
|
||||
return "INVALID";
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace xrpl {
|
||||
* secp256k1
|
||||
* ed25519
|
||||
* dilithium
|
||||
* p256
|
||||
*
|
||||
* secp256k1 public keys consist of a 33 byte
|
||||
* compressed public key, with the lead byte equal
|
||||
@@ -57,9 +58,10 @@ class PublicKey
|
||||
protected:
|
||||
// Minimum / standard public key size (secp256k1, ed25519).
|
||||
static constexpr std::size_t kSize = 33;
|
||||
// Buffer sized for the largest supported key (dilithium = 1312 bytes).
|
||||
// Actual length is tracked in size_.
|
||||
std::uint8_t buf_[1312]{};
|
||||
// Buffer sized for the largest supported key (dilithium = 1312 bytes;
|
||||
// uncompressed p256 = 65 bytes). Actual length is tracked in size_.
|
||||
static constexpr std::size_t kMaxSize = 1312;
|
||||
std::uint8_t buf_[kMaxSize]{};
|
||||
std::size_t size_ = 0;
|
||||
|
||||
public:
|
||||
@@ -137,7 +139,7 @@ operator<<(std::ostream& os, PublicKey const& pk);
|
||||
inline bool
|
||||
operator==(PublicKey const& lhs, PublicKey const& rhs)
|
||||
{
|
||||
return std::memcmp(lhs.data(), rhs.data(), rhs.size()) == 0;
|
||||
return lhs.size() == rhs.size() && std::memcmp(lhs.data(), rhs.data(), rhs.size()) == 0;
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
||||
@@ -151,3 +151,4 @@ XRPL_FIX (Cleanup3_5_0, Supported::Yes, VoteBehavior::DefaultN
|
||||
XRPL_FEATURE(ConfidentialMPTKeyRotation, Supported::No, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(TokenPaychan, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(Quantum, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(Passkey, Supported::Yes, VoteBehavior::DefaultNo)
|
||||
|
||||
@@ -693,6 +693,13 @@ LEDGER_ENTRY(ltSPONSORSHIP, 0x0090, Sponsorship, sponsorship, ({
|
||||
{sfOwnerNode, SoeRequired},
|
||||
{sfSponseeNode, SoeRequired},
|
||||
}))
|
||||
LEDGER_ENTRY(ltPASSKEY_LIST, 0x0091, PasskeyList, passkey_list, ({
|
||||
{sfPreviousTxnID, SoeRequired},
|
||||
{sfPreviousTxnLgrSeq, SoeRequired},
|
||||
{sfOwnerNode, SoeRequired},
|
||||
{sfOwner, SoeRequired},
|
||||
{sfPasskeys, SoeRequired},
|
||||
}))
|
||||
|
||||
#undef EXPAND
|
||||
#undef LEDGER_ENTRY_DUPLICATE
|
||||
|
||||
@@ -471,3 +471,10 @@ UNTYPED_SFIELD(sfParameters, ARRAY, 35)
|
||||
TYPED_SFIELD(sfParameterValue, DATA, 1, SField::kSmdDefault)
|
||||
TYPED_SFIELD(sfParameterType, DATATYPE, 1)
|
||||
TYPED_SFIELD(sfContractJson, JSON, 1)
|
||||
TYPED_SFIELD(sfSignCount, UINT32, 87)
|
||||
TYPED_SFIELD(sfPasskeyID, VL, 50)
|
||||
TYPED_SFIELD(sfAuthenticatorData, VL, 51)
|
||||
TYPED_SFIELD(sfClientDataJSON, VL, 52)
|
||||
UNTYPED_SFIELD(sfPasskeySignature, OBJECT, 43, SField::kSmdDefault, SField::kNotSigning)
|
||||
UNTYPED_SFIELD(sfPasskey, OBJECT, 44)
|
||||
UNTYPED_SFIELD(sfPasskeys, ARRAY, 36)
|
||||
|
||||
@@ -1310,3 +1310,11 @@ TRANSACTION(ttUNL_MODIFY, 102, UNLModify,
|
||||
{sfLedgerSequence, SoeRequired},
|
||||
{sfUNLModifyValidator, SoeRequired},
|
||||
}))
|
||||
TRANSACTION(ttPASSKEY_LIST_SET, 103, PasskeyListSet,
|
||||
({
|
||||
.delegable = Delegation::Delegable,
|
||||
.amendment = featurePasskey,
|
||||
}),
|
||||
({
|
||||
{sfPasskeys, SoeRequired},
|
||||
}))
|
||||
|
||||
@@ -237,4 +237,14 @@ sha512HalfS(Args const&... args)
|
||||
return static_cast<sha512_half_hasher_s::result_type>(h);
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
sha256_hasher::result_type
|
||||
sha256(Args const&... args)
|
||||
{
|
||||
xrpl::sha256_hasher h;
|
||||
using beast::hash_append;
|
||||
hash_append(h, args...);
|
||||
return static_cast<typename sha256_hasher::result_type>(h);
|
||||
}
|
||||
|
||||
} // namespace xrpl
|
||||
|
||||
218
include/xrpl/protocol_autogen/ledger_entries/PasskeyList.h
Normal file
218
include/xrpl/protocol_autogen/ledger_entries/PasskeyList.h
Normal file
@@ -0,0 +1,218 @@
|
||||
// This file is auto-generated. Do not edit.
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/protocol_autogen/LedgerEntryBase.h>
|
||||
#include <xrpl/protocol_autogen/LedgerEntryBuilderBase.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl::ledger_entries {
|
||||
|
||||
class PasskeyListBuilder;
|
||||
|
||||
/**
|
||||
* @brief Ledger Entry: PasskeyList
|
||||
*
|
||||
* Type: ltPASSKEY_LIST (0x0091)
|
||||
* RPC Name: passkey_list
|
||||
*
|
||||
* Immutable wrapper around SLE providing type-safe field access.
|
||||
* Use PasskeyListBuilder to construct new ledger entries.
|
||||
*/
|
||||
class PasskeyList : public LedgerEntryBase
|
||||
{
|
||||
public:
|
||||
static constexpr LedgerEntryType entryType = ltPASSKEY_LIST;
|
||||
|
||||
/**
|
||||
* @brief Construct a PasskeyList ledger entry wrapper from an existing SLE object.
|
||||
* @throws std::runtime_error if the ledger entry type doesn't match.
|
||||
*/
|
||||
explicit PasskeyList(SLE::const_pointer sle)
|
||||
: LedgerEntryBase(std::move(sle))
|
||||
{
|
||||
// Verify ledger entry type
|
||||
if (sle_->getType() != entryType)
|
||||
{
|
||||
throw std::runtime_error("Invalid ledger entry type for PasskeyList");
|
||||
}
|
||||
}
|
||||
|
||||
// Ledger entry-specific field getters
|
||||
|
||||
/**
|
||||
* @brief Get sfPreviousTxnID (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT256::type::value_type
|
||||
getPreviousTxnID() const
|
||||
{
|
||||
return this->sle_->at(sfPreviousTxnID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfPreviousTxnLgrSeq (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT32::type::value_type
|
||||
getPreviousTxnLgrSeq() const
|
||||
{
|
||||
return this->sle_->at(sfPreviousTxnLgrSeq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOwnerNode (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_UINT64::type::value_type
|
||||
getOwnerNode() const
|
||||
{
|
||||
return this->sle_->at(sfOwnerNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfOwner (SoeRequired)
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
SF_ACCOUNT::type::value_type
|
||||
getOwner() const
|
||||
{
|
||||
return this->sle_->at(sfOwner);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get sfPasskeys (SoeRequired)
|
||||
* @note This is an untyped field (unknown).
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
STArray const&
|
||||
getPasskeys() const
|
||||
{
|
||||
return this->sle_->getFieldArray(sfPasskeys);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for PasskeyList ledger entries.
|
||||
*
|
||||
* Provides a fluent interface for constructing ledger entries with method chaining.
|
||||
* Uses STObject internally for flexible ledger entry construction.
|
||||
* Inherits common field setters from LedgerEntryBuilderBase.
|
||||
*/
|
||||
class PasskeyListBuilder : public LedgerEntryBuilderBase<PasskeyListBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new PasskeyListBuilder with required fields.
|
||||
* @param previousTxnID The sfPreviousTxnID field value.
|
||||
* @param previousTxnLgrSeq The sfPreviousTxnLgrSeq field value.
|
||||
* @param ownerNode The sfOwnerNode field value.
|
||||
* @param owner The sfOwner field value.
|
||||
* @param passkeys The sfPasskeys field value.
|
||||
*/
|
||||
PasskeyListBuilder(std::decay_t<typename SF_UINT256::type::value_type> const& previousTxnID,std::decay_t<typename SF_UINT32::type::value_type> const& previousTxnLgrSeq,std::decay_t<typename SF_UINT64::type::value_type> const& ownerNode,std::decay_t<typename SF_ACCOUNT::type::value_type> const& owner,STArray const& passkeys)
|
||||
: LedgerEntryBuilderBase<PasskeyListBuilder>(ltPASSKEY_LIST)
|
||||
{
|
||||
setPreviousTxnID(previousTxnID);
|
||||
setPreviousTxnLgrSeq(previousTxnLgrSeq);
|
||||
setOwnerNode(ownerNode);
|
||||
setOwner(owner);
|
||||
setPasskeys(passkeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a PasskeyListBuilder from an existing SLE object.
|
||||
* @param sle The existing ledger entry to copy from.
|
||||
* @throws std::runtime_error if the ledger entry type doesn't match.
|
||||
*/
|
||||
PasskeyListBuilder(SLE::const_pointer sle)
|
||||
{
|
||||
if (sle->at(sfLedgerEntryType) != ltPASSKEY_LIST)
|
||||
{
|
||||
throw std::runtime_error("Invalid ledger entry type for PasskeyList");
|
||||
}
|
||||
object_ = *sle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ledger entry-specific field setters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set sfPreviousTxnID (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
PasskeyListBuilder&
|
||||
setPreviousTxnID(std::decay_t<typename SF_UINT256::type::value_type> const& value)
|
||||
{
|
||||
object_[sfPreviousTxnID] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfPreviousTxnLgrSeq (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
PasskeyListBuilder&
|
||||
setPreviousTxnLgrSeq(std::decay_t<typename SF_UINT32::type::value_type> const& value)
|
||||
{
|
||||
object_[sfPreviousTxnLgrSeq] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOwnerNode (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
PasskeyListBuilder&
|
||||
setOwnerNode(std::decay_t<typename SF_UINT64::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOwnerNode] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfOwner (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
PasskeyListBuilder&
|
||||
setOwner(std::decay_t<typename SF_ACCOUNT::type::value_type> const& value)
|
||||
{
|
||||
object_[sfOwner] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set sfPasskeys (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
PasskeyListBuilder&
|
||||
setPasskeys(STArray const& value)
|
||||
{
|
||||
object_.setFieldArray(sfPasskeys, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the completed PasskeyList wrapper.
|
||||
* @param index The ledger entry index.
|
||||
* @return The constructed ledger entry wrapper.
|
||||
*/
|
||||
PasskeyList
|
||||
build(uint256 const& index)
|
||||
{
|
||||
return PasskeyList{std::make_shared<SLE>(std::move(object_), index)};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::ledger_entries
|
||||
131
include/xrpl/protocol_autogen/transactions/PasskeyListSet.h
Normal file
131
include/xrpl/protocol_autogen/transactions/PasskeyListSet.h
Normal file
@@ -0,0 +1,131 @@
|
||||
// This file is auto-generated. Do not edit.
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/protocol/jss.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBase.h>
|
||||
#include <xrpl/protocol_autogen/TransactionBuilderBase.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <optional>
|
||||
|
||||
namespace xrpl::transactions {
|
||||
|
||||
class PasskeyListSetBuilder;
|
||||
|
||||
/**
|
||||
* @brief Transaction: PasskeyListSet
|
||||
*
|
||||
* Type: ttPASSKEY_LIST_SET (92)
|
||||
* Delegable: Delegation::Delegable
|
||||
* Amendment: featurePasskey
|
||||
* Privileges: Privilege::NoPriv
|
||||
*
|
||||
* Immutable wrapper around STTx providing type-safe field access.
|
||||
* Use PasskeyListSetBuilder to construct new transactions.
|
||||
*/
|
||||
class PasskeyListSet : public TransactionBase
|
||||
{
|
||||
public:
|
||||
static constexpr xrpl::TxType txType = ttPASSKEY_LIST_SET;
|
||||
|
||||
/**
|
||||
* @brief Construct a PasskeyListSet transaction wrapper from an existing STTx object.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
explicit PasskeyListSet(std::shared_ptr<STTx const> tx)
|
||||
: TransactionBase(std::move(tx))
|
||||
{
|
||||
// Verify transaction type
|
||||
if (tx_->getTxnType() != txType)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for PasskeyListSet");
|
||||
}
|
||||
}
|
||||
|
||||
// Transaction-specific field getters
|
||||
/**
|
||||
* @brief Get sfPasskeys (SoeRequired)
|
||||
* @note This is an untyped field.
|
||||
* @return The field value.
|
||||
*/
|
||||
[[nodiscard]]
|
||||
STArray const&
|
||||
getPasskeys() const
|
||||
{
|
||||
return this->tx_->getFieldArray(sfPasskeys);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Builder for PasskeyListSet transactions.
|
||||
*
|
||||
* Provides a fluent interface for constructing transactions with method chaining.
|
||||
* Uses STObject internally for flexible transaction construction.
|
||||
* Inherits common field setters from TransactionBuilderBase.
|
||||
*/
|
||||
class PasskeyListSetBuilder : public TransactionBuilderBase<PasskeyListSetBuilder>
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new PasskeyListSetBuilder with required fields.
|
||||
* @param account The account initiating the transaction.
|
||||
* @param passkeys The sfPasskeys field value.
|
||||
* @param sequence Optional sequence number for the transaction.
|
||||
* @param fee Optional fee for the transaction.
|
||||
*/
|
||||
PasskeyListSetBuilder(SF_ACCOUNT::type::value_type account,
|
||||
STArray const& passkeys, std::optional<SF_UINT32::type::value_type> sequence = std::nullopt,
|
||||
std::optional<SF_AMOUNT::type::value_type> fee = std::nullopt
|
||||
)
|
||||
: TransactionBuilderBase<PasskeyListSetBuilder>(ttPASSKEY_LIST_SET, account, sequence, fee)
|
||||
{
|
||||
setPasskeys(passkeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a PasskeyListSetBuilder from an existing STTx object.
|
||||
* @param tx The existing transaction to copy from.
|
||||
* @throws std::runtime_error if the transaction type doesn't match.
|
||||
*/
|
||||
PasskeyListSetBuilder(std::shared_ptr<STTx const> tx)
|
||||
{
|
||||
if (tx->getTxnType() != ttPASSKEY_LIST_SET)
|
||||
{
|
||||
throw std::runtime_error("Invalid transaction type for PasskeyListSetBuilder");
|
||||
}
|
||||
object_ = *tx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transaction-specific field setters
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set sfPasskeys (SoeRequired)
|
||||
* @return Reference to this builder for method chaining.
|
||||
*/
|
||||
PasskeyListSetBuilder&
|
||||
setPasskeys(STArray const& value)
|
||||
{
|
||||
object_.setFieldArray(sfPasskeys, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Build and return the PasskeyListSet wrapper.
|
||||
* @param publicKey The public key for signing.
|
||||
* @param secretKey The secret key for signing.
|
||||
* @return The constructed transaction wrapper.
|
||||
*/
|
||||
PasskeyListSet
|
||||
build(PublicKey const& publicKey, SecretKey const& secretKey)
|
||||
{
|
||||
sign(publicKey, secretKey);
|
||||
return PasskeyListSet{std::make_shared<STTx>(std::move(object_))};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace xrpl::transactions
|
||||
42
include/xrpl/tx/transactors/account/SetPasskeyList.h
Normal file
42
include/xrpl/tx/transactors/account/SetPasskeyList.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/tx/ApplyContext.h>
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
class SetPasskeyList : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr auto kConsequencesFactory = ConsequencesFactoryType::Blocker;
|
||||
|
||||
explicit SetPasskeyList(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
|
||||
void
|
||||
visitInvariantEntry(bool isDelete, SLE::const_ref before, SLE::const_ref after) override;
|
||||
|
||||
[[nodiscard]] bool
|
||||
finalizeInvariants(
|
||||
STTx const& tx,
|
||||
TER result,
|
||||
XRPAmount fee,
|
||||
ReadView const& view,
|
||||
beast::Journal const& j) override;
|
||||
};
|
||||
|
||||
using PasskeyListSet = SetPasskeyList;
|
||||
|
||||
} // namespace xrpl
|
||||
Reference in New Issue
Block a user