Skip to content

Commit 50dbe3d

Browse files
committed
add AccountPermission
1 parent 63209c2 commit 50dbe3d

18 files changed

+461
-6
lines changed

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 = 79;
83+
static constexpr std::size_t numFeatures = 80;
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/Indexes.h

+11
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,17 @@ amm(Issue const& issue1, Issue const& issue2) noexcept;
272272
Keylet
273273
amm(uint256 const& amm) noexcept;
274274

275+
/** An AccountPermission */
276+
/** @{ */
277+
Keylet
278+
accountPermission(
279+
AccountID const& account,
280+
AccountID const& authorizedAccount) noexcept;
281+
282+
Keylet
283+
accountPermission(uint256 const& key) noexcept;
284+
/** @} */
285+
275286
Keylet
276287
bridge(STXChainBridge const& bridge, STXChainBridge::ChainType chainType);
277288

include/xrpl/protocol/Permissions.h

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
//------------------------------------------------------------------------------
2+
/*
3+
This file is part of rippled: https://github.com/ripple/rippled
4+
Copyright (c) 2024 Ripple Labs Inc.
5+
6+
Permission to use, copy, modify, and/or distribute this software for any
7+
purpose with or without fee is hereby granted, provided that the above
8+
copyright notice and this permission notice appear in all copies.
9+
10+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13+
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17+
*/
18+
//==============================================================================
19+
20+
#ifndef RIPPLE_PROTOCOL_PERMISSIONFORMATS_H_INCLUDED
21+
#define RIPPLE_PROTOCOL_PERMISSIONFORMATS_H_INCLUDED
22+
23+
#include <xrpl/protocol/KnownFormats.h>
24+
25+
namespace ripple {
26+
27+
/**
28+
* We have transaction type account permissions and granular account
29+
* permissions. Since we will reuse the TransactionFormats to parse the
30+
* Transaction Permissions, we only define the GranularPermissionType here.
31+
*/
32+
33+
enum GranularPermissionType : std::uint32_t {
34+
gpTrustlineAuthorize = 65537,
35+
36+
gpTrustlineFreeze = 65538,
37+
38+
gpTrustlineUnfreeze = 65539,
39+
40+
gpAccountDomainSet = 65540,
41+
42+
gpAccountEmailHashSet = 65541,
43+
44+
gpAccountMessageKeySet = 65542,
45+
46+
gpAccountTransferRateSet = 65543,
47+
48+
gpAccountTickSizeSet = 65544,
49+
50+
gpPaymentMint = 65545,
51+
52+
gpPaymentBurn = 65546,
53+
54+
gpMPTokenIssuanceLock = 65547,
55+
56+
gpMPTokenIssuanceUnlock = 65548,
57+
};
58+
59+
class GranularPermission
60+
{
61+
private:
62+
GranularPermission();
63+
64+
std::unordered_map<std::string, GranularPermissionType>
65+
granularPermissionMap;
66+
67+
public:
68+
static GranularPermission const&
69+
getInstance();
70+
71+
std::optional<std::uint32_t>
72+
getValue(const std::string& name) const;
73+
};
74+
75+
} // namespace ripple
76+
77+
#endif

