Skip to content

Commit

Permalink
RXI-1151 VC implementation (XLS-70)
Browse files Browse the repository at this point in the history
  • Loading branch information
oleks-rip committed Aug 31, 2024
1 parent d9bd75e commit 0ac3ab3
Show file tree
Hide file tree
Showing 34 changed files with 1,513 additions and 151 deletions.
3 changes: 2 additions & 1 deletion include/xrpl/protocol/Feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ namespace detail {
// Feature.cpp. Because it's only used to reserve storage, and determine how
// large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than
// the actual number of amendments. A LogicError on startup will verify this.
static constexpr std::size_t numFeatures = 79;
static constexpr std::size_t numFeatures = 80;

/** Amendments that this server supports and the default voting behavior.
Whether they are enabled depends on the Rules defined in the validated
Expand Down Expand Up @@ -372,6 +372,7 @@ extern uint256 const fixEnforceNFTokenTrustline;
extern uint256 const fixInnerObjTemplate2;
extern uint256 const featureInvariantsV1_1;
extern uint256 const fixNFTokenPageLinks;
extern uint256 const featureCredentials;

} // namespace ripple

Expand Down
3 changes: 3 additions & 0 deletions include/xrpl/protocol/HashPrefix.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ enum class HashPrefix : std::uint32_t {

/** Payment Channel Claim */
paymentChannelClaim = detail::make_hash_prefix('C', 'L', 'M'),

/** Credentials signature */
credential = detail::make_hash_prefix('C', 'R', 'S'),
};

template <class Hasher>
Expand Down
16 changes: 16 additions & 0 deletions include/xrpl/protocol/Indexes.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <xrpl/protocol/Serializer.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/protocol/jss.h>

#include <cstdint>

