Skip to content

Commit 1f953dc

Browse files
Merge branch 'develop'
2 parents 0e11fa7 + 9d58f11 commit 1f953dc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+8689
-451
lines changed

include/xrpl/basics/scope.h

+65
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define RIPPLE_BASICS_SCOPE_H_INCLUDED
2222

2323
#include <exception>
24+
#include <mutex>
2425
#include <type_traits>
2526
#include <utility>
2627

@@ -186,6 +187,70 @@ class scope_success
186187
template <class EF>
187188
scope_success(EF) -> scope_success<EF>;
188189

190+
/**
191+
Automatically unlocks and re-locks a unique_lock object.
192+
193+
This is the reverse of a std::unique_lock object - instead of locking the
194+
mutex for the lifetime of this object, it unlocks it.
195+
196+
Make sure you don't try to unlock mutexes that aren't actually locked!
197+
198+
This is essentially a less-versatile boost::reverse_lock.
199+
200+
e.g. @code
201+
202+
std::mutex mut;
203+
204+
for (;;)
205+
{
206+
std::unique_lock myScopedLock{mut};
207+
// mut is now locked
208+
209+
... do some stuff with it locked ..
210+
211+
while (xyz)
212+
{
213+
... do some stuff with it locked ..
214+
215+
scope_unlock unlocker{myScopedLock};
216+
217+
// mut is now unlocked for the remainder of this block,
218+
// and re-locked at the end.
219+
220+
...do some stuff with it unlocked ...
221+
} // mut gets locked here.
222+
223+
} // mut gets unlocked here
224+
@endcode
225+
*/
226+
227+
template <class Mutex>
228+
class scope_unlock
229+
{
230+
std::unique_lock<Mutex>* plock;
231+
232+
public:
233+
explicit scope_unlock(std::unique_lock<Mutex>& lock) noexcept(true)
234+
: plock(&lock)
235+
{
236+
assert(plock->owns_lock());
237+
plock->unlock();
238+
}
239+
240+
// Immovable type
241+
scope_unlock(scope_unlock const&) = delete;
242+
scope_unlock&
243+
operator=(scope_unlock const&) = delete;
244+
245+
~scope_unlock() noexcept(true)
246+
{
247+
plock->lock();
248+
}
249+
};
250+
251+
template <class Mutex>
252+
scope_unlock(std::unique_lock<Mutex>&) -> scope_unlock<Mutex>;
253+
189254
} // namespace ripple
190255

191256
#endif

include/xrpl/protocol/Asset.h

+29
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ class Asset
9797

9898
friend constexpr bool
9999
operator==(Currency const& lhs, Asset const& rhs);
100+
101+
/** Return true if both assets refer to the same currency (regardless of
102+
* issuer) or MPT issuance. Otherwise return false.
103+
*/
104+
friend constexpr bool
105+
equalTokens(Asset const& lhs, Asset const& rhs);
100106
};
101107

102108
template <ValidIssueType TIss>
@@ -157,6 +163,26 @@ operator==(Currency const& lhs, Asset const& rhs)
157163
return rhs.holds<Issue>() && rhs.get<Issue>().currency == lhs;
158164
}
159165

166+
constexpr bool
167+
equalTokens(Asset const& lhs, Asset const& rhs)
168+
{
169+
return std::visit(
170+
[&]<typename TLhs, typename TRhs>(
171+
TLhs const& issLhs, TRhs const& issRhs) {
172+
if constexpr (
173+
std::is_same_v<TLhs, Issue> && std::is_same_v<TRhs, Issue>)
174+
return issLhs.currency == issRhs.currency;
175+
else if constexpr (
176+
std::is_same_v<TLhs, MPTIssue> &&
177+
std::is_same_v<TRhs, MPTIssue>)
178+
return issLhs.getMptID() == issRhs.getMptID();
179+
else
180+
return false;
181+
},
182+
lhs.issue_,
183+
rhs.issue_);
184+
}
185+
160186
inline bool
161187
isXRP(Asset const& asset)
162188
{
@@ -172,6 +198,9 @@ validJSONAsset(Json::Value const& jv);
172198
Asset
173199
assetFromJson(Json::Value const& jv);
174200

201+
Json::Value
202+
to_json(Asset const& asset);
203+
175204
} // namespace ripple
176205