include/xrpl/protocol/detail/features.macro

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ XRPL_FIX (1513, Supported::yes, VoteBehavior::DefaultYe
9494
XRPL_FEATURE(FlowCross, Supported::yes, VoteBehavior::DefaultYes)
9595
XRPL_FEATURE(Flow, Supported::yes, VoteBehavior::DefaultYes)
9696
XRPL_FEATURE(OwnerPaysFee, Supported::no, VoteBehavior::DefaultNo)
97+
XRPL_FEATURE(AccountPermission, Supported::yes, VoteBehavior::DefaultYes)
9798

9899
// The following amendments are obsolete, but must remain supported
99100
// because they could potentially get enabled.

include/xrpl/protocol/detail/ledger_entries.macro

+13
Original file line numberDiff line numberDiff line change
@@ -392,3 +392,16 @@ LEDGER_ENTRY(ltORACLE, 0x0080, Oracle, ({
392392
{sfPreviousTxnID, soeREQUIRED},
393393
{sfPreviousTxnLgrSeq, soeREQUIRED},
394394
}))
395+
396+
/** A ledger object representing permissions an account has delegated to another account.
397+
398+
\sa keylet::accountPermission
399+
*/
400+
LEDGER_ENTRY(ltACCOUNT_PERMISSION, 0x0081, AccountPermission, ({
401+
{sfAccount, soeREQUIRED},
402+
{sfAuthorize, soeREQUIRED},
403+
{sfPermissions, soeREQUIRED},
404+
{sfOwnerNode, soeREQUIRED},
405+
{sfPreviousTxnID, soeREQUIRED},
406+
{sfPreviousTxnLgrSeq, soeREQUIRED},
407+
}))

include/xrpl/protocol/detail/sfields.macro

+3
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ TYPED_SFIELD(sfEmitGeneration, UINT32, 46)
111111
TYPED_SFIELD(sfVoteWeight, UINT32, 48)
112112
TYPED_SFIELD(sfFirstNFTokenSequence, UINT32, 50)
113113
TYPED_SFIELD(sfOracleDocumentID, UINT32, 51)
114+
TYPED_SFIELD(sfPermissionValue, UINT32, 52)
114115

115116
// 64-bit integers (common)
116117
TYPED_SFIELD(sfIndexNext, UINT64, 1)
@@ -309,6 +310,7 @@ UNTYPED_SFIELD(sfSignerEntry, OBJECT, 11)
309310
UNTYPED_SFIELD(sfNFToken, OBJECT, 12)
310311
UNTYPED_SFIELD(sfEmitDetails, OBJECT, 13)
311312
UNTYPED_SFIELD(sfHook, OBJECT, 14)
313+
UNTYPED_SFIELD(sfPermission, OBJECT, 15)
312314

313315
// inner object (uncommon)
314316
UNTYPED_SFIELD(sfSigner, OBJECT, 16)
@@ -355,3 +357,4 @@ UNTYPED_SFIELD(sfXChainCreateAccountAttestations, ARRAY, 22)
355357
// 23 unused
356358
UNTYPED_SFIELD(sfPriceDataSeries, ARRAY, 24)
357359
UNTYPED_SFIELD(sfAuthAccounts, ARRAY, 25)
360+
UNTYPED_SFIELD(sfPermissions, ARRAY, 26)

include/xrpl/protocol/detail/transactions.macro

+6
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,12 @@ TRANSACTION(ttLEDGER_STATE_FIX, 53, LedgerStateFix, ({
386386
{sfOwner, soeOPTIONAL},
387387
}))
388388

389+
/** This transaction type delegates authorized account specified permissions */
390+
TRANSACTION(ttACCOUNT_PERMISSION_SET, 54, AccountPermissionSet, ({
391+
{sfAuthorize, soeREQUIRED},
392+
{sfPermissions, soeREQUIRED},
393+
}))
394+
389395
/** This system-generated transaction type is used to update the status of the various amendments.
390396

391397
For details, see: https://xrpl.org/amendments.html

include/xrpl/protocol/jss.h

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ namespace jss {
4545
JSS(AL_size); // out: GetCounts
4646
JSS(AL_hit_rate); // out: GetCounts
4747
JSS(Account); // in: TransactionSign; field.
48+
JSS(AccountPermission); // ledger type.
4849
JSS(AccountRoot); // ledger type.
4950
JSS(AMM); // ledger type
5051
JSS(AMMID); // field
@@ -126,6 +127,7 @@ JSS(account_hash); // out: LedgerToJson
126127
JSS(account_id); // out: WalletPropose
127128
JSS(account_nfts); // out: AccountNFTs
128129
JSS(account_objects); // out: AccountObjects
130+
JSS(account_permission); // in: AccountPermission
129131
JSS(account_root); // in: LedgerEntry
130132
JSS(account_sequence_next); // out: SubmitTransaction
131133
JSS(account_sequence_available); // out: SubmitTransaction

src/libxrpl/protocol/Indexes.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ enum class LedgerNameSpace : std::uint16_t {
7373
XCHAIN_CREATE_ACCOUNT_CLAIM_ID = 'K',
7474
DID = 'I',
7575
ORACLE = 'R',
76+
ACCOUNT_PERMISSION = 'P',
7677

7778
// No longer used or supported. Left here to reserve the space
7879
// to avoid accidental reuse.
@@ -398,6 +399,23 @@ amm(uint256 const& id) noexcept
398399
return {ltAMM, id};
399400
}
400401

402+
Keylet
403+
accountPermission(
404+
AccountID const& account,
405+
AccountID const& authorizedAccount) noexcept
406+
{
407+
return {
408+
ltACCOUNT_PERMISSION,
409+
indexHash(
410+
LedgerNameSpace::ACCOUNT_PERMISSION, account, authorizedAccount)};
411+
}
412+
413+
Keylet
414+
accountPermission(uint256 const& key) noexcept
415+
{
416+
return {ltACCOUNT_PERMISSION, key};
417+
}
418+
401419
Keylet
402420
bridge(STXChainBridge const& bridge, STXChainBridge::ChainType chainType)
403421
{

src/libxrpl/protocol/Permissions.cpp

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//------------------------------------------------------------------------------
2+
/*
3+
This file is part of rippled: https://github.com/ripple/rippled
4+
Copyright (c) 2024 Ripple Labs Inc.
5+
6+
Permission to use, copy, modify, and/or distribute this software for any
7+
purpose with or without fee is hereby granted, provided that the above
8+
copyright notice and this permission notice appear in all copies.
9+
10+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13+
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17+
*/
18+
//==============================================================================
19+
20+
#include <xrpl/protocol/Permissions.h>
21+
#include <xrpl/protocol/SField.h>
22+
#include <xrpl/protocol/SOTemplate.h>
23+
#include <xrpl/protocol/jss.h>
24+
25+
namespace ripple {
26+
27+
GranularPermission::GranularPermission()
28+
{
29+
// add(jss::TrustlineAuthorize, gpTrustlineAuthorize, {});
30+
granularPermissionMap = {
31+
{"TrustlineAuthorize", gpTrustlineAuthorize},
32+
{"TrustlineFreeze", gpTrustlineFreeze},
33+
{"TrustlineUnfreeze", gpTrustlineUnfreeze},
34+
{"AccountDomainSet", gpAccountDomainSet},
35+
{"AccountEmailHashSet", gpAccountEmailHashSet},
36+
{"AccountMessageKeySet", gpAccountMessageKeySet},
37+
{"AccountTransferRateSet", gpAccountTransferRateSet},
38+
{"AccountTickSizeSet", gpAccountTickSizeSet},
39+
{"PaymentMint", gpPaymentMint},
40+
{"PaymentBurn", gpPaymentBurn},
41+
{"MPTokenIssuanceLock", gpMPTokenIssuanceLock},
42+
{"MPTokenIssuanceUnlock", gpMPTokenIssuanceUnlock}};
43+
}
44+
45+
GranularPermission const&
46+
GranularPermission::getInstance()
47+
{
48+
static GranularPermission const instance;
49+
return instance;
50+
}
51+
52+
std::optional<std::uint32_t>
53+
GranularPermission::getValue(const std::string& name) const
54+
{
55+
auto const it = granularPermissionMap.find(name);
56+
if (it != granularPermissionMap.end())
57+
return static_cast<uint32_t>(it->second);
58+
59+
return std::nullopt;
60+
}
61+
62+
} // namespace ripple

src/libxrpl/protocol/STParsedJSON.cpp

+26-4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <xrpl/beast/core/LexicalCast.h>
2424
#include <xrpl/protocol/ErrorCodes.h>
2525
#include <xrpl/protocol/LedgerFormats.h>
26+
#include <xrpl/protocol/Permissions.h>
2627
#include <xrpl/protocol/SField.h>
2728
#include <xrpl/protocol/STAccount.h>
2829
#include <xrpl/protocol/STAmount.h>
@@ -360,10 +361,31 @@ parseLeaf(
360361
{
361362
if (value.isString())
362363
{
363-
ret = detail::make_stvar<STUInt32>(
364-
field,
365-
beast::lexicalCastThrow<std::uint32_t>(
366-
value.asString()));
364+
if (field == sfPermissionValue)
365+
{
366+
auto const granularPermission =
367+
GranularPermission::getInstance().getValue(
368+
value.asString());
369+
if (!granularPermission)
370+
// if it's not granular permission, parse as
371+
// transaction type permission
372+
ret = detail::make_stvar<STUInt32>(
373+
field,
374+
static_cast<std::uint32_t>(
375+
TxFormats::getInstance().findTypeByName(
376+
value.asString()) +
377+
1));
378+
else
379+
ret = detail::make_stvar<STUInt32>(
380+
field, *granularPermission);
381+
}
382+
else
383+
{
384+
ret = detail::make_stvar<STUInt32>(
385+
field,
386+
beast::lexicalCastThrow<std::uint32_t>(
387+
value.asString()));
388+
}
367389
}
368390
else if (value.isInt())
369391
{

0 commit comments

Comments
 (0)