mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Add DepositPreauth ledger type and transaction (RIPD-1624):
The lsfDepositAuth flag limits the AccountIDs that can deposit into the account that has the flag set. The original design only allowed deposits to complete if the account with the flag set also signed the transaction that caused the deposit. The DepositPreauth ledger type allows an account with the lsfDepositAuth flag set to preauthorize additional accounts. This preauthorization allows them to sign deposits as well. An account can add DepositPreauth objects to the ledger (and remove them as well) using the DepositPreauth transaction.
This commit is contained in:
@@ -78,7 +78,8 @@ class FeatureCollections
|
||||
"Checks",
|
||||
"fix1571",
|
||||
"fix1543",
|
||||
"fix1623"
|
||||
"fix1623",
|
||||
"DepositPreauth"
|
||||
};
|
||||
|
||||
std::vector<uint256> features;
|
||||
@@ -363,6 +364,7 @@ extern uint256 const featureChecks;
|
||||
extern uint256 const fix1571;
|
||||
extern uint256 const fix1543;
|
||||
extern uint256 const fix1623;
|
||||
extern uint256 const featureDepositPreauth;
|
||||
|
||||
} // ripple
|
||||
|
||||
|
||||
@@ -93,6 +93,9 @@ getSignerListIndex (AccountID const& account);
|
||||
uint256
|
||||
getCheckIndex (AccountID const& account, std::uint32_t uSequence);
|
||||
|
||||
uint256
|
||||
getDepositPreauthIndex (AccountID const& owner, AccountID const& preauthorized);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/* VFALCO TODO
|
||||
@@ -253,6 +256,21 @@ struct check_t
|
||||
};
|
||||
static check_t const check {};
|
||||
|
||||
/** A DepositPreauth */
|
||||
struct depositPreauth_t
|
||||
{
|
||||
explicit depositPreauth_t() = default;
|
||||
|
||||
Keylet operator()(AccountID const& owner,
|
||||
AccountID const& preauthorized) const;
|
||||
|
||||
Keylet operator()(uint256 const& key) const
|
||||
{
|
||||
return { ltDEPOSIT_PREAUTH, key };
|
||||
}
|
||||
};
|
||||
static depositPreauth_t const depositPreauth {};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Any ledger entry */
|
||||
|
||||
@@ -141,6 +141,8 @@ JSS ( dbKBTotal ); // out: getCounts
|
||||
JSS ( dbKBTransaction ); // out: getCounts
|
||||
JSS ( debug_signing ); // in: TransactionSign
|
||||
JSS ( delivered_amount ); // out: addPaymentDeliveredAmount
|
||||
JSS ( deposit_authorized ); // out: deposit_authorized
|
||||
JSS ( deposit_preauth ); // in: AccountObjects, LedgerData
|
||||
JSS ( deprecated ); // out
|
||||
JSS ( descending ); // in: AccountTx*
|
||||
JSS ( destination_account ); // in: PathRequest, RipplePathFind, account_lines
|
||||
|
||||
@@ -85,6 +85,8 @@ enum LedgerEntryType
|
||||
|
||||
ltCHECK = 'C',
|
||||
|
||||
ltDEPOSIT_PREAUTH = 'p',
|
||||
|
||||
// No longer used or supported. Left here to prevent accidental
|
||||
// reassignment of the ledger type.
|
||||
ltNICKNAME = 'n',
|
||||
@@ -114,6 +116,7 @@ enum LedgerNameSpace
|
||||
spaceSignerList = 'S',
|
||||
spaceXRPUChannel = 'x',
|
||||
spaceCheck = 'C',
|
||||
spaceDepositPreauth = 'p',
|
||||
|
||||
// No longer used or supported. Left here to reserve the space and
|
||||
// avoid accidental reuse of the space.
|
||||
|
||||
@@ -464,6 +464,8 @@ extern SF_Account const sfAccount;
|
||||
extern SF_Account const sfOwner;
|
||||
extern SF_Account const sfDestination;
|
||||
extern SF_Account const sfIssuer;
|
||||
extern SF_Account const sfAuthorize;
|
||||
extern SF_Account const sfUnauthorize;
|
||||
extern SF_Account const sfTarget;
|
||||
extern SF_Account const sfRegularKey;
|
||||
|
||||
|
||||
@@ -106,6 +106,8 @@ enum TEMcodes : TERUnderlyingType
|
||||
temBAD_QUORUM,
|
||||
temBAD_WEIGHT,
|
||||
temBAD_TICK_SIZE,
|
||||
temINVALID_ACCOUNT_ID,
|
||||
temCANNOT_PREAUTH_SELF,
|
||||
|
||||
// An intermediate result used internally, should never be returned.
|
||||
temUNCERTAIN,
|
||||
@@ -259,7 +261,8 @@ enum TECcodes : TERUnderlyingType
|
||||
tecOVERSIZE = 145,
|
||||
tecCRYPTOCONDITION_ERROR = 146,
|
||||
tecINVARIANT_FAILED = 147,
|
||||
tecEXPIRED = 148
|
||||
tecEXPIRED = 148,
|
||||
tecDUPLICATE = 149,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -53,7 +53,7 @@ enum TxType
|
||||
ttCHECK_CREATE = 16,
|
||||
ttCHECK_CASH = 17,
|
||||
ttCHECK_CANCEL = 18,
|
||||
|
||||
ttDEPOSIT_PREAUTH = 19,
|
||||
ttTRUST_SET = 20,
|
||||
|
||||
ttAMENDMENT = 100,
|
||||
|
||||
@@ -110,7 +110,8 @@ detail::supportedAmendments ()
|
||||
{ "157D2D480E006395B76F948E3E07A45A05FE10230D88A7993C71F97AE4B1F2D1 Checks" },
|
||||
{ "7117E2EC2DBF119CA55181D69819F1999ECEE1A0225A7FD2B9ED47940968479C fix1571" },
|
||||
{ "CA7C02118BA27599528543DFE77BA6838D1B0F43B447D4D7F53523CE6A0E9AC2 fix1543" },
|
||||
{ "58BE9B5968C4DA7C59BA900961828B113E5490699B21877DEF9A31E9D0FE5D5F fix1623" }
|
||||
{ "58BE9B5968C4DA7C59BA900961828B113E5490699B21877DEF9A31E9D0FE5D5F fix1623" },
|
||||
{ "3CBC5C4E630A1B82380295CDA84B32B49DD066602E74E39B85EF64137FA65194 DepositPreauth"}
|
||||
};
|
||||
return supported;
|
||||
}
|
||||
@@ -163,5 +164,6 @@ uint256 const featureChecks = *getRegisteredFeature("Checks");
|
||||
uint256 const fix1571 = *getRegisteredFeature("fix1571");
|
||||
uint256 const fix1543 = *getRegisteredFeature("fix1543");
|
||||
uint256 const fix1623 = *getRegisteredFeature("fix1623");
|
||||
uint256 const featureDepositPreauth = *getRegisteredFeature("DepositPreauth");
|
||||
|
||||
} // ripple
|
||||
|
||||
@@ -198,6 +198,15 @@ getCheckIndex (AccountID const& account, std::uint32_t uSequence)
|
||||
std::uint32_t(uSequence));
|
||||
}
|
||||
|
||||
uint256
|
||||
getDepositPreauthIndex (AccountID const& owner, AccountID const& preauthorized)
|
||||
{
|
||||
return sha512Half(
|
||||
std::uint16_t(spaceDepositPreauth),
|
||||
owner,
|
||||
preauthorized);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace keylet {
|
||||
@@ -300,6 +309,13 @@ Keylet check_t::operator()(AccountID const& id,
|
||||
getCheckIndex(id, seq) };
|
||||
}
|
||||
|
||||
Keylet depositPreauth_t::operator()(AccountID const& owner,
|
||||
AccountID const& preauthorized) const
|
||||
{
|
||||
return { ltDEPOSIT_PREAUTH,
|
||||
getDepositPreauthIndex(owner, preauthorized) };
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Keylet unchecked (uint256 const& key)
|
||||
|
||||
@@ -168,6 +168,14 @@ LedgerFormats::LedgerFormats ()
|
||||
<< SOElement (sfPreviousTxnID, SOE_REQUIRED)
|
||||
<< SOElement (sfPreviousTxnLgrSeq, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
add ("DepositPreauth", ltDEPOSIT_PREAUTH)
|
||||
<< SOElement (sfAccount, SOE_REQUIRED)
|
||||
<< SOElement (sfAuthorize, SOE_REQUIRED)
|
||||
<< SOElement (sfOwnerNode, SOE_REQUIRED)
|
||||
<< SOElement (sfPreviousTxnID, SOE_REQUIRED)
|
||||
<< SOElement (sfPreviousTxnLgrSeq, SOE_REQUIRED)
|
||||
;
|
||||
}
|
||||
|
||||
void LedgerFormats::addCommonFields (Item& item)
|
||||
|
||||
@@ -220,6 +220,8 @@ SF_Account const sfAccount = make::one<SF_Account::type>(&sfAccount, STI
|
||||
SF_Account const sfOwner = make::one<SF_Account::type>(&sfOwner, STI_ACCOUNT, 2, "Owner");
|
||||
SF_Account const sfDestination = make::one<SF_Account::type>(&sfDestination, STI_ACCOUNT, 3, "Destination");
|
||||
SF_Account const sfIssuer = make::one<SF_Account::type>(&sfIssuer, STI_ACCOUNT, 4, "Issuer");
|
||||
SF_Account const sfAuthorize = make::one<SF_Account::type>(&sfAuthorize, STI_ACCOUNT, 5, "Authorize");
|
||||
SF_Account const sfUnauthorize = make::one<SF_Account::type>(&sfUnauthorize, STI_ACCOUNT, 6, "Unauthorize");
|
||||
SF_Account const sfTarget = make::one<SF_Account::type>(&sfTarget, STI_ACCOUNT, 7, "Target");
|
||||
SF_Account const sfRegularKey = make::one<SF_Account::type>(&sfRegularKey, STI_ACCOUNT, 8, "RegularKey");
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ transResults()
|
||||
{ tecCRYPTOCONDITION_ERROR, { "tecCRYPTOCONDITION_ERROR", "Malformed, invalid, or mismatched conditional or fulfillment." } },
|
||||
{ tecINVARIANT_FAILED, { "tecINVARIANT_FAILED", "One or more invariants for the transaction were not satisfied." } },
|
||||
{ tecEXPIRED, { "tecEXPIRED", "Expiration time is passed." } },
|
||||
{ tecDUPLICATE, { "tecDUPLICATE", "Ledger object already exists." } },
|
||||
|
||||
{ tefALREADY, { "tefALREADY", "The exact transaction was already in this ledger." } },
|
||||
{ tefBAD_ADD_AUTH, { "tefBAD_ADD_AUTH", "Not authorized to add account." } },
|
||||
@@ -138,6 +139,8 @@ transResults()
|
||||
{ temUNKNOWN, { "temUNKNOWN", "The transaction requires logic that is not implemented yet." } },
|
||||
{ temDISABLED, { "temDISABLED", "The transaction requires logic that is currently disabled." } },
|
||||
{ temBAD_TICK_SIZE, { "temBAD_TICK_SIZE", "Malformed: Tick size out of range." } },
|
||||
{ temINVALID_ACCOUNT_ID, { "temINVALID_ACCOUNT_ID", "Malformed: A field contains an invalid account ID." } },
|
||||
{ temCANNOT_PREAUTH_SELF, { "temCANNOT_PREAUTH_SELF", "Malformed: An account may not preauthorize itself." } },
|
||||
|
||||
{ terRETRY, { "terRETRY", "Retry transaction." } },
|
||||
{ terFUNDS_SPENT, { "terFUNDS_SPENT", "Can't set password, password set funds already spent." } },
|
||||
|
||||
@@ -156,6 +156,11 @@ TxFormats::TxFormats ()
|
||||
add ("CheckCancel", ttCHECK_CANCEL)
|
||||
<< SOElement (sfCheckID, SOE_REQUIRED)
|
||||
;
|
||||
|
||||
add ("DepositPreauth", ttDEPOSIT_PREAUTH)
|
||||
<< SOElement (sfAuthorize, SOE_OPTIONAL)
|
||||
<< SOElement (sfUnauthorize, SOE_OPTIONAL)
|
||||
;
|
||||
}
|
||||
|
||||
void TxFormats::addCommonFields (Item& item)
|
||||
|
||||
Reference in New Issue
Block a user