-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Work in Progress] add AccountPermission #5164
base: develop
Are you sure you want to change the base?
Conversation
81fcb3f
to
34c5065
Compare
34c5065
to
2e9b7a6
Compare
gpMPTokenIssuanceUnlock = 65548, | ||
}; | ||
|
||
class Permission |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should probably delete copy and copy assignment constructors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this still needs to be done?
{ | ||
auto const sleOwner = ctx_.view().peek(keylet::account(account_)); | ||
if (!sleOwner) | ||
return {tefINTERNAL}; // LCOV_EXCL_LINE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return {tefINTERNAL}; // LCOV_EXCL_LINE | |
return tecINTERNAL; // LCOV_EXCL_LINE |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
sle = std::make_shared<SLE>(accountPermissionKey); | ||
auto const& permissions = ctx_.tx.getFieldArray(sfPermissions); | ||
sle->setFieldArray(sfPermissions, permissions); | ||
auto page = ctx_.view().dirInsert( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
auto page = ctx_.view().dirInsert( | |
auto const page = ctx_.view().dirInsert( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
keylet::accountPermission(account_, ctx_.tx[sfAuthorize]); | ||
|
||
auto sle = ctx_.view().peek(accountPermissionKey); | ||
if (!sle) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be refactored like
auto sle = ctx_.view().peek(accountPermissionKey);
if (sle)
{
auto const& permissions = ctx_.tx.getFieldArray(sfPermissions);
sle->setFieldArray(sfPermissions, permissions);
ctx_.view().update(sle);
return tesSUCCESS;
}
STAmount const reserve{ctx_.view().fees().accountReserve(
sleOwner->getFieldU32(sfOwnerCount) + 1)};
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
auto const accountPermissionKey = | ||
keylet::accountPermission(account_, ctx_.tx[sfAuthorize]); | ||
|
||
auto sle = ctx_.view().peek(accountPermissionKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
auto sle = ctx_.view().peek(accountPermissionKey); | |
auto const sle = ctx_.view().peek(accountPermissionKey); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to update sle later (sle = std::make_shared<SLE>(accountPermissionKey);
). can not be const.
6101542
to
bd7150e
Compare
04cf7ad
to
5c1d6a3
Compare
5c1d6a3
to
6bbe2ca
Compare
try | ||
{ | ||
return {pfctx, invoke_preflight(pfctx)}; | ||
// if AccountPermission is not enabled, do not use OnBehalfOf field. | ||
if (!rules.enabled(featureAccountPermission) && tx[~sfOnBehalfOf]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so what's the behavior when someone submits a tx with sfOnBehalfOf but not enabled the amendment? what error code does it return? To me, i feel we should not be throwing a runtime error, because it's a completely acceptable input. pls consider performing this check in the Transactor::preflight1
instead and return an code like temDISABLED
PR description should be added with a link to technical specifications if applicable. |
just added |
FYI: unit test failures are transient, which have passed locally. "ERR:Env Env::close() failed: no response from server" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took a pass and left a few comments.
My big concern is how sfAccount
is obfuscated by sfOnBehalfOf
. sfAccount
pretty much should never be used in the transactors with some exceptions. It's easy to miss these kind of errors where sfAccount
is used instead of the account
included in the context.
LEDGER_ENTRY(ltACCOUNT_PERMISSION, 0x0082, AccountPermission, ({ | ||
{sfAccount, soeREQUIRED}, | ||
{sfAuthorize, soeREQUIRED}, | ||
{sfPermissions, soeREQUIRED}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to make this optional since it could be empty?
/** This transaction type delegates authorized account specified permissions */ | ||
TRANSACTION(ttACCOUNT_PERMISSION_SET, 61, AccountPermissionSet, ({ | ||
{sfAuthorize, soeREQUIRED}, | ||
{sfPermissions, soeREQUIRED}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to make it optional since it could be empty?
*/ | ||
|
||
enum GranularPermissionType : std::uint32_t { | ||
gpTrustlineAuthorize = 65537, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is gp
prefix necessary? Can we just have TrustlineAuthorize
, etc?
@@ -77,6 +77,7 @@ enum class LedgerNameSpace : std::uint16_t { | |||
MPTOKEN_ISSUANCE = '~', | |||
MPTOKEN = 't', | |||
CREDENTIAL = 'D', | |||
ACCOUNT_PERMISSION = 'P', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This value is already used by DEPOSIT_PREAUTH_CREDENTIALS
{ | ||
auto permissionObj = dynamic_cast<STObject const*>(&permission); | ||
|
||
if (!permissionObj || (permissionObj->getFName() != sfPermission)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this needed? If the array is invalid it should fail in the array parsing. And if the name is not Permission
then it should fail also before it gets to the transactor. Should have a unit-test fo this.
@@ -197,7 +197,7 @@ preclaimHelper<MPTIssue>( | |||
TER | |||
Clawback::preclaim(PreclaimContext const& ctx) | |||
{ | |||
AccountID const issuer = ctx.tx[sfAccount]; | |||
AccountID const issuer = ctx.account; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be const&. Please check everywhere where an alias variable is used for ctx.account
. It should be AccountID const&
.
if (ctx_.isDelegated && !ctx_.gpSet.empty()) | ||
{ | ||
// if gpSet is not empty, granular delegation is happening. | ||
if (bLock && ctx_.gpSet.find(gpMPTokenIssuanceLock) == ctx_.gpSet.end()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can simplify here and below.
if (bLock && !ctx.gpSet.contains(gpMPTokenIssuanceLock))
auto const amountIssue = dstAmount.issue(); | ||
if (isXRP(amountIssue)) | ||
return tecNO_AUTH; | ||
if (amountIssue.account == account_ && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can simplify here and below:
if (amountIssue.account == account_ &&
ctx_.gpSet.contains(gpPaymentMint))
if (bSetNoRipple || bClearNoRipple || bQualityIn || bQualityOut) | ||
return terNO_AUTH; | ||
if (bSetAuth && | ||
ctx_.gpSet.find(gpTrustlineAuthorize) == ctx_.gpSet.end()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can simplify here and below:
if (bSetAuth &&
!ctx_.gpSet.contains(gpTrustlineAuthorize))
@@ -458,6 +458,7 @@ LedgerEntryTypesMatch::visitEntry( | |||
switch (after->getType()) | |||
{ | |||
case ltACCOUNT_ROOT: | |||
case ltACCOUNT_PERMISSION: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't leave a comment on unchanged lines so commenting here for ValidClawback::finalize:924, which is this line:
AccountID const issuer = tx.getAccountID(sfAccount);
The issuer
in this case could be either sfAccount
or sfOnBehalfOf
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is missed out. I'll also check all the other similar places which is missed out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gregtatcam
I also need to make change to AcceptedLedgerTx.cpp, LedgerToJson.cpp, and NetworkOPs.cpp, because they also check the account id when the transaction type is ttOFFER_CREATE. I'm working on this as well
spec:
XRPLF/XRPL-Standards#217
XRPLF/XRPL-Standards#218
This PR includes the following changes:
to enable an account(delegating account) delegate some permissions to another account(delegated account), so that the delegated account can send transactions on behalf of the delegating account.
The AccountPermissionSet transaction will create AccountPermission ledger object, with keylet(delegating account, delegated account)
a. transaction level permission
b. granular permission which will be part of a transaction
more details:
account
andisDelegated
in PreflightContext, PreclaimContext and ApplyContext. Theaccount
is the account which is the transaction being operated on.account_
is updated to the account which is the transaction being operated on.gpSet
is added to ApplyContext. It contains the granular permissions enabled for that transaction. But if the transaction is fully delegated, then even there are granular permissions related to that transaction, the gpSet will be cleared up. To be more specific:a. isDelegated=true && gpSet not empty: only granular permissions delegated to the transaction
b. isDelegated=true && gpSet is empty: the transaction is fully delegated
Permissions.cpp
are supported, so the unauthorized granular operations and the other parts under these transactions are prohibited under granular permission mode.High Level Overview of Change
Context of Change
Type of Change
.gitignore
, formatting, dropping support for older tooling)API Impact
libxrpl
change (any change that may affectlibxrpl
or dependents oflibxrpl
)