177206
#endif // RIPPLE_PROTOCOL_ASSET_H_INCLUDED

include/xrpl/protocol/ErrorCodes.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,10 @@ enum error_code_i {
148148
// Oracle
149149
rpcORACLE_MALFORMED = 94,
150150

151-
rpcLAST = rpcORACLE_MALFORMED // rpcLAST should always equal the last code.
151+
// deposit_authorized + credentials
152+
rpcBAD_CREDENTIALS = 95,
153+
154+
rpcLAST = rpcBAD_CREDENTIALS // rpcLAST should always equal the last code.
152155
};
153156

154157
/** Codes returned in the `warnings` array of certain RPC commands.

include/xrpl/protocol/Feature.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ namespace detail {
8080
// Feature.cpp. Because it's only used to reserve storage, and determine how
8181
// large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than
8282
// the actual number of amendments. A LogicError on startup will verify this.
83-
static constexpr std::size_t numFeatures = 80;
83+
static constexpr std::size_t numFeatures = 83;
8484

8585
/** Amendments that this server supports and the default voting behavior.
8686
Whether they are enabled depends on the Rules defined in the validated

include/xrpl/protocol/HashPrefix.h

+3
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ enum class HashPrefix : std::uint32_t {
8484

8585
/** Payment Channel Claim */
8686
paymentChannelClaim = detail::make_hash_prefix('C', 'L', 'M'),
87+
88+
/** Credentials signature */
89+
credential = detail::make_hash_prefix('C', 'R', 'D'),
8790
};
8891

8992
template <class Hasher>

include/xrpl/protocol/Indexes.h

+18
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <xrpl/protocol/Serializer.h>
3131
#include <xrpl/protocol/UintTypes.h>
3232
#include <xrpl/protocol/jss.h>
33+
3334
#include <cstdint>
3435

3536
namespace ripple {
@@ -189,6 +190,11 @@ check(uint256 const& key) noexcept
189190
Keylet
190191
depositPreauth(AccountID const& owner, AccountID const& preauthorized) noexcept;
191192

193+
Keylet
194+
depositPreauth(
195+
AccountID const& owner,
196+
std::set<std::pair<AccountID, Slice>> const& authCreds) noexcept;
197+
192198
inline Keylet
193199
depositPreauth(uint256 const& key) noexcept
194200
{
@@ -287,6 +293,18 @@ did(AccountID const& account) noexcept;
287293
Keylet
288294
oracle(AccountID const& account, std::uint32_t const& documentID) noexcept;
289295

296+
Keylet
297+
credential(
298+
AccountID const& subject,
299+
AccountID const& issuer,
300+
Slice const& credType) noexcept;
301+
302+
inline Keylet
303+
credential(uint256 const& key) noexcept
304+
{
305+
return {ltCREDENTIAL, key};
306+
}
307+
290308
Keylet
291309
mptIssuance(std::uint32_t seq, AccountID const& issuer) noexcept;
292310

include/xrpl/protocol/LedgerFormats.h

+3
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ enum LedgerSpecificFlags {
186186

187187
// ltMPTOKEN
188188
lsfMPTAuthorized = 0x00000002,
189+
190+
// ltCREDENTIAL
191+
lsfAccepted = 0x00010000,
189192
};
190193

191194
//------------------------------------------------------------------------------

include/xrpl/protocol/Protocol.h

+9
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,15 @@ std::size_t constexpr maxDIDAttestationLength = 256;
9696
/** The maximum length of a domain */
9797
std::size_t constexpr maxDomainLength = 256;
9898

99+
/** The maximum length of a URI inside a Credential */
100+
std::size_t constexpr maxCredentialURILength = 256;
101+
102+
/** The maximum length of a CredentialType inside a Credential */
103+
std::size_t constexpr maxCredentialTypeLength = 64;
104+
105+
/** The maximum number of credentials can be passed in array */
106+
std::size_t constexpr maxCredentialsArraySize = 8;
107+
99108
/** The maximum length of MPTokenMetadata */
100109
std::size_t constexpr maxMPTokenMetadataLength = 1024;
101110

include/xrpl/protocol/TER.h

+1
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ enum TECcodes : TERUnderlyingType {
343343
tecARRAY_EMPTY = 190,
344344
tecARRAY_TOO_LARGE = 191,
345345
tecLOCKED = 192,
346+
tecBAD_CREDENTIALS = 193,
346347
};
347348

348349
//------------------------------------------------------------------------------

include/xrpl/protocol/TxFlags.h

+4
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,10 @@ constexpr std::uint32_t tfDepositSubTx =
207207
constexpr std::uint32_t tfWithdrawMask = ~(tfUniversal | tfWithdrawSubTx);
208208
constexpr std::uint32_t tfDepositMask = ~(tfUniversal | tfDepositSubTx);
209209

210+
// AMMClawback flags:
211+
constexpr std::uint32_t tfClawTwoAssets = 0x00000001;
212+
constexpr std::uint32_t tfAMMClawbackMask = ~(tfUniversal | tfClawTwoAssets);
213+
210214
// BridgeModify flags:
211215
constexpr std::uint32_t tfClearAccountCreateAmount = 0x00010000;
212216
constexpr std::uint32_t tfBridgeModifyMask = ~(tfUniversal | tfClearAccountCreateAmount);

include/xrpl/protocol/UintTypes.h

+6
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,12 @@ struct hash<ripple::Directory> : ripple::Directory::hasher
134134
explicit hash() = default;
135135
};
136136

137+
template <>
138+
struct hash<ripple::uint256> : ripple::uint256::hasher
139+
{
140+
explicit hash() = default;
141+
};
142+
137143
} // namespace std
138144

