mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 02:55:50 +00:00
Return terADDRESS_COLLISION from preclaim if cannot allocate AccountID
This commit is contained in:
@@ -225,6 +225,8 @@ enum TERcodes : TERUnderlyingType {
|
||||
terQUEUED, // Transaction is being held in TxQ until fee drops
|
||||
terPRE_TICKET, // Ticket is not yet in ledger but might be on its way
|
||||
terNO_AMM, // AMM doesn't exist for the asset pair
|
||||
terADDRESS_COLLISION, // Failed to allocate AccountID when trying to
|
||||
// create a pseudo-account
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -231,6 +231,7 @@ transResults()
|
||||
MAKE_ERROR(terQUEUED, "Held until escalated fee drops."),
|
||||
MAKE_ERROR(terPRE_TICKET, "Ticket is not yet in ledger."),
|
||||
MAKE_ERROR(terNO_AMM, "AMM doesn't exist for the asset pair."),
|
||||
MAKE_ERROR(terADDRESS_COLLISION, "Failed to allocate an unique account address"),
|
||||
|
||||
MAKE_ERROR(tesSUCCESS, "The transaction was applied. Only final in a validated ledger."),
|
||||
};
|
||||
|
||||
@@ -119,6 +119,12 @@ VaultCreate::preclaim(PreclaimContext const& ctx)
|
||||
return tecOBJECT_NOT_FOUND;
|
||||
}
|
||||
|
||||
auto sequence = ctx.tx.getSeqValue();
|
||||
if (auto const accountId = pseudoAccountAddress(
|
||||
ctx.view, keylet::vault(account, sequence).key);
|
||||
accountId == beast::zero)
|
||||
return terADDRESS_COLLISION;
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -488,6 +488,9 @@ describeOwnerDir(AccountID const& account);
|
||||
[[nodiscard]] TER
|
||||
dirLink(ApplyView& view, AccountID const& owner, std::shared_ptr<SLE>& object);
|
||||
|
||||
AccountID
|
||||
pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey);
|
||||
|
||||
// Which of the owner-object fields should we set: sfAMMID, sfVaultID
|
||||
enum class PseudoAccountOwnerType : int { AMM, Vault };
|
||||
|
||||
|
||||
@@ -1037,29 +1037,31 @@ dirLink(ApplyView& view, AccountID const& owner, std::shared_ptr<SLE>& object)
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
Expected<std::shared_ptr<SLE>, TER>
|
||||
createPseudoAccount(
|
||||
ApplyView& view,
|
||||
uint256 const& pseudoOwnerKey,
|
||||
PseudoAccountOwnerType type)
|
||||
AccountID
|
||||
pseudoAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey)
|
||||
{
|
||||
auto const accountId = [&]() -> AccountID {
|
||||
AccountID ret = beast::zero;
|
||||
// This number must not be changed without an amendment
|
||||
constexpr int maxAccountAttempts = 256;
|
||||
for (auto i = 0; i < maxAccountAttempts; ++i)
|
||||
{
|
||||
ripesha_hasher rsh;
|
||||
auto const hash =
|
||||
sha512Half(i, view.info().parentHash, pseudoOwnerKey);
|
||||
auto const hash = sha512Half(i, view.info().parentHash, pseudoOwnerKey);
|
||||
rsh(hash.data(), hash.size());
|
||||
ret = static_cast<ripesha_hasher::result_type>(rsh);
|
||||
if (!view.read(keylet::account(ret)))
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}();
|
||||
}
|
||||
|
||||
Expected<std::shared_ptr<SLE>, TER>
|
||||
createPseudoAccount(
|
||||
ApplyView& view,
|
||||
uint256 const& pseudoOwnerKey,
|
||||
PseudoAccountOwnerType type)
|
||||
{
|
||||
auto const accountId = pseudoAccountAddress(view, pseudoOwnerKey);
|
||||
if (accountId == beast::zero)
|
||||
return Unexpected(tecDUPLICATE);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user