mirror of
https://github.com/XRPLF/rippled.git
synced 2026-10-11 14:18:07 +00:00
Compare commits
7 Commits
bthomee/rp
...
mvadari/re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d8f73794f | ||
|
|
0872ef04f3 | ||
|
|
39390ad40e | ||
|
|
66a4f59c9e | ||
|
|
63ffb130ec | ||
|
|
000596c262 | ||
|
|
b1a1dde2a6 |
@@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
@@ -9,6 +11,11 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -39,6 +46,44 @@ public:
|
||||
: Base(keylet::credential(credentialID), view, j)
|
||||
{
|
||||
}
|
||||
|
||||
// Check if the credential's sfExpiration field has passed the given
|
||||
// ledger close time.
|
||||
[[nodiscard]] bool
|
||||
isExpired(NetClock::time_point const& closed) const
|
||||
{
|
||||
std::uint32_t const exp =
|
||||
Base::operator*()[~sfExpiration].value_or(std::numeric_limits<std::uint32_t>::max());
|
||||
std::uint32_t const now = closed.time_since_epoch().count();
|
||||
return now > exp;
|
||||
}
|
||||
|
||||
// Remove this credential's SLE from the ledger: delete it from the
|
||||
// issuer's (and, unless it is the same account, the subject's) owner
|
||||
// directory, adjust owner counts, and erase the SLE.
|
||||
[[nodiscard]] TER
|
||||
removeFromLedger()
|
||||
requires Base::kIsWritable;
|
||||
|
||||
// Check whether this credential belongs to src and is accepted.
|
||||
// Expiration is checked separately by isExpired().
|
||||
[[nodiscard]] TER
|
||||
isValid(AccountID const& src) const
|
||||
{
|
||||
if (Base::operator->()->getAccountID(sfSubject) != src)
|
||||
{
|
||||
JLOG(this->journal().trace()) << "Credential doesn't belong to the source account.";
|
||||
return tecBAD_CREDENTIALS;
|
||||
}
|
||||
|
||||
if (!Base::operator->()->isFlag(lsfAccepted))
|
||||
{
|
||||
JLOG(this->journal().trace()) << "Credential isn't accepted.";
|
||||
return tecBAD_CREDENTIALS;
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
};
|
||||
|
||||
using CredentialEntryR = CredentialEntry<ReadView>;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
@@ -25,14 +24,6 @@ namespace credentials {
|
||||
// (and any future pre-authorization modes) as part of authorization (all the
|
||||
// transfer funds transactions)
|
||||
|
||||
// Check if credential sfExpiration field has passed ledger's parentCloseTime
|
||||
bool
|
||||
checkExpired(SLE const& sleCredential, NetClock::time_point const& closed);
|
||||
|
||||
// Actually remove a credentials object from the ledger
|
||||
[[nodiscard]] TER
|
||||
deleteSLE(ApplyView& view, SLE::Ref sleCredential, beast::Journal j);
|
||||
|
||||
// Amendment and parameters checks for sfCredentialIDs field
|
||||
NotTEC
|
||||
checkFields(STTx const& tx, Rules const& rules, beast::Journal j);
|
||||
|
||||
77
src/libxrpl/ledger/entries/CredentialEntry.cpp
Normal file
77
src/libxrpl/ledger/entries/CredentialEntry.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#include <xrpl/ledger/entries/CredentialEntry.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
template <typename ViewT>
|
||||
TER
|
||||
CredentialEntry<ViewT>::removeFromLedger()
|
||||
requires Base::kIsWritable
|
||||
{
|
||||
if (!this->exists())
|
||||
return tecNO_ENTRY;
|
||||
|
||||
auto delSLE = [this](AccountID const& account, SField const& node, bool isOwner) -> TER {
|
||||
auto const sleAccount = this->applyView().peek(keylet::account(account));
|
||||
if (!sleAccount)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
JLOG(this->journal().fatal()) << "Internal error: can't retrieve Owner account.";
|
||||
return tecINTERNAL;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
std::uint64_t const page = Base::operator->()->getFieldU64(node);
|
||||
if (!this->applyView().dirRemove(keylet::ownerDir(account), page, this->key(), false))
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
JLOG(this->journal().fatal()) << "Unable to delete Credential from owner.";
|
||||
return tefBAD_LEDGER;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
if (isOwner)
|
||||
{
|
||||
decreaseOwnerCountForObject(
|
||||
this->applyView(), sleAccount, this->mutableRawSle(), 1, this->journal());
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
};
|
||||
|
||||
auto const issuer = Base::operator->()->getAccountID(sfIssuer);
|
||||
auto const subject = Base::operator->()->getAccountID(sfSubject);
|
||||
bool const accepted = Base::operator->()->isFlag(lsfAccepted);
|
||||
|
||||
auto err = delSLE(issuer, sfIssuerNode, !accepted || (subject == issuer));
|
||||
if (!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
if (subject != issuer)
|
||||
{
|
||||
err = delSLE(subject, sfSubjectNode, accepted);
|
||||
if (!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
|
||||
// Remove object from ledger
|
||||
this->erase();
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
template class CredentialEntry<ReadView>;
|
||||
template class CredentialEntry<ApplyView>;
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -3,11 +3,10 @@
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/entries/CredentialEntry.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -23,9 +22,7 @@
|
||||
#include <xrpl/protocol/digest.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <limits>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
@@ -34,15 +31,6 @@
|
||||
namespace xrpl {
|
||||
namespace credentials {
|
||||
|
||||
bool
|
||||
checkExpired(SLE const& sleCredential, NetClock::time_point const& closed)
|
||||
{
|
||||
std::uint32_t const exp =
|
||||
sleCredential[~sfExpiration].value_or(std::numeric_limits<std::uint32_t>::max());
|
||||
std::uint32_t const now = closed.time_since_epoch().count();
|
||||
return now > exp;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
static std::expected<bool, TER>
|
||||
removeExpired(ApplyView& view, STVector256 const& arr, beast::Journal const j)
|
||||
@@ -56,14 +44,13 @@ removeExpired(ApplyView& view, STVector256 const& arr, beast::Journal const j)
|
||||
if (view.rules().enabled(fixCleanup3_4_0) && h.isZero())
|
||||
return std::unexpected(tecINTERNAL); // LCOV_EXCL_LINE
|
||||
|
||||
auto const k = keylet::credential(h);
|
||||
auto const sleCred = view.peek(k);
|
||||
CredentialEntryW sleCred(h, view, j);
|
||||
|
||||
if (sleCred && checkExpired(*sleCred, closeTime))
|
||||
if (sleCred && sleCred.isExpired(closeTime))
|
||||
{
|
||||
JLOG(j.trace()) << "Credentials are expired. Cred: " << sleCred->getText();
|
||||
// delete expired credentials even if the transaction failed
|
||||
auto const err = deleteSLE(view, sleCred, j);
|
||||
auto const err = sleCred.removeFromLedger();
|
||||
if (view.rules().enabled(fixCleanup3_1_3) && !isTesSuccess(err))
|
||||
return std::unexpected(err);
|
||||
foundExpired = true;
|
||||
@@ -73,60 +60,6 @@ removeExpired(ApplyView& view, STVector256 const& arr, beast::Journal const j)
|
||||
return foundExpired;
|
||||
}
|
||||
|
||||
TER
|
||||
deleteSLE(ApplyView& view, SLE::Ref sleCredential, beast::Journal j)
|
||||
{
|
||||
if (!sleCredential)
|
||||
return tecNO_ENTRY;
|
||||
|
||||
auto delSLE = [&view, &sleCredential, j](
|
||||
AccountID const& account, SField const& node, bool isOwner) -> TER {
|
||||
auto const sleAccount = view.peek(keylet::account(account));
|
||||
if (!sleAccount)
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
JLOG(j.fatal()) << "Internal error: can't retrieve Owner account.";
|
||||
return tecINTERNAL;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
// Remove object from owner directory
|
||||
std::uint64_t const page = sleCredential->getFieldU64(node);
|
||||
if (!view.dirRemove(keylet::ownerDir(account), page, sleCredential->key(), false))
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
JLOG(j.fatal()) << "Unable to delete Credential from owner.";
|
||||
return tefBAD_LEDGER;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
if (isOwner)
|
||||
decreaseOwnerCountForObject(view, sleAccount, sleCredential, 1, j);
|
||||
|
||||
return tesSUCCESS;
|
||||
};
|
||||
|
||||
auto const issuer = sleCredential->getAccountID(sfIssuer);
|
||||
auto const subject = sleCredential->getAccountID(sfSubject);
|
||||
bool const accepted = sleCredential->isFlag(lsfAccepted);
|
||||
|
||||
auto err = delSLE(issuer, sfIssuerNode, !accepted || (subject == issuer));
|
||||
if (!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
if (subject != issuer)
|
||||
{
|
||||
err = delSLE(subject, sfSubjectNode, accepted);
|
||||
if (!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
|
||||
// Remove object from ledger
|
||||
view.erase(sleCredential);
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
NotTEC
|
||||
checkFields(STTx const& tx, Rules const& rules, beast::Journal j)
|
||||
{
|
||||
@@ -179,24 +112,15 @@ valid(STTx const& tx, ReadView const& view, AccountID const& src, beast::Journal
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
auto const sleCred = view.read(keylet::credential(h));
|
||||
CredentialEntryR const sleCred(h, view, j);
|
||||
if (!sleCred)
|
||||
{
|
||||
JLOG(j.trace()) << "Credential doesn't exist. Cred: " << h;
|
||||
return tecBAD_CREDENTIALS;
|
||||
}
|
||||
|
||||
if (sleCred->getAccountID(sfSubject) != src)
|
||||
{
|
||||
JLOG(j.trace()) << "Credential doesn't belong to the source account. Cred: " << h;
|
||||
return tecBAD_CREDENTIALS;
|
||||
}
|
||||
|
||||
if (!sleCred->isFlag(lsfAccepted))
|
||||
{
|
||||
JLOG(j.trace()) << "Credential isn't accepted. Cred: " << h;
|
||||
return tecBAD_CREDENTIALS;
|
||||
}
|
||||
if (auto const err = sleCred.isValid(src); !isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
// Expiration checks are in doApply
|
||||
}
|
||||
@@ -218,8 +142,7 @@ validDomain(ReadView const& view, UInt256 domainID, AccountID const& subject)
|
||||
{
|
||||
auto const issuer = h.getAccountID(sfIssuer);
|
||||
auto const type = h.getFieldVL(sfCredentialType);
|
||||
auto const keyletCredential = keylet::credential(subject, issuer, makeSlice(type));
|
||||
auto const sleCredential = view.read(keyletCredential);
|
||||
CredentialEntryR const sleCredential(subject, issuer, makeSlice(type), view);
|
||||
|
||||
// We cannot delete expired credentials, that would require ApplyView&
|
||||
// However we can check if credentials are expired. Expected transaction
|
||||
@@ -228,7 +151,7 @@ validDomain(ReadView const& view, UInt256 domainID, AccountID const& subject)
|
||||
// allows expired credentials to be deleted by any transaction.
|
||||
if (sleCredential)
|
||||
{
|
||||
if (checkExpired(*sleCredential, closeTime))
|
||||
if (sleCredential.isExpired(closeTime))
|
||||
{
|
||||
foundExpired = true;
|
||||
continue;
|
||||
@@ -249,14 +172,14 @@ TER
|
||||
authorizedDepositPreauth(ReadView const& view, STVector256 const& credIDs, AccountID const& dst)
|
||||
{
|
||||
std::set<std::pair<AccountID, Slice>> sorted;
|
||||
std::vector<SLE::const_pointer> lifeExtender;
|
||||
std::vector<CredentialEntryR> lifeExtender;
|
||||
lifeExtender.reserve(credIDs.size());
|
||||
for (auto const& h : credIDs)
|
||||
{
|
||||
if (view.rules().enabled(fixCleanup3_4_0) && h.isZero())
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
auto sleCred = view.read(keylet::credential(h));
|
||||
CredentialEntryR sleCred(h, view);
|
||||
if (!sleCred) // already checked in preclaim
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -356,7 +279,7 @@ verifyValidDomain(ApplyView& view, AccountID const& account, UInt256 domainID, b
|
||||
|
||||
for (auto const& h : credentials)
|
||||
{
|
||||
auto sleCredential = view.read(keylet::credential(h));
|
||||
CredentialEntryR const sleCredential(h, view);
|
||||
if (!sleCredential)
|
||||
continue; // expired, i.e. deleted in credentials::removeExpired
|
||||
|
||||
|
||||
@@ -6,12 +6,13 @@
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/entries/CredentialEntry.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STArray.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -42,12 +43,12 @@ accountInDomain(ReadView const& view, AccountID const& account, Domain const& do
|
||||
auto const& credentials = sleDomain->getFieldArray(sfAcceptedCredentials);
|
||||
|
||||
bool const inDomain = std::ranges::any_of(credentials, [&](auto const& credential) {
|
||||
auto const sleCred = view.read(
|
||||
keylet::credential(account, credential[sfIssuer], credential[sfCredentialType]));
|
||||
CredentialEntryR const sleCred(
|
||||
account, credential[sfIssuer], credential[sfCredentialType], view);
|
||||
if (!sleCred || !sleCred->isFlag(lsfAccepted))
|
||||
return false;
|
||||
|
||||
return !credentials::checkExpired(*sleCred, view.header().parentCloseTime);
|
||||
return !sleCred.isExpired(view.header().parentCloseTime);
|
||||
});
|
||||
|
||||
return inDomain;
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#include <xrpl/json/to_string.h> // IWYU pragma: keep
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/entries/CredentialEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DelegateHelpers.h>
|
||||
#include <xrpl/ledger/helpers/NFTokenHelpers.h>
|
||||
#include <xrpl/ledger/helpers/OfferHelpers.h>
|
||||
@@ -1250,9 +1250,9 @@ removeExpiredCredentials(ApplyView& view, std::vector<UInt256> const& creds, bea
|
||||
{
|
||||
for (auto const& index : creds)
|
||||
{
|
||||
if (auto const sle = view.peek(keylet::credential(index)))
|
||||
if (auto sle = CredentialEntryW(index, view, viewJ))
|
||||
{
|
||||
if (auto const ter = credentials::deleteSLE(view, sle, viewJ); !isTesSuccess(ter))
|
||||
if (auto const ter = sle.removeFromLedger(); !isTesSuccess(ter))
|
||||
{
|
||||
JLOG(viewJ.error())
|
||||
<< "removeExpiredCredentials: failed to delete expired credential. Err: "
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/CredentialEntry.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/NFTokenHelpers.h>
|
||||
@@ -166,11 +167,12 @@ removeCredentialFromLedger(
|
||||
ServiceRegistry&,
|
||||
ApplyView& view,
|
||||
AccountID const&,
|
||||
UInt256 const&,
|
||||
SLE::Ref sleDel,
|
||||
UInt256 const& delIndex,
|
||||
SLE::Ref,
|
||||
beast::Journal j)
|
||||
{
|
||||
return credentials::deleteSLE(view, sleDel, j);
|
||||
CredentialEntryW sleDel(delIndex, view, j);
|
||||
return sleDel.removeFromLedger();
|
||||
}
|
||||
|
||||
TER
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/entries/CredentialEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/SponsorHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
@@ -22,8 +22,6 @@
|
||||
#include <cstdint>
|
||||
namespace xrpl {
|
||||
|
||||
using namespace credentials;
|
||||
|
||||
std::uint32_t
|
||||
CredentialAccept::getFlagsMask(PreflightContext const& ctx)
|
||||
{
|
||||
@@ -63,7 +61,7 @@ CredentialAccept::preclaim(PreclaimContext const& ctx)
|
||||
return tecNO_ISSUER;
|
||||
}
|
||||
|
||||
auto const sleCred = ctx.view.read(keylet::credential(subject, issuer, credType));
|
||||
CredentialEntryR const sleCred(subject, issuer, credType, ctx.view);
|
||||
if (!sleCred)
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "No credential: " << to_string(subject) << ", " << to_string(issuer)
|
||||
@@ -108,16 +106,15 @@ CredentialAccept::doApply()
|
||||
return ret;
|
||||
|
||||
auto const credType(ctx_.tx[sfCredentialType]);
|
||||
Keylet const credentialKey = keylet::credential(accountID_, issuer, credType);
|
||||
auto const sleCred = view().peek(credentialKey); // Checked in preclaim()
|
||||
CredentialEntryW sleCred(accountID_, issuer, credType, view(), j_); // Checked in preclaim()
|
||||
if (!sleCred)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
if (checkExpired(*sleCred, view().header().parentCloseTime))
|
||||
if (sleCred.isExpired(view().header().parentCloseTime))
|
||||
{
|
||||
JLOG(j_.trace()) << "Credential is expired: " << sleCred->getText();
|
||||
// delete expired credentials even if the transaction failed
|
||||
auto const err = credentials::deleteSLE(view(), sleCred, j_);
|
||||
auto const err = sleCred.removeFromLedger();
|
||||
return isTesSuccess(err) ? tecEXPIRED : err;
|
||||
}
|
||||
|
||||
@@ -126,12 +123,12 @@ CredentialAccept::doApply()
|
||||
// Release the original creation sponsor from the credential (it covered
|
||||
// the issuer's reserve), then assign the accept tx's sponsor (if any) so
|
||||
// the credential reflects whoever is now covering the subject's reserve.
|
||||
decreaseOwnerCountForObject(view(), sleIssuer, sleCred, 1, j_);
|
||||
removeSponsorFromLedgerEntry(sleCred);
|
||||
decreaseOwnerCountForObject(view(), sleIssuer, sleCred.mutableRawSle(), 1, j_);
|
||||
removeSponsorFromLedgerEntry(sleCred.mutableRawSle());
|
||||
|
||||
addSponsorToLedgerEntry(ctx_.getApplyViewContext(), sleCred);
|
||||
addSponsorToLedgerEntry(ctx_.getApplyViewContext(), sleCred.mutableRawSle());
|
||||
increaseOwnerCount(ctx_.getApplyViewContext(), sleSubject, 1, j_);
|
||||
view().update(sleCred);
|
||||
sleCred.update();
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/entries/CredentialEntry.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h> // IWYU pragma: keep
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
@@ -114,7 +115,8 @@ CredentialCreate::doApply()
|
||||
auto const credType(ctx_.tx[sfCredentialType]);
|
||||
Keylet const credentialKey = keylet::credential(subject, accountID_, credType);
|
||||
|
||||
auto const sleCred = std::make_shared<SLE>(credentialKey);
|
||||
CredentialEntryW sleCred(credentialKey, view(), j_);
|
||||
sleCred.newSLE();
|
||||
if (!sleCred)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
@@ -160,7 +162,7 @@ CredentialCreate::doApply()
|
||||
sleCred->setFieldU64(sfIssuerNode, *page);
|
||||
|
||||
increaseOwnerCount(ctx_.getApplyViewContext(), sleIssuer, 1, j_);
|
||||
addSponsorToLedgerEntry(ctx_.getApplyViewContext(), sleCred);
|
||||
addSponsorToLedgerEntry(ctx_.getApplyViewContext(), sleCred.mutableRawSle());
|
||||
}
|
||||
|
||||
if (subject == accountID_)
|
||||
@@ -180,7 +182,7 @@ CredentialCreate::doApply()
|
||||
sleCred->setFieldU64(sfSubjectNode, *page);
|
||||
}
|
||||
|
||||
view().insert(sleCred);
|
||||
sleCred.insert();
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/entries/CredentialEntry.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -18,8 +18,6 @@
|
||||
#include <cstdint>
|
||||
namespace xrpl {
|
||||
|
||||
using namespace credentials;
|
||||
|
||||
std::uint32_t
|
||||
CredentialDelete::getFlagsMask(PreflightContext const& ctx)
|
||||
{
|
||||
@@ -80,18 +78,18 @@ CredentialDelete::doApply()
|
||||
auto const issuer = ctx_.tx[~sfIssuer].value_or(accountID_);
|
||||
|
||||
auto const credType(ctx_.tx[sfCredentialType]);
|
||||
auto const sleCred = view().peek(keylet::credential(subject, issuer, credType));
|
||||
CredentialEntryW sleCred(subject, issuer, credType, view(), j_);
|
||||
if (!sleCred)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
if ((subject != accountID_) && (issuer != accountID_) &&
|
||||
!checkExpired(*sleCred, ctx_.view().header().parentCloseTime))
|
||||
!sleCred.isExpired(ctx_.view().header().parentCloseTime))
|
||||
{
|
||||
JLOG(j_.trace()) << "Can't delete non-expired credential.";
|
||||
return tecNO_PERMISSION;
|
||||
}
|
||||
|
||||
return deleteSLE(view(), sleCred, j_);
|
||||
return sleCred.removeFromLedger();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -16,11 +16,14 @@
|
||||
#include <test/jtx/txflags.h>
|
||||
#include <test/jtx/vault.h>
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/basics/strHex.h>
|
||||
#include <xrpl/beast/unit_test/suite.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/json/to_string.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ApplyViewImpl.h>
|
||||
#include <xrpl/ledger/entries/CredentialEntry.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
@@ -903,7 +906,8 @@ struct Credentials_test : public beast::unit_test::Suite
|
||||
testcase("deleteSLE fail, bad SLE.");
|
||||
auto view =
|
||||
std::make_shared<ApplyViewImpl>(env.current().get(), ApplyFlags::TapNone);
|
||||
auto ter = xrpl::credentials::deleteSLE(*view, {}, env.journal);
|
||||
CredentialEntryW sleCred(UInt256{}, *view);
|
||||
auto ter = sleCred.removeFromLedger();
|
||||
BEAST_EXPECT(ter == tecNO_ENTRY);
|
||||
}
|
||||
}
|
||||
@@ -1119,7 +1123,8 @@ struct Credentials_test : public beast::unit_test::Suite
|
||||
auto const sleCred = env.current()->read(credKeylet);
|
||||
BEAST_EXPECT(
|
||||
sleCred &&
|
||||
xrpl::credentials::checkExpired(*sleCred, env.current()->header().parentCloseTime));
|
||||
CredentialEntryR(sleCred, *env.current())
|
||||
.isExpired(env.current()->header().parentCloseTime));
|
||||
}
|
||||
|
||||
// Create an ApplyViewImpl on top of the current closed ledger
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <xrpl/ledger/entries/XChainOwnedClaimIDEntry.h> // IWYU pragma: keep
|
||||
#include <xrpl/ledger/entries/XChainOwnedCreateAccountClaimIDEntry.h> // IWYU pragma: keep
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
@@ -76,12 +77,22 @@ template class SLEBase<ApplyView>;
|
||||
#pragma push_macro("LEDGER_ENTRY")
|
||||
#undef LEDGER_ENTRY
|
||||
|
||||
// No explicit instantiation here, neither a definition nor a declaration.
|
||||
// A definition would instantiate an entry a second time once its member
|
||||
// bodies live in its own .cpp (MSVC rejects that with C4661 under /WX), and a
|
||||
// declaration (`extern template`) stops clang from emitting the inline
|
||||
// constructors of the header-only entries at -O0, which leaves them undefined
|
||||
// at link time in the debug builds. Naming the class in a static_assert is
|
||||
// enough to instantiate its definition, which is all this exhaustiveness
|
||||
// check needs; the per-type suites exercise the members.
|
||||
#define LEDGER_ENTRY(tag, value, name, ...) \
|
||||
template class name##Entry<ReadView>; \
|
||||
template class name##Entry<ApplyView>; \
|
||||
static_assert( \
|
||||
name##Entry<ReadView>::kEntryType == tag && name##Entry<ApplyView>::kEntryType == tag, \
|
||||
#name "Entry must be bound to " #tag);
|
||||
#name "Entry must be bound to " #tag); \
|
||||
static_assert( \
|
||||
std::is_constructible_v<name##Entry<ReadView>, Keylet const&, ReadView const&> && \
|
||||
std::is_constructible_v<name##Entry<ApplyView>, Keylet const&, ApplyView&>, \
|
||||
#name "Entry must be constructible from a Keylet and a view");
|
||||
|
||||
#include <xrpl/protocol/detail/ledger_entries.macro>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/entries/CredentialEntry.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/ErrorCodes.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
@@ -141,7 +141,7 @@ doDepositAuthorized(rpc::JsonContext& context)
|
||||
return result;
|
||||
}
|
||||
|
||||
if (credentials::checkExpired(*sleCred, ledger->header().parentCloseTime))
|
||||
if (CredentialEntryR(sleCred, *ledger).isExpired(ledger->header().parentCloseTime))
|
||||
{
|
||||
rpc::injectError(RpcBadCredentials, "credentials are expired", result);
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user