139145
#endif

include/xrpl/protocol/detail/features.macro

+4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
// If you add an amendment here, then do not forget to increment `numFeatures`
3030
// in include/xrpl/protocol/Feature.h.
3131

32+
XRPL_FEATURE(Credentials, Supported::yes, VoteBehavior::DefaultNo)
33+
XRPL_FEATURE(AMMClawback, Supported::yes, VoteBehavior::DefaultNo)
34+
XRPL_FIX (AMMv1_2, Supported::yes, VoteBehavior::DefaultNo)
3235
// InvariantsV1_1 will be changes to Supported::yes when all the
3336
// invariants expected to be included under it are complete.
3437
XRPL_FEATURE(MPTokensV1, Supported::yes, VoteBehavior::DefaultNo)
@@ -96,6 +99,7 @@ XRPL_FEATURE(FlowCross, Supported::yes, VoteBehavior::DefaultYe
9699
XRPL_FEATURE(Flow, Supported::yes, VoteBehavior::DefaultYes)
97100
XRPL_FEATURE(OwnerPaysFee, Supported::no, VoteBehavior::DefaultNo)
98101

102+
99103
// The following amendments are obsolete, but must remain supported
100104
// because they could potentially get enabled.
101105
//

include/xrpl/protocol/detail/ledger_entries.macro

+17-1
Original file line numberDiff line numberDiff line change
@@ -245,10 +245,11 @@ LEDGER_ENTRY(ltOFFER, 0x006f, Offer, ({
245245
*/
246246
LEDGER_ENTRY(ltDEPOSIT_PREAUTH, 0x0070, DepositPreauth, ({
247247
{sfAccount, soeREQUIRED},
248-
{sfAuthorize, soeREQUIRED},
248+
{sfAuthorize, soeOPTIONAL},
249249
{sfOwnerNode, soeREQUIRED},
250250
{sfPreviousTxnID, soeREQUIRED},
251251
{sfPreviousTxnLgrSeq, soeREQUIRED},
252+
{sfAuthorizeCredentials, soeOPTIONAL},
252253
}))
253254

254255
/** A claim id for a cross chain transaction.
@@ -420,3 +421,18 @@ LEDGER_ENTRY(ltMPTOKEN, 0x007f, MPToken, ({
420421
{sfPreviousTxnID, soeREQUIRED},
421422
{sfPreviousTxnLgrSeq, soeREQUIRED},
422423
}))
424+
425+
/** A ledger object which tracks Credential
426+
\sa keylet::credential
427+
*/
428+
LEDGER_ENTRY(ltCREDENTIAL, 0x0081, Credential, ({
429+
{sfSubject, soeREQUIRED},
430+
{sfIssuer, soeREQUIRED},
431+
{sfCredentialType, soeREQUIRED},
432+
{sfExpiration, soeOPTIONAL},
433+
{sfURI, soeOPTIONAL},
434+
{sfIssuerNode, soeREQUIRED},
435+
{sfSubjectNode, soeREQUIRED},
436+
{sfPreviousTxnID, soeREQUIRED},
437+
{sfPreviousTxnLgrSeq, soeREQUIRED},
438+
}))

include/xrpl/protocol/detail/sfields.macro

+8
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ TYPED_SFIELD(sfAssetPrice, UINT64, 23)
140140
TYPED_SFIELD(sfMaximumAmount, UINT64, 24, SField::sMD_BaseTen|SField::sMD_Default)
141141
TYPED_SFIELD(sfOutstandingAmount, UINT64, 25, SField::sMD_BaseTen|SField::sMD_Default)
142142
TYPED_SFIELD(sfMPTAmount, UINT64, 26, SField::sMD_BaseTen|SField::sMD_Default)
143+
TYPED_SFIELD(sfIssuerNode, UINT64, 27)
144+
TYPED_SFIELD(sfSubjectNode, UINT64, 28)
143145

144146
// 128-bit
145147
TYPED_SFIELD(sfEmailHash, UINT128, 1)
@@ -258,6 +260,7 @@ TYPED_SFIELD(sfData, VL, 27)
258260
TYPED_SFIELD(sfAssetClass, VL, 28)
259261
TYPED_SFIELD(sfProvider, VL, 29)
260262
TYPED_SFIELD(sfMPTokenMetadata, VL, 30)
263+
TYPED_SFIELD(sfCredentialType, VL, 31)
261264

262265
// account (common)
263266
TYPED_SFIELD(sfAccount, ACCOUNT, 1)
@@ -280,12 +283,14 @@ TYPED_SFIELD(sfAttestationSignerAccount, ACCOUNT, 20)
280283
TYPED_SFIELD(sfAttestationRewardAccount, ACCOUNT, 21)
281284
TYPED_SFIELD(sfLockingChainDoor, ACCOUNT, 22)
282285
TYPED_SFIELD(sfIssuingChainDoor, ACCOUNT, 23)
286+
TYPED_SFIELD(sfSubject, ACCOUNT, 24)
283287

284288
// vector of 256-bit
285289
TYPED_SFIELD(sfIndexes, VECTOR256, 1, SField::sMD_Never)
286290
TYPED_SFIELD(sfHashes, VECTOR256, 2)
287291
TYPED_SFIELD(sfAmendments, VECTOR256, 3)
288292
TYPED_SFIELD(sfNFTokenOffers, VECTOR256, 4)
293+
TYPED_SFIELD(sfCredentialIDs, VECTOR256, 5)
289294

290295
// path set
291296
UNTYPED_SFIELD(sfPaths, PATHSET, 1)
@@ -337,6 +342,7 @@ UNTYPED_SFIELD(sfXChainCreateAccountProofSig, OBJECT, 29)
337342
UNTYPED_SFIELD(sfXChainClaimAttestationCollectionElement, OBJECT, 30)
338343
UNTYPED_SFIELD(sfXChainCreateAccountAttestationCollectionElement, OBJECT, 31)
339344
UNTYPED_SFIELD(sfPriceData, OBJECT, 32)
345+
UNTYPED_SFIELD(sfCredential, OBJECT, 33)
340346

341347
// array of objects (common)
342348
// ARRAY/1 is reserved for end of array
@@ -364,3 +370,5 @@ UNTYPED_SFIELD(sfXChainCreateAccountAttestations, ARRAY, 22)
364370
// 23 unused
365371
UNTYPED_SFIELD(sfPriceDataSeries, ARRAY, 24)
366372
UNTYPED_SFIELD(sfAuthAccounts, ARRAY, 25)
373+
UNTYPED_SFIELD(sfAuthorizeCredentials, ARRAY, 26)
374+
UNTYPED_SFIELD(sfUnauthorizeCredentials, ARRAY, 27)

0 commit comments

Comments
 (0)