mirror of
https://github.com/XRPLF/rippled.git
synced 2026-10-11 22:28:02 +00:00
Compare commits
4 Commits
nb-seriali
...
mvadari/re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
efe43738fb | ||
|
|
70e648aa39 | ||
|
|
7095c25f47 | ||
|
|
1c589f96a7 |
@@ -7,6 +7,7 @@
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/LedgerFormats.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -27,6 +28,30 @@ public:
|
||||
: Base(keylet::did(account), view, j)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a new DID into the ledger, links it into the owner's directory
|
||||
* and increments the owner count.
|
||||
*
|
||||
* Call newSLE() and set the DID fields first.
|
||||
*
|
||||
* @param owner The account that owns the DID
|
||||
* @return tesSUCCESS, or tecINSUFFICIENT_RESERVE / tecDIR_FULL on failure
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
addToLedger(AccountID const& owner)
|
||||
requires Base::kIsWritable;
|
||||
|
||||
/**
|
||||
* Removes the DID from the owner's directory, decrements the owner count
|
||||
* and erases the DID from the ledger.
|
||||
*
|
||||
* @param owner The account that owns the DID
|
||||
* @return tesSUCCESS, or tefBAD_LEDGER / tecINTERNAL on failure
|
||||
*/
|
||||
[[nodiscard]] TER
|
||||
removeFromLedger(AccountID const& owner)
|
||||
requires Base::kIsWritable;
|
||||
};
|
||||
|
||||
using DIDEntryR = DIDEntry<ReadView>;
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
@@ -26,12 +23,6 @@ public:
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
deleteSLE(ApplyContext& ctx, Keylet sleKeylet, AccountID const owner);
|
||||
|
||||
static TER
|
||||
deleteSLE(ApplyView& view, SLE::pointer sle, AccountID const owner, beast::Journal j);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
|
||||
|
||||
84
src/libxrpl/ledger/entries/DIDEntry.cpp
Normal file
84
src/libxrpl/ledger/entries/DIDEntry.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#include <xrpl/ledger/entries/DIDEntry.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
template <typename ViewT>
|
||||
TER
|
||||
DIDEntry<ViewT>::addToLedger(AccountID const& owner)
|
||||
requires Base::kIsWritable
|
||||
{
|
||||
auto& view = this->applyView();
|
||||
auto const j = this->journal();
|
||||
|
||||
auto const sleAccount = view.peek(keylet::account(owner));
|
||||
if (!sleAccount)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
// Check reserve availability for new object creation
|
||||
{
|
||||
auto const balance = STAmount((*sleAccount)[sfBalance]).xrp();
|
||||
auto const reserve = accountReserve(view, sleAccount, j, {.ownerCountDelta = 1});
|
||||
|
||||
if (balance < reserve)
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
}
|
||||
|
||||
// Add ledger object to ledger
|
||||
this->insert();
|
||||
|
||||
// Add ledger object to owner's page
|
||||
{
|
||||
auto page = view.dirInsert(keylet::ownerDir(owner), this->key(), describeOwnerDir(owner));
|
||||
if (!page)
|
||||
return tecDIR_FULL; // LCOV_EXCL_LINE
|
||||
(**this)[sfOwnerNode] = *page;
|
||||
}
|
||||
increaseOwnerCount(view, sleAccount, {}, 1, j);
|
||||
view.update(sleAccount);
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
template <typename ViewT>
|
||||
TER
|
||||
DIDEntry<ViewT>::removeFromLedger(AccountID const& owner)
|
||||
requires Base::kIsWritable
|
||||
{
|
||||
auto& view = this->applyView();
|
||||
auto const j = this->journal();
|
||||
|
||||
// Remove object from owner directory
|
||||
if (!view.dirRemove(keylet::ownerDir(owner), (**this)[sfOwnerNode], this->key(), true))
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
JLOG(j.fatal()) << "Unable to delete DID from owner.";
|
||||
return tefBAD_LEDGER;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
auto const sleOwner = view.peek(keylet::account(owner));
|
||||
if (!sleOwner)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
decreaseOwnerCountForObject(view, sleOwner, this->mutableRawSle(), 1, j);
|
||||
|
||||
// Remove object from ledger
|
||||
this->erase();
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
template class DIDEntry<ReadView>;
|
||||
template class DIDEntry<ApplyView>;
|
||||
|
||||
} // namespace xrpl
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/View.h>
|
||||
#include <xrpl/ledger/entries/DIDEntry.h>
|
||||
#include <xrpl/ledger/helpers/CredentialHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/ledger/helpers/NFTokenHelpers.h>
|
||||
@@ -27,7 +28,6 @@
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
#include <xrpl/tx/transactors/account/SignerListSet.h>
|
||||
#include <xrpl/tx/transactors/delegate/DelegateSet.h>
|
||||
#include <xrpl/tx/transactors/did/DIDDelete.h>
|
||||
#include <xrpl/tx/transactors/oracle/OracleDelete.h>
|
||||
#include <xrpl/tx/transactors/payment/DepositPreauth.h>
|
||||
|
||||
@@ -143,10 +143,10 @@ removeDIDFromLedger(
|
||||
ApplyView& view,
|
||||
AccountID const& account,
|
||||
UInt256 const& delIndex,
|
||||
SLE::Ref sleDel,
|
||||
SLE::Ref,
|
||||
beast::Journal j)
|
||||
{
|
||||
return DIDDelete::deleteSLE(view, sleDel, account, j);
|
||||
return DIDEntryW(Keylet(ltDID, delIndex), view, j).removeFromLedger(account);
|
||||
}
|
||||
|
||||
TER
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
#include <xrpl/tx/transactors/did/DIDDelete.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/core/ServiceRegistry.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/Keylet.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/ledger/entries/DIDEntry.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
@@ -24,43 +18,14 @@ DIDDelete::preflight(PreflightContext const& ctx)
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
TER
|
||||
DIDDelete::deleteSLE(ApplyContext& ctx, Keylet sleKeylet, AccountID const owner)
|
||||
{
|
||||
auto const sle = ctx.view().peek(sleKeylet);
|
||||
if (!sle)
|
||||
return tecNO_ENTRY;
|
||||
|
||||
return DIDDelete::deleteSLE(ctx.view(), sle, owner, ctx.journal);
|
||||
}
|
||||
|
||||
TER
|
||||
DIDDelete::deleteSLE(ApplyView& view, SLE::pointer sle, AccountID const owner, beast::Journal j)
|
||||
{
|
||||
// Remove object from owner directory
|
||||
if (!view.dirRemove(keylet::ownerDir(owner), (*sle)[sfOwnerNode], sle->key(), true))
|
||||
{
|
||||
// LCOV_EXCL_START
|
||||
JLOG(j.fatal()) << "Unable to delete DID from owner.";
|
||||
return tefBAD_LEDGER;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
|
||||
auto const sleOwner = view.peek(keylet::account(owner));
|
||||
if (!sleOwner)
|
||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
decreaseOwnerCountForObject(view, sleOwner, sle, 1, j);
|
||||
|
||||
// Remove object from ledger
|
||||
view.erase(sle);
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
TER
|
||||
DIDDelete::doApply()
|
||||
{
|
||||
return deleteSLE(ctx_, keylet::did(accountID_), accountID_);
|
||||
DIDEntryW sleDID(accountID_, ctx_.view(), ctx_.journal);
|
||||
if (!sleDID)
|
||||
return tecNO_ENTRY;
|
||||
|
||||
return sleDID.removeFromLedger(accountID_);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -3,12 +3,8 @@
|
||||
#include <xrpl/core/ServiceRegistry.h>
|
||||
#include <xrpl/ledger/ApplyView.h>
|
||||
#include <xrpl/ledger/ReadView.h>
|
||||
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
|
||||
#include <xrpl/ledger/helpers/DirectoryHelpers.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/ledger/entries/DIDEntry.h>
|
||||
#include <xrpl/protocol/Feature.h>
|
||||
#include <xrpl/protocol/Indexes.h>
|
||||
#include <xrpl/protocol/Keylet.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
@@ -19,7 +15,6 @@
|
||||
#include <xrpl/tx/Transactor.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
|
||||
namespace xrpl {
|
||||
|
||||
@@ -62,46 +57,12 @@ DIDSet::preflight(PreflightContext const& ctx)
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
static TER
|
||||
addSLE(ApplyContext& ctx, SLE::Ref sle, AccountID const& owner)
|
||||
{
|
||||
auto const sleAccount = ctx.view().peek(keylet::account(owner));
|
||||
if (!sleAccount)
|
||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||
|
||||
// Check reserve availability for new object creation
|
||||
{
|
||||
auto const balance = STAmount((*sleAccount)[sfBalance]).xrp();
|
||||
auto const reserve =
|
||||
accountReserve(ctx.view(), sleAccount, ctx.journal, {.ownerCountDelta = 1});
|
||||
|
||||
if (balance < reserve)
|
||||
return tecINSUFFICIENT_RESERVE;
|
||||
}
|
||||
|
||||
// Add ledger object to ledger
|
||||
ctx.view().insert(sle);
|
||||
|
||||
// Add ledger object to owner's page
|
||||
{
|
||||
auto page =
|
||||
ctx.view().dirInsert(keylet::ownerDir(owner), sle->key(), describeOwnerDir(owner));
|
||||
if (!page)
|
||||
return tecDIR_FULL; // LCOV_EXCL_LINE
|
||||
(*sle)[sfOwnerNode] = *page;
|
||||
}
|
||||
increaseOwnerCount(ctx.view(), sleAccount, {}, 1, ctx.journal);
|
||||
ctx.view().update(sleAccount);
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
TER
|
||||
DIDSet::doApply()
|
||||
{
|
||||
// Edit ledger object if it already exists
|
||||
Keylet const didKeylet = keylet::did(accountID_);
|
||||
if (auto const sleDID = ctx_.view().peek(didKeylet))
|
||||
DIDEntryW sleDID(accountID_, ctx_.view(), ctx_.journal);
|
||||
if (sleDID)
|
||||
{
|
||||
auto update = [&](auto const& sField) {
|
||||
if (auto const field = ctx_.tx[~sField])
|
||||
@@ -125,12 +86,12 @@ DIDSet::doApply()
|
||||
{
|
||||
return tecEMPTY_DID;
|
||||
}
|
||||
ctx_.view().update(sleDID);
|
||||
sleDID.update();
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
// Create new ledger object otherwise
|
||||
auto const sleDID = std::make_shared<SLE>(didKeylet);
|
||||
sleDID.newSLE();
|
||||
(*sleDID)[sfAccount] = accountID_;
|
||||
|
||||
auto set = [&](auto const& sField) {
|
||||
@@ -147,7 +108,7 @@ DIDSet::doApply()
|
||||
return tecEMPTY_DID;
|
||||
}
|
||||
|
||||
return addSLE(ctx_, sleDID, accountID_);
|
||||
return sleDID.addToLedger(accountID_);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user