mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-13 15:45:54 +00:00
Demonstrate how strongly typed ledger objects work
Signed-off-by: JCW <a1q123456@users.noreply.github.com> # Conflicts: # include/xrpl/protocol/Keylet.h # src/libxrpl/protocol/Indexes.cpp # src/xrpld/rpc/handlers/VaultInfo.cpp
This commit is contained in:
@@ -157,7 +157,7 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
SeqProxy const acctSeq =
|
SeqProxy const acctSeq =
|
||||||
SeqProxy::sequence(sleAcct->getFieldU32(sfSequence));
|
SeqProxy::sequence(sleAcct.fsfSequence());
|
||||||
SeqProxy const seqProx = txn.getSeqProxy();
|
SeqProxy const seqProx = txn.getSeqProxy();
|
||||||
|
|
||||||
if (seqProx.isSeq())
|
if (seqProx.isSeq())
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ authorizedDepositPreauth(
|
|||||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||||
|
|
||||||
auto [it, ins] =
|
auto [it, ins] =
|
||||||
sorted.emplace((*sleCred)[sfIssuer], (*sleCred)[sfCredentialType]);
|
sorted.emplace(sleCred.fsfIssuer(), sleCred.fsfCredentialType());
|
||||||
if (!ins)
|
if (!ins)
|
||||||
return tefINTERNAL; // LCOV_EXCL_LINE
|
return tefINTERNAL; // LCOV_EXCL_LINE
|
||||||
lifeExtender.push_back(std::move(sleCred));
|
lifeExtender.push_back(std::move(sleCred));
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ accountInDomain(
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// domain owner is in the domain
|
// domain owner is in the domain
|
||||||
if (sleDomain->getAccountID(sfOwner) == account)
|
if (sleDomain.fsfOwner() == account)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
auto const& credentials = sleDomain->getFieldArray(sfAcceptedCredentials);
|
auto const& credentials = sleDomain.fsfAcceptedCredentials();
|
||||||
|
|
||||||
bool const inDomain = std::any_of(
|
bool const inDomain = std::any_of(
|
||||||
credentials.begin(), credentials.end(), [&](auto const& credential) {
|
credentials.begin(), credentials.end(), [&](auto const& credential) {
|
||||||
@@ -67,20 +67,20 @@ offerInDomain(
|
|||||||
// have any of the following wrong behavior
|
// have any of the following wrong behavior
|
||||||
if (!sleOffer)
|
if (!sleOffer)
|
||||||
return false; // LCOV_EXCL_LINE
|
return false; // LCOV_EXCL_LINE
|
||||||
if (!sleOffer->isFieldPresent(sfDomainID))
|
if (!sleOffer.fsfDomainID().has_value())
|
||||||
return false; // LCOV_EXCL_LINE
|
return false; // LCOV_EXCL_LINE
|
||||||
if (sleOffer->getFieldH256(sfDomainID) != domainID)
|
if (sleOffer.fsfDomainID() != domainID)
|
||||||
return false; // LCOV_EXCL_LINE
|
return false; // LCOV_EXCL_LINE
|
||||||
|
|
||||||
if (sleOffer->isFlag(lsfHybrid) &&
|
if (sleOffer->isFlag(lsfHybrid) &&
|
||||||
!sleOffer->isFieldPresent(sfAdditionalBooks))
|
!sleOffer.fsfAdditionalBooks())
|
||||||
{
|
{
|
||||||
JLOG(j.error()) << "Hybrid offer " << offerID
|
JLOG(j.error()) << "Hybrid offer " << offerID
|
||||||
<< " missing AdditionalBooks field";
|
<< " missing AdditionalBooks field";
|
||||||
return false; // LCOV_EXCL_LINE
|
return false; // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
|
|
||||||
return accountInDomain(view, sleOffer->getAccountID(sfAccount), domainID);
|
return accountInDomain(view, sleOffer.fsfAccount(), domainID);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace permissioned_dex
|
} // namespace permissioned_dex
|
||||||
|
|||||||
@@ -215,14 +215,14 @@ ammAccountHolds(
|
|||||||
if (isXRP(issue))
|
if (isXRP(issue))
|
||||||
{
|
{
|
||||||
if (auto const sle = view.read(keylet::account(ammAccountID)))
|
if (auto const sle = view.read(keylet::account(ammAccountID)))
|
||||||
return (*sle)[sfBalance];
|
return sle.fsfBalance();
|
||||||
}
|
}
|
||||||
else if (auto const sle = view.read(
|
else if (auto const sle = view.read(
|
||||||
keylet::line(ammAccountID, issue.account, issue.currency));
|
keylet::line(ammAccountID, issue.account, issue.currency));
|
||||||
sle &&
|
sle &&
|
||||||
!isFrozen(view, ammAccountID, issue.currency, issue.account))
|
!isFrozen(view, ammAccountID, issue.currency, issue.account))
|
||||||
{
|
{
|
||||||
auto amount = (*sle)[sfBalance];
|
auto amount = sle.fsfBalance();
|
||||||
if (ammAccountID > issue.account)
|
if (ammAccountID > issue.account)
|
||||||
amount.negate();
|
amount.negate();
|
||||||
amount.setIssuer(issue.account);
|
amount.setIssuer(issue.account);
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ public:
|
|||||||
ammSle && ammSle->getFieldAmount(sfLPTokenBalance) != beast::zero)
|
ammSle && ammSle->getFieldAmount(sfLPTokenBalance) != beast::zero)
|
||||||
ammLiquidity_.emplace(
|
ammLiquidity_.emplace(
|
||||||
ctx.view,
|
ctx.view,
|
||||||
(*ammSle)[sfAccount],
|
ammSle.fsfAccount(),
|
||||||
getTradingFee(ctx.view, *ammSle, ctx.ammContext.account()),
|
getTradingFee(ctx.view, *ammSle, ctx.ammContext.account()),
|
||||||
in,
|
in,
|
||||||
out,
|
out,
|
||||||
@@ -1392,7 +1392,7 @@ BookStep<TIn, TOut, TDerived>::check(StrandContext const& ctx) const
|
|||||||
auto sle = view.read(keylet::line(*prev, cur, book_.in.currency));
|
auto sle = view.read(keylet::line(*prev, cur, book_.in.currency));
|
||||||
if (!sle)
|
if (!sle)
|
||||||
return terNO_LINE;
|
return terNO_LINE;
|
||||||
if ((*sle)[sfFlags] &
|
if ((*sle.getObject())[sfFlags] &
|
||||||
((cur > *prev) ? lsfHighNoRipple : lsfLowNoRipple))
|
((cur > *prev) ? lsfHighNoRipple : lsfLowNoRipple))
|
||||||
return terNO_RIPPLE;
|
return terNO_RIPPLE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -421,7 +421,7 @@ DirectIPaymentStep::check(
|
|||||||
|
|
||||||
if (((*sleSrc)[sfFlags] & lsfRequireAuth) &&
|
if (((*sleSrc)[sfFlags] & lsfRequireAuth) &&
|
||||||
!((*sleLine)[sfFlags] & authField) &&
|
!((*sleLine)[sfFlags] & authField) &&
|
||||||
(*sleLine)[sfBalance] == beast::zero)
|
sleLine.fsfBalance() == beast::zero)
|
||||||
{
|
{
|
||||||
JLOG(j_.warn())
|
JLOG(j_.warn())
|
||||||
<< "DirectStepI: can't receive IOUs from issuer without auth."
|
<< "DirectStepI: can't receive IOUs from issuer without auth."
|
||||||
|
|||||||
@@ -65,17 +65,17 @@ checkFreeze(
|
|||||||
if (view.rules().enabled(fixFrozenLPTokenTransfer))
|
if (view.rules().enabled(fixFrozenLPTokenTransfer))
|
||||||
{
|
{
|
||||||
if (auto const sleDst = view.read(keylet::account(dst));
|
if (auto const sleDst = view.read(keylet::account(dst));
|
||||||
sleDst && sleDst->isFieldPresent(sfAMMID))
|
sleDst && sleDst.fsfAMMID().has_value())
|
||||||
{
|
{
|
||||||
auto const sleAmm = view.read(keylet::amm((*sleDst)[sfAMMID]));
|
auto const sleAmm = view.read(keylet::amm(sleDst.fsfAMMID().value()));
|
||||||
if (!sleAmm)
|
if (!sleAmm)
|
||||||
return tecINTERNAL; // LCOV_EXCL_LINE
|
return tecINTERNAL; // LCOV_EXCL_LINE
|
||||||
|
|
||||||
if (isLPTokenFrozen(
|
if (isLPTokenFrozen(
|
||||||
view,
|
view,
|
||||||
src,
|
src,
|
||||||
(*sleAmm)[sfAsset].get<Issue>(),
|
sleAmm.fsfAsset().get<Issue>(),
|
||||||
(*sleAmm)[sfAsset2].get<Issue>()))
|
sleAmm.fsfAsset2().get<Issue>()))
|
||||||
{
|
{
|
||||||
return terNO_LINE;
|
return terNO_LINE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ AMMBid::preclaim(PreclaimContext const& ctx)
|
|||||||
return terNO_AMM;
|
return terNO_AMM;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const lpTokensBalance = (*ammSle)[sfLPTokenBalance];
|
auto const lpTokensBalance = ammSle.fsfLPTokenBalance();
|
||||||
if (lpTokensBalance == beast::zero)
|
if (lpTokensBalance == beast::zero)
|
||||||
return tecAMM_EMPTY;
|
return tecAMM_EMPTY;
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ AMMDelete::preclaim(PreclaimContext const& ctx)
|
|||||||
return terNO_AMM;
|
return terNO_AMM;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const lpTokensBalance = (*ammSle)[sfLPTokenBalance];
|
auto const lpTokensBalance = ammSle.fsfLPTokenBalance();
|
||||||
if (lpTokensBalance != beast::zero)
|
if (lpTokensBalance != beast::zero)
|
||||||
return tecAMM_NOT_EMPTY;
|
return tecAMM_NOT_EMPTY;
|
||||||
|
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ AMMDeposit::preclaim(PreclaimContext const& ctx)
|
|||||||
auto balance = [&](auto const& deposit) -> TER {
|
auto balance = [&](auto const& deposit) -> TER {
|
||||||
if (isXRP(deposit))
|
if (isXRP(deposit))
|
||||||
{
|
{
|
||||||
auto const lpIssue = (*ammSle)[sfLPTokenBalance].issue();
|
auto const lpIssue = ammSle.fsfLPTokenBalance().issue();
|
||||||
// Adjust the reserve if LP doesn't have LPToken trustline
|
// Adjust the reserve if LP doesn't have LPToken trustline
|
||||||
auto const sle = ctx.view.read(
|
auto const sle = ctx.view.read(
|
||||||
keylet::line(accountID, lpIssue.account, lpIssue.currency));
|
keylet::line(accountID, lpIssue.account, lpIssue.currency));
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ CancelCheck::preclaim(PreclaimContext const& ctx)
|
|||||||
|
|
||||||
using duration = NetClock::duration;
|
using duration = NetClock::duration;
|
||||||
using timepoint = NetClock::time_point;
|
using timepoint = NetClock::time_point;
|
||||||
auto const optExpiry = (*sleCheck)[~sfExpiration];
|
auto const optExpiry = sleCheck.fsfExpiration();
|
||||||
|
|
||||||
// Expiration is defined in terms of the close time of the parent
|
// Expiration is defined in terms of the close time of the parent
|
||||||
// ledger, because we definitively know the time that it closed but
|
// ledger, because we definitively know the time that it closed but
|
||||||
@@ -73,8 +73,8 @@ CancelCheck::preclaim(PreclaimContext const& ctx)
|
|||||||
// If the check is not yet expired, then only the creator or the
|
// If the check is not yet expired, then only the creator or the
|
||||||
// destination may cancel the check.
|
// destination may cancel the check.
|
||||||
AccountID const acctId{ctx.tx[sfAccount]};
|
AccountID const acctId{ctx.tx[sfAccount]};
|
||||||
if (acctId != (*sleCheck)[sfAccount] &&
|
if (acctId != sleCheck.fsfAccount() &&
|
||||||
acctId != (*sleCheck)[sfDestination])
|
acctId != sleCheck.fsfDestination())
|
||||||
{
|
{
|
||||||
JLOG(ctx.j.warn()) << "Check is not expired and canceler is "
|
JLOG(ctx.j.warn()) << "Check is not expired and canceler is "
|
||||||
"neither check source nor destination.";
|
"neither check source nor destination.";
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ CancelOffer::preclaim(PreclaimContext const& ctx)
|
|||||||
if (!sle)
|
if (!sle)
|
||||||
return terNO_ACCOUNT;
|
return terNO_ACCOUNT;
|
||||||
|
|
||||||
if ((*sle)[sfSequence] <= offerSequence)
|
if (sle.fsfSequence() <= offerSequence)
|
||||||
{
|
{
|
||||||
JLOG(ctx.j.trace()) << "Malformed transaction: "
|
JLOG(ctx.j.trace()) << "Malformed transaction: "
|
||||||
<< "Sequence " << offerSequence << " is invalid.";
|
<< "Sequence " << offerSequence << " is invalid.";
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <xrpl/protocol/STAmount.h>
|
#include <xrpl/protocol/STAmount.h>
|
||||||
#include <xrpl/protocol/STLedgerEntry.h>
|
#include <xrpl/protocol/STLedgerEntry.h>
|
||||||
#include <xrpl/protocol/STTx.h>
|
#include <xrpl/protocol/STTx.h>
|
||||||
|
#include <xrpl/protocol/TypedLedgerEntries.h>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
@@ -170,6 +171,13 @@ public:
|
|||||||
virtual std::shared_ptr<SLE const>
|
virtual std::shared_ptr<SLE const>
|
||||||
read(Keylet const& k) const = 0;
|
read(Keylet const& k) const = 0;
|
||||||
|
|
||||||
|
template<LedgerEntryType Type>
|
||||||
|
ConstLedgerObjectType<Type>
|
||||||
|
read(TypedKeylet<Type> const& k) const
|
||||||
|
{
|
||||||
|
return ConstLedgerObjectType<Type>::fromObject(read(k));
|
||||||
|
}
|
||||||
|
|
||||||
// Accounts in a payment are not allowed to use assets acquired during that
|
// Accounts in a payment are not allowed to use assets acquired during that
|
||||||
// payment. The PaymentSandbox tracks the debits, credits, and owner count
|
// payment. The PaymentSandbox tracks the debits, credits, and owner count
|
||||||
// changes that accounts make during a payment. `balanceHook` adjusts
|
// changes that accounts make during a payment. `balanceHook` adjusts
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#include <xrpl/protocol/TxFlags.h>
|
#include <xrpl/protocol/TxFlags.h>
|
||||||
#include <xrpl/protocol/digest.h>
|
#include <xrpl/protocol/digest.h>
|
||||||
#include <xrpl/protocol/st.h>
|
#include <xrpl/protocol/st.h>
|
||||||
|
#include <xrpl/protocol/TypedLedgerEntries.h>
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
@@ -260,9 +261,9 @@ isFrozen(
|
|||||||
if (issuer != account)
|
if (issuer != account)
|
||||||
{
|
{
|
||||||
// Check if the issuer froze the line
|
// Check if the issuer froze the line
|
||||||
sle = view.read(keylet::line(account, issuer, currency));
|
auto sleLine = view.read(keylet::line(account, issuer, currency));
|
||||||
if (sle &&
|
if (sleLine &&
|
||||||
sle->isFlag((issuer > account) ? lsfHighFreeze : lsfLowFreeze))
|
sleLine->isFlag((issuer > account) ? lsfHighFreeze : lsfLowFreeze))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -319,30 +320,34 @@ isVaultPseudoAccountFrozen(
|
|||||||
return true; // LCOV_EXCL_LINE
|
return true; // LCOV_EXCL_LINE
|
||||||
|
|
||||||
auto const mptIssuance =
|
auto const mptIssuance =
|
||||||
view.read(keylet::mptIssuance(mptShare.getMptID()));
|
ConstLedgerObjectType<ltMPTOKEN_ISSUANCE>::fromObject(
|
||||||
if (mptIssuance == nullptr)
|
view.read(keylet::mptIssuance(mptShare.getMptID())));
|
||||||
|
if (mptIssuance.isValid())
|
||||||
return false; // zero MPToken won't block deletion of MPTokenIssuance
|
return false; // zero MPToken won't block deletion of MPTokenIssuance
|
||||||
|
|
||||||
auto const issuer = mptIssuance->getAccountID(sfIssuer);
|
auto const issuer = mptIssuance.fsfIssuer();
|
||||||
auto const mptIssuer = view.read(keylet::account(issuer));
|
auto const mptIssuer =
|
||||||
if (mptIssuer == nullptr)
|
ConstLedgerObjectType<ltACCOUNT_ROOT>::fromObject(
|
||||||
|
view.read(keylet::account(issuer)));
|
||||||
|
if (mptIssuer.isValid())
|
||||||
{ // LCOV_EXCL_START
|
{ // LCOV_EXCL_START
|
||||||
UNREACHABLE("ripple::isVaultPseudoAccountFrozen : null MPToken issuer");
|
UNREACHABLE("ripple::isVaultPseudoAccountFrozen : null MPToken issuer");
|
||||||
return false;
|
return false;
|
||||||
} // LCOV_EXCL_STOP
|
} // LCOV_EXCL_STOP
|
||||||
|
|
||||||
if (!mptIssuer->isFieldPresent(sfVaultID))
|
if (!mptIssuer.fsfVaultID().has_value())
|
||||||
return false; // not a Vault pseudo-account, common case
|
return false; // not a Vault pseudo-account, common case
|
||||||
|
|
||||||
auto const vault =
|
auto const vault =
|
||||||
view.read(keylet::vault(mptIssuer->getFieldH256(sfVaultID)));
|
ConstLedgerObjectType<ltVAULT>::fromObject(
|
||||||
if (vault == nullptr)
|
view.read(keylet::vault(*mptIssuer.fsfVaultID())));
|
||||||
|
if (vault.isValid())
|
||||||
{ // LCOV_EXCL_START
|
{ // LCOV_EXCL_START
|
||||||
UNREACHABLE("ripple::isVaultPseudoAccountFrozen : null vault");
|
UNREACHABLE("ripple::isVaultPseudoAccountFrozen : null vault");
|
||||||
return false;
|
return false;
|
||||||
} // LCOV_EXCL_STOP
|
} // LCOV_EXCL_STOP
|
||||||
|
|
||||||
return isAnyFrozen(view, {issuer, account}, vault->at(sfAsset), depth + 1);
|
return isAnyFrozen(view, {issuer, account}, vault.fsfAsset(), depth + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|||||||
Reference in New Issue
Block a user