namespace ripple {
Expand Down Expand Up @@ -189,6 +190,9 @@ check(uint256 const& key) noexcept
Keylet
depositPreauth(AccountID const& owner, AccountID const& preauthorized) noexcept;

Keylet
depositPreauth(AccountID const& owner, STArray const& authCreds) noexcept;

inline Keylet
depositPreauth(uint256 const& key) noexcept
{
Expand Down Expand Up @@ -287,6 +291,18 @@ did(AccountID const& account) noexcept;
Keylet
oracle(AccountID const& account, std::uint32_t const& documentID) noexcept;

Keylet
credential(
AccountID const& subject,
AccountID const& issuer,
Slice const& credType) noexcept;

inline Keylet
credential(uint256 const& key) noexcept
{
return {ltCREDENTIAL, key};
}

} // namespace keylet

// Everything below is deprecated and should be removed in favor of keylets:
Expand Down
9 changes: 9 additions & 0 deletions include/xrpl/protocol/LedgerFormats.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,12 @@ enum LedgerEntryType : std::uint16_t
*/
ltORACLE = 0x0080,

/** A ledger object which describes a Verifiable Credentials for DID.
\sa keylet::credential
*/
ltCREDENTIAL = 0x0081,

//---------------------------------------------------------------------------
/** A special type, matching any ledger entry type.
Expand Down Expand Up @@ -308,6 +314,9 @@ enum LedgerSpecificFlags {

// ltNFTOKEN_OFFER
lsfSellNFToken = 0x00000001,

// ltCREDENTIAL
lsfAccepted = 0x00010000,
};

//------------------------------------------------------------------------------
Expand Down
6 changes: 6 additions & 0 deletions include/xrpl/protocol/Protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ std::size_t constexpr unfundedOfferRemoveLimit = 1000;
/** The maximum number of expired offers to delete at once */
std::size_t constexpr expiredOfferRemoveLimit = 256;

/** The maximum number of credentials can be passed in array */
std::size_t constexpr credentialsArrayMaxSize = 8;

/** The maximum number of metadata entries allowed in one transaction */
std::size_t constexpr oversizeMetaDataCap = 5200;

Expand Down Expand Up @@ -95,6 +98,9 @@ std::size_t constexpr maxDIDAttestationLength = 256;
/** The maximum length of a domain */
std::size_t constexpr maxDomainLength = 256;

/** The maximum length of a URI inside a Credential */
std::size_t constexpr maxCredentialURILength = 256;

/** A ledger index. */
using LedgerIndex = std::uint32_t;

Expand Down
6 changes: 6 additions & 0 deletions include/xrpl/protocol/SField.h
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,7 @@ extern SF_VL const sfHookStateData;
extern SF_VL const sfHookReturnString;
extern SF_VL const sfHookParameterName;
extern SF_VL const sfHookParameterValue;
extern SF_VL const sfCredentialType;

// account
extern SF_ACCOUNT const sfAccount;
Expand All @@ -596,6 +597,7 @@ extern SF_ACCOUNT const sfAttestationSignerAccount;
extern SF_ACCOUNT const sfAttestationRewardAccount;
extern SF_ACCOUNT const sfLockingChainDoor;
extern SF_ACCOUNT const sfIssuingChainDoor;
extern SF_ACCOUNT const sfSubject;

// path set
extern SField const sfPaths;
Expand All @@ -618,6 +620,7 @@ extern SF_VECTOR256 const sfIndexes;
extern SF_VECTOR256 const sfHashes;
extern SF_VECTOR256 const sfAmendments;
extern SF_VECTOR256 const sfNFTokenOffers;
extern SF_VECTOR256 const sfCredentialIDs;

// inner object
// OBJECT/1 is reserved for end of object
Expand Down Expand Up @@ -651,6 +654,7 @@ extern SField const sfXChainClaimProofSig;
extern SField const sfXChainCreateAccountProofSig;
extern SField const sfXChainClaimAttestationCollectionElement;
extern SField const sfXChainCreateAccountAttestationCollectionElement;
extern SField const sfCredential;

// array of objects (common)
// ARRAY/1 is reserved for end of array
Expand All @@ -676,6 +680,8 @@ extern SField const sfHookParameters;
extern SField const sfHookGrants;
extern SField const sfXChainClaimAttestations;
extern SField const sfXChainCreateAccountAttestations;
extern SField const sfAuthorizeCredentials;
extern SField const sfUnauthorizeCredentials;

//------------------------------------------------------------------------------

Expand Down
4 changes: 3 additions & 1 deletion include/xrpl/protocol/TER.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ enum TEMcodes : TERUnderlyingType {

temARRAY_EMPTY,
temARRAY_TOO_LARGE,

temBAD_CREDENTIALS,
};

//------------------------------------------------------------------------------
Expand Down Expand Up @@ -339,7 +341,7 @@ enum TECcodes : TERUnderlyingType {
tecINVALID_UPDATE_TIME = 188,
tecTOKEN_PAIR_NOT_FOUND = 189,
tecARRAY_EMPTY = 190,
tecARRAY_TOO_LARGE = 191
tecARRAY_TOO_LARGE = 191,
};

//------------------------------------------------------------------------------
Expand Down
9 changes: 9 additions & 0 deletions include/xrpl/protocol/TxFormats.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,15 @@ enum TxType : std::uint16_t
ttLEDGER_STATE_FIX = 53,


/** This transaction type creates an Credential instance */
ttCREDENTIAL_CREATE = 54,

/** This transaction type accepts an Credential instance */
ttCREDENTIAL_ACCEPT = 55,

/** This transaction type deletes an Credential instance */
ttCREDENTIAL_DELETE = 56,

/** This system-generated transaction type is used to update the status of the various amendments.
For details, see: https://xrpl.org/amendments.html
Expand Down
10 changes: 10 additions & 0 deletions include/xrpl/protocol/jss.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ JSS(CheckCash); // transaction type.
JSS(CheckCreate); // transaction type.
JSS(Clawback); // transaction type.
JSS(ClearFlag); // field.
JSS(Credential); // ledger type.
JSS(CredentialAccept); // transaction type.
JSS(CredentialCreate); // transaction type.
JSS(CredentialDelete); // transaction type.
JSS(DID); // ledger type.
JSS(DIDDelete); // transaction type.
JSS(DIDSet); // transaction type.
Expand Down Expand Up @@ -137,6 +141,7 @@ JSS(SendMax); // in: TransactionSign
JSS(Sequence); // in/out: TransactionSign; field.
JSS(SetFlag); // field.
JSS(SetRegularKey); // transaction type.
JSS(Signature); // in: Credential transactions
JSS(SignerList); // ledger type.
JSS(SignerListSet); // transaction type.
JSS(SigningPubKey); // field.
Expand Down Expand Up @@ -208,6 +213,7 @@ JSS(attestations); //
JSS(attestation_reward_account); //
JSS(auction_slot); // out: amm_info
JSS(authorized); // out: AccountLines
JSS(authorize_credentials); // in: ledger_entry DepositPreauth
JSS(auth_accounts); // out: amm_info
JSS(auth_change); // out: AccountInfo
JSS(auth_change_queued); // out: AccountInfo
Expand Down Expand Up @@ -266,6 +272,9 @@ JSS(converge_time_s); // out: NetworkOPs
JSS(cookie); // out: NetworkOPs
JSS(count); // in: AccountTx*, ValidatorList
JSS(counters); // in/out: retrieve counters
JSS(credential); // in: LedgerEntry Credential
JSS(credentials); // in: deposit_authorized
JSS(credential_type); // in: LedgerEntry DepositPreauth
JSS(ctid); // in/out: Tx RPC
JSS(currency_a); // out: BookChanges
JSS(currency_b); // out: BookChanges
Expand Down Expand Up @@ -651,6 +660,7 @@ JSS(streams); // in: Subscribe, Unsubscribe
JSS(strict); // in: AccountCurrencies, AccountInfo
JSS(sub_index); // in: LedgerEntry
JSS(subcommand); // in: PathFind
JSS(subject); // in: LedgerEntry Credential
JSS(success); // rpc
JSS(supported); // out: AmendmentTableImpl
JSS(sync_mode); // in: Submit
Expand Down
2 changes: 2 additions & 0 deletions src/libxrpl/protocol/Feature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,8 @@ REGISTER_FIX (fixReducedOffersV2, Supported::yes, VoteBehavior::De
REGISTER_FIX (fixEnforceNFTokenTrustline, Supported::yes, VoteBehavior::DefaultNo);
REGISTER_FIX (fixInnerObjTemplate2, Supported::yes, VoteBehavior::DefaultNo);
REGISTER_FIX (fixNFTokenPageLinks, Supported::yes, VoteBehavior::DefaultNo);
REGISTER_FEATURE(Credentials, Supported::yes, VoteBehavior::DefaultNo);

// InvariantsV1_1 will be changes to Supported::yes when all the
// invariants expected to be included under it are complete.
REGISTER_FEATURE(InvariantsV1_1, Supported::no, VoteBehavior::DefaultNo);
Expand Down
34 changes: 34 additions & 0 deletions src/libxrpl/protocol/Indexes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STArray.h>
#include <xrpl/protocol/STXChainBridge.h>
#include <xrpl/protocol/SeqProxy.h>
#include <xrpl/protocol/digest.h>
Expand Down Expand Up @@ -73,6 +74,7 @@ enum class LedgerNameSpace : std::uint16_t {
XCHAIN_CREATE_ACCOUNT_CLAIM_ID = 'K',
DID = 'I',
ORACLE = 'R',
CREDENTIAL = 'D',

// No longer used or supported. Left here to reserve the space
// to avoid accidental reuse.
Expand Down Expand Up @@ -301,6 +303,27 @@ depositPreauth(AccountID const& owner, AccountID const& preauthorized) noexcept
indexHash(LedgerNameSpace::DEPOSIT_PREAUTH, owner, preauthorized)};
}

Keylet
depositPreauth(AccountID const& owner, STArray const& authCreds) noexcept
{
std::string s;
std::vector<uint256> hashes;
hashes.reserve(authCreds.size());
for (auto const& o : authCreds)
{
hashes.push_back(sha512Half(
o.getAccountID(sfIssuer), o.getFieldVL(sfCredentialType)));
}

// eleminate duplicates
std::sort(hashes.begin(), hashes.end());
hashes.erase(std::unique(hashes.begin(), hashes.end()), hashes.end());

return {
ltDEPOSIT_PREAUTH,
indexHash(LedgerNameSpace::DEPOSIT_PREAUTH, owner, hashes)};
}

//------------------------------------------------------------------------------

Keylet
Expand Down Expand Up @@ -451,6 +474,17 @@ oracle(AccountID const& account, std::uint32_t const& documentID) noexcept
return {ltORACLE, indexHash(LedgerNameSpace::ORACLE, account, documentID)};
}

Keylet
credential(
AccountID const& subject,
AccountID const& issuer,
Slice const& credType) noexcept
{
return {
ltCREDENTIAL,
indexHash(LedgerNameSpace::CREDENTIAL, subject, issuer, credType)};
}

} // namespace keylet

} // namespace ripple
7 changes: 7 additions & 0 deletions src/libxrpl/protocol/InnerObjectFormats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,13 @@ InnerObjectFormats::InnerObjectFormats()
{sfAssetPrice, soeOPTIONAL},
{sfScale, soeDEFAULT},
});

add(sfCredential.jsonName.c_str(),
sfCredential.getCode(),
{
{sfIssuer, soeREQUIRED},
{sfCredentialType, soeREQUIRED},
});
}

InnerObjectFormats const&
Expand Down
18 changes: 16 additions & 2 deletions src/libxrpl/protocol/LedgerFormats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

#include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/jss.h>
#include <utility>

namespace ripple {

Expand Down Expand Up @@ -233,10 +232,11 @@ LedgerFormats::LedgerFormats()
ltDEPOSIT_PREAUTH,
{
{sfAccount, soeREQUIRED},
{sfAuthorize, soeREQUIRED},
{sfAuthorize, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
{sfAuthorizeCredentials, soeOPTIONAL},
},
commonFields);

Expand Down Expand Up @@ -365,6 +365,20 @@ LedgerFormats::LedgerFormats()
},
commonFields);

add(jss::Credential,
ltCREDENTIAL,
{
{sfSubject, soeREQUIRED},
{sfIssuer, soeREQUIRED},
{sfCredentialType, soeREQUIRED},
{sfExpiration, soeOPTIONAL},
{sfURI, soeOPTIONAL},
{sfOwnerNode, soeREQUIRED},
{sfPreviousTxnID, soeREQUIRED},
{sfPreviousTxnLgrSeq, soeREQUIRED},
},
commonFields);

// clang-format on
}

Expand Down
7 changes: 7 additions & 0 deletions src/libxrpl/protocol/SField.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ CONSTRUCT_TYPED_SFIELD(sfDIDDocument, "DIDDocument", VL,
CONSTRUCT_TYPED_SFIELD(sfData, "Data", VL, 27);
CONSTRUCT_TYPED_SFIELD(sfAssetClass, "AssetClass", VL, 28);
CONSTRUCT_TYPED_SFIELD(sfProvider, "Provider", VL, 29);
CONSTRUCT_TYPED_SFIELD(sfCredentialType, "CredentialType", VL, 30);

// account
CONSTRUCT_TYPED_SFIELD(sfAccount, "Account", ACCOUNT, 1);
Expand All @@ -328,12 +329,14 @@ CONSTRUCT_TYPED_SFIELD(sfAttestationSignerAccount, "AttestationSignerAccount", A
CONSTRUCT_TYPED_SFIELD(sfAttestationRewardAccount, "AttestationRewardAccount", ACCOUNT, 21);
CONSTRUCT_TYPED_SFIELD(sfLockingChainDoor, "LockingChainDoor", ACCOUNT, 22);
CONSTRUCT_TYPED_SFIELD(sfIssuingChainDoor, "IssuingChainDoor", ACCOUNT, 23);
CONSTRUCT_TYPED_SFIELD(sfSubject, "Subject", ACCOUNT, 24);

// vector of 256-bit
CONSTRUCT_TYPED_SFIELD(sfIndexes, "Indexes", VECTOR256, 1, SField::sMD_Never);
CONSTRUCT_TYPED_SFIELD(sfHashes, "Hashes", VECTOR256, 2);
CONSTRUCT_TYPED_SFIELD(sfAmendments, "Amendments", VECTOR256, 3);
CONSTRUCT_TYPED_SFIELD(sfNFTokenOffers, "NFTokenOffers", VECTOR256, 4);
CONSTRUCT_TYPED_SFIELD(sfCredentialIDs, "CredentialIDs", VECTOR256, 5);

// path set
CONSTRUCT_UNTYPED_SFIELD(sfPaths, "Paths", PATHSET, 1);
Expand Down Expand Up @@ -391,6 +394,8 @@ CONSTRUCT_UNTYPED_SFIELD(sfXChainCreateAccountAttestationCollectionElement,
"XChainCreateAccountAttestationCollectionElement",
OBJECT, 31);
CONSTRUCT_UNTYPED_SFIELD(sfPriceData, "PriceData", OBJECT, 32);
CONSTRUCT_UNTYPED_SFIELD(sfCredential, "Credential", OBJECT, 33);


// array of objects
// ARRAY/1 is reserved for end of array
Expand Down Expand Up @@ -421,6 +426,8 @@ CONSTRUCT_UNTYPED_SFIELD(sfXChainCreateAccountAttestations,
// 23 is unused and available for use
CONSTRUCT_UNTYPED_SFIELD(sfPriceDataSeries, "PriceDataSeries", ARRAY, 24);
CONSTRUCT_UNTYPED_SFIELD(sfAuthAccounts, "AuthAccounts", ARRAY, 25);
CONSTRUCT_UNTYPED_SFIELD(sfAuthorizeCredentials, "AuthorizeCredentials", ARRAY, 26);
CONSTRUCT_UNTYPED_SFIELD(sfUnauthorizeCredentials, "UnauthorizeCredentials", ARRAY, 27);

// clang-format on

Expand Down
Loading

0 comments on commit 0ac3ab3

Please sign in to comment.