Check for pseudo-account in other transaction types

This commit is contained in:
Bronek Kozicki
2025-04-28 17:41:40 +01:00
parent a205906e54
commit 298aaac456
6 changed files with 36 additions and 10 deletions

View File

@@ -207,12 +207,13 @@ Clawback::preclaim(PreclaimContext const& ctx)
if (!sleIssuer || !sleHolder)
return terNO_ACCOUNT;
if (sleHolder->isFieldPresent(sfAMMID))
return tecAMM_ACCOUNT;
// Note the order of checks - when SAV is active, this check here will make
// the one which follows `sleHolder->isFieldPresent(sfAMMID)` redundant.
if (ctx.view.rules().enabled(featureSingleAssetVault) &&
sleHolder->isFieldPresent(sfVaultID))
isPseudoAccount(sleHolder))
return tecPSEUDO_ACCOUNT;
else if (sleHolder->isFieldPresent(sfAMMID))
return tecAMM_ACCOUNT;
return std::visit(
[&]<typename T>(T const&) {

View File

@@ -97,7 +97,7 @@ CreateCheck::preclaim(PreclaimContext const& ctx)
(flags & lsfDisallowIncomingCheck))
return tecNO_PERMISSION;
// Pseudo-accounts cannot cash check. Note, this is not amendment-gated
// Pseudo-accounts cannot cash checks. Note, this is not amendment-gated
// because all writes to pseudo-account discriminator fields **are**
// amendment gated, hence the behaviour of this check will always match the
// currently active amendments.

View File

@@ -148,7 +148,12 @@ EscrowCreate::preclaim(PreclaimContext const& ctx)
auto const sled = ctx.view.read(keylet::account(ctx.tx[sfDestination]));
if (!sled)
return tecNO_DST;
if (sled->isFieldPresent(sfAMMID))
// Pseudo-accounts cannot receive escrow. Note, this is not amendment-gated
// because all writes to pseudo-account discriminator fields **are**
// amendment gated, hence the behaviour of this check will always match the
// currently active amendments.
if (isPseudoAccount(sled))
return tecNO_PERMISSION;
return tesSUCCESS;

View File

@@ -237,7 +237,13 @@ PayChanCreate::preclaim(PreclaimContext const& ctx)
(flags & lsfDisallowXRP))
return tecNO_TARGET;
if (sled->isFieldPresent(sfAMMID))
// Pseudo-accounts cannot receive payment channels, other than native
// to their underlying ledger object - implemented in their respective
// transaction types. Note, this is not amendment-gated because all
// writes to pseudo-account discriminator fields **are** amendment
// gated, hence the behaviour of this check will always match the
// currently active amendments.
if (isPseudoAccount(sled))
return tecNO_PERMISSION;
}

View File

@@ -556,9 +556,12 @@ Payment::doApply()
return tecUNFUNDED_PAYMENT;
}
// AMMs can never receive an XRP payment.
// Must use AMMDeposit transaction instead.
if (sleDst->isFieldPresent(sfAMMID))
// Pseudo-accounts cannot receive payments, other than these native to
// their underlying ledger object - implemented in their respective
// transaction types. Note, this is not amendment-gated because all writes
// to pseudo-account discriminator fields **are** amendment gated, hence the
// behaviour of this check will always match the active amendments.
if (isPseudoAccount(sleDst))
return tecNO_PERMISSION;
// The source account does have enough money. Make sure the

View File

@@ -228,6 +228,17 @@ SetTrust::preclaim(PreclaimContext const& ctx)
}
}
// Pseudo-accounts cannot receive trustlines, other than these native to
// their underlying ledger object - implemented in their respective
// transaction types. Note, this is not amendment-gated because all writes
// to pseudo-account discriminator fields **are** amendment gated, hence the
// behaviour of this check will always match the currently active
// amendments.
// The AMM destination is handled above, so exclude it from check here
// since AMM does allow trustline in certain conditions.
if (sleDst && !sleDst->isFieldPresent(sfAMMID) && isPseudoAccount(sleDst))
return tecPSEUDO_ACCOUNT;
// Checking all freeze/deep freeze flag invariants.
if (ctx.view.rules().enabled(featureDeepFreeze))
{