mirror of
https://github.com/Xahau/xahaud.git
synced 2026-09-24 22:30:17 +00:00
Compare commits
7 Commits
HookAdmini
...
server-def
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd342dabee | ||
|
|
902ed9b492 | ||
|
|
318f941ec4 | ||
|
|
5450719bdc | ||
|
|
fb8c29cf38 | ||
|
|
3754109e4b | ||
|
|
9d125f4d19 |
@@ -243,7 +243,6 @@
|
||||
#define sfLockingChainDoor ((8U << 16U) + 22U)
|
||||
#define sfIssuingChainDoor ((8U << 16U) + 23U)
|
||||
#define sfSubject ((8U << 16U) + 24U)
|
||||
#define sfHookAdministrator ((8U << 16U) + 98U)
|
||||
#define sfInform ((8U << 16U) + 99U)
|
||||
#define sfIndexes ((19U << 16U) + 1U)
|
||||
#define sfHashes ((19U << 16U) + 2U)
|
||||
|
||||
@@ -100,10 +100,6 @@ enum NFTokenCreateOfferFlags : uint32_t {
|
||||
tfSellNFToken = 0x00000001,
|
||||
};
|
||||
|
||||
enum SetHookFlags : uint32_t {
|
||||
tfNewAccount = 0x00000001,
|
||||
};
|
||||
|
||||
enum ClaimRewardFlags : uint32_t {
|
||||
tfOptOut = 0x00000001,
|
||||
};
|
||||
|
||||
@@ -223,11 +223,6 @@ constexpr std::uint32_t const tfNFTokenCancelOfferMask = ~tfUniversal;
|
||||
// NFTokenAcceptOffer flags:
|
||||
constexpr std::uint32_t const tfNFTokenAcceptOfferMask = ~tfUniversal;
|
||||
|
||||
enum SetHookFlags : uint32_t {
|
||||
tfNewAccount = 0x00000001,
|
||||
};
|
||||
constexpr std::uint32_t const tfSetHookMask = ~(tfUniversal | tfNewAccount);
|
||||
|
||||
// URIToken mask
|
||||
constexpr std::uint32_t const tfURITokenMintMask = ~(tfUniversal | tfBurnable);
|
||||
constexpr std::uint32_t const tfURITokenNonMintMask = ~tfUniversal;
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
// If you add an amendment here, then do not forget to increment `numFeatures`
|
||||
// in include/xrpl/protocol/Feature.h.
|
||||
|
||||
XRPL_FEATURE(HookAdministrator, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(OnChainManifests, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (HookMap, Supported::yes, VoteBehavior::DefaultYes)
|
||||
XRPL_FIX (GuardDepth32, Supported::yes, VoteBehavior::DefaultNo)
|
||||
|
||||
@@ -262,7 +262,6 @@ LEDGER_ENTRY(ltACCOUNT_ROOT, 0x0061, AccountRoot, account, ({
|
||||
{sfHookStateScale, soeOPTIONAL},
|
||||
{sfCron, soeOPTIONAL},
|
||||
{sfAMMID, soeOPTIONAL},
|
||||
{sfHookAdministrator, soeOPTIONAL},
|
||||
{sfManifestID, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
|
||||
@@ -320,7 +320,6 @@ TYPED_SFIELD(sfAttestationRewardAccount, ACCOUNT, 21)
|
||||
TYPED_SFIELD(sfLockingChainDoor, ACCOUNT, 22)
|
||||
TYPED_SFIELD(sfIssuingChainDoor, ACCOUNT, 23)
|
||||
TYPED_SFIELD(sfSubject, ACCOUNT, 24)
|
||||
TYPED_SFIELD(sfHookAdministrator, ACCOUNT, 98)
|
||||
TYPED_SFIELD(sfInform, ACCOUNT, 99)
|
||||
|
||||
// vector of 256-bit
|
||||
|
||||
@@ -195,7 +195,6 @@ TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete, ({
|
||||
/** This transaction type installs a hook. */
|
||||
TRANSACTION(ttHOOK_SET, 22, SetHook, ({
|
||||
{sfHooks, soeREQUIRED},
|
||||
{sfDestination, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** This transaction mints a new NFT. */
|
||||
|
||||
@@ -292,7 +292,9 @@ JSS(duration_us); // out: NetworkOPs
|
||||
JSS(effective); // out: ValidatorList
|
||||
// in: UNL
|
||||
JSS(elapsed_seconds);
|
||||
JSS(enabled); // out: AmendmentTable
|
||||
JSS(enabled); // out: AmendmentTable (on-ledger);
|
||||
// ServerDefinitions (this server)
|
||||
JSS(ledger_enabled); // out: ServerDefinitions (on-ledger)
|
||||
JSS(engine_result); // out: NetworkOPs, TransactionSign, Submit
|
||||
JSS(engine_result_code); // out: NetworkOPs, TransactionSign, Submit
|
||||
JSS(engine_result_message); // out: NetworkOPs, TransactionSign, Submit
|
||||
|
||||
@@ -163,7 +163,7 @@ public:
|
||||
void
|
||||
testNoParams(FeatureBitset features)
|
||||
{
|
||||
testcase("No Params, None Enabled");
|
||||
testcase("Default Env: config-forced, none on-ledger");
|
||||
|
||||
using namespace test::jtx;
|
||||
Env env{*this};
|
||||
@@ -178,8 +178,6 @@ public:
|
||||
{
|
||||
if (!BEAST_EXPECT(feature.isMember(jss::name)))
|
||||
return;
|
||||
// default config - so all should be disabled, and
|
||||
// supported. Some may be vetoed.
|
||||
bool expectVeto =
|
||||
(votes.at(feature[jss::name].asString()) ==
|
||||
VoteBehavior::DefaultNo);
|
||||
@@ -188,8 +186,12 @@ public:
|
||||
VoteBehavior::Obsolete);
|
||||
BEAST_EXPECTS(
|
||||
feature.isMember(jss::enabled) &&
|
||||
!feature[jss::enabled].asBool(),
|
||||
feature[jss::enabled].asBool(),
|
||||
feature[jss::name].asString() + " enabled");
|
||||
BEAST_EXPECTS(
|
||||
feature.isMember(jss::ledger_enabled) &&
|
||||
!feature[jss::ledger_enabled].asBool(),
|
||||
feature[jss::name].asString() + " ledger_enabled");
|
||||
BEAST_EXPECTS(
|
||||
feature.isMember(jss::vetoed) &&
|
||||
feature[jss::vetoed].isBool() == !expectObsolete &&
|
||||
@@ -208,7 +210,7 @@ public:
|
||||
void
|
||||
testSomeEnabled(FeatureBitset features)
|
||||
{
|
||||
testcase("No Params, Some Enabled");
|
||||
testcase("Two config-forced, none on-ledger");
|
||||
|
||||
using namespace test::jtx;
|
||||
Env env{
|
||||
@@ -228,7 +230,10 @@ public:
|
||||
(void)id.parseHex(it.key().asString().c_str());
|
||||
if (!BEAST_EXPECT((*it).isMember(jss::name)))
|
||||
return;
|
||||
bool expectEnabled = env.app().getAmendmentTable().isEnabled(id);
|
||||
bool const expectOnLedger =
|
||||
env.app().getAmendmentTable().isEnabled(id);
|
||||
bool const expectForced =
|
||||
id == featureDepositAuth || id == featureDepositPreauth;
|
||||
bool expectSupported =
|
||||
env.app().getAmendmentTable().isSupported(id);
|
||||
bool expectVeto =
|
||||
@@ -239,9 +244,14 @@ public:
|
||||
VoteBehavior::Obsolete);
|
||||
BEAST_EXPECTS(
|
||||
(*it).isMember(jss::enabled) &&
|
||||
(*it)[jss::enabled].asBool() == expectEnabled,
|
||||
(*it)[jss::enabled].asBool() ==
|
||||
(expectOnLedger || expectForced),
|
||||
(*it)[jss::name].asString() + " enabled");
|
||||
if (expectEnabled)
|
||||
BEAST_EXPECTS(
|
||||
(*it).isMember(jss::ledger_enabled) &&
|
||||
(*it)[jss::ledger_enabled].asBool() == expectOnLedger,
|
||||
(*it)[jss::name].asString() + " ledger_enabled");
|
||||
if (expectOnLedger)
|
||||
BEAST_EXPECTS(
|
||||
!(*it).isMember(jss::vetoed),
|
||||
(*it)[jss::name].asString() + " vetoed");
|
||||
@@ -360,12 +370,122 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testConfigForced(FeatureBitset features)
|
||||
{
|
||||
testcase("Config-forced features ([features] stanza)");
|
||||
|
||||
using namespace test::jtx;
|
||||
|
||||
auto const forced = featurePriceOracle;
|
||||
auto const forcedHex = to_string(forced);
|
||||
|
||||
Env env{*this, FeatureBitset(forced)};
|
||||
|
||||
auto jrr = env.rpc("server_definitions")[jss::result];
|
||||
if (!BEAST_EXPECT(jrr.isMember(jss::features)))
|
||||
return;
|
||||
|
||||
bool sawForced = false;
|
||||
for (auto it = jrr[jss::features].begin();
|
||||
it != jrr[jss::features].end();
|
||||
++it)
|
||||
{
|
||||
auto const& f = *it;
|
||||
auto const name = f[jss::name].asString();
|
||||
|
||||
if (!BEAST_EXPECTS(
|
||||
f.isMember(jss::enabled) && f.isMember(jss::ledger_enabled),
|
||||
name + " enabled/ledger_enabled"))
|
||||
return;
|
||||
|
||||
BEAST_EXPECTS(
|
||||
!f[jss::ledger_enabled].asBool(), name + " ledger_enabled");
|
||||
|
||||
if (it.key().asString() == forcedHex)
|
||||
{
|
||||
sawForced = true;
|
||||
BEAST_EXPECTS(f[jss::enabled].asBool(), name + " enabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
BEAST_EXPECTS(!f[jss::enabled].asBool(), name + " enabled");
|
||||
}
|
||||
}
|
||||
BEAST_EXPECT(sawForced);
|
||||
}
|
||||
|
||||
void
|
||||
testOnLedger(FeatureBitset features)
|
||||
{
|
||||
testcase("On-ledger plus one config-forced");
|
||||
|
||||
using namespace test::jtx;
|
||||
|
||||
// Veto XahauGenesis: FRESH would otherwise enable it via pseudo-tx.
|
||||
auto const forced = featurePriceOracle;
|
||||
auto const forcedHex = to_string(forced);
|
||||
|
||||
Env env{
|
||||
*this,
|
||||
envconfig([](std::unique_ptr<Config> cfg) {
|
||||
cfg->START_UP = Config::FRESH;
|
||||
cfg->section(SECTION_VETO_AMENDMENTS)
|
||||
.append(to_string(featureXahauGenesis) + " XahauGenesis");
|
||||
return cfg;
|
||||
}),
|
||||
FeatureBitset(forced)};
|
||||
|
||||
auto jrr = env.rpc("server_definitions")[jss::result];
|
||||
if (!BEAST_EXPECT(jrr.isMember(jss::features)))
|
||||
return;
|
||||
|
||||
bool sawOnLedger = false;
|
||||
bool sawForced = false;
|
||||
for (auto it = jrr[jss::features].begin();
|
||||
it != jrr[jss::features].end();
|
||||
++it)
|
||||
{
|
||||
uint256 id;
|
||||
(void)id.parseHex(it.key().asString().c_str());
|
||||
auto const& f = *it;
|
||||
auto const name = f[jss::name].asString();
|
||||
|
||||
if (!BEAST_EXPECTS(
|
||||
f.isMember(jss::enabled) && f.isMember(jss::ledger_enabled),
|
||||
name + " enabled/ledger_enabled"))
|
||||
return;
|
||||
|
||||
bool const onLedger = env.app().getAmendmentTable().isEnabled(id);
|
||||
bool const isForced = it.key().asString() == forcedHex;
|
||||
|
||||
BEAST_EXPECTS(
|
||||
f[jss::ledger_enabled].asBool() == onLedger,
|
||||
name + " ledger_enabled");
|
||||
BEAST_EXPECTS(
|
||||
f[jss::enabled].asBool() == (onLedger || isForced),
|
||||
name + " enabled");
|
||||
|
||||
if (onLedger)
|
||||
sawOnLedger = true;
|
||||
if (isForced)
|
||||
{
|
||||
sawForced = true;
|
||||
BEAST_EXPECTS(!onLedger, name + " forced not on-ledger");
|
||||
}
|
||||
}
|
||||
BEAST_EXPECT(sawOnLedger);
|
||||
BEAST_EXPECT(sawForced);
|
||||
}
|
||||
|
||||
void
|
||||
testServerFeatures(FeatureBitset features)
|
||||
{
|
||||
testNoParams(features);
|
||||
testSomeEnabled(features);
|
||||
testWithMajorities(features);
|
||||
testConfigForced(features);
|
||||
testOnLedger(features);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -30,12 +30,6 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
TxConsequences
|
||||
ClaimReward::makeTxConsequences(PreflightContext const& ctx)
|
||||
{
|
||||
return TxConsequences{ctx.tx, TxConsequences::normal};
|
||||
}
|
||||
|
||||
NotTEC
|
||||
ClaimReward::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
|
||||
@@ -32,15 +32,12 @@ namespace ripple {
|
||||
class ClaimReward : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Custom};
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
|
||||
explicit ClaimReward(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static TxConsequences
|
||||
makeTxConsequences(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
|
||||
@@ -30,12 +30,6 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
TxConsequences
|
||||
Cron::makeTxConsequences(PreflightContext const& ctx)
|
||||
{
|
||||
return TxConsequences{ctx.tx, TxConsequences::normal};
|
||||
}
|
||||
|
||||
NotTEC
|
||||
Cron::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace ripple {
|
||||
class Cron : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Custom};
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
|
||||
explicit Cron(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
@@ -39,9 +39,6 @@ public:
|
||||
static XRPAmount
|
||||
calculateBaseFee(ReadView const& view, STTx const& tx);
|
||||
|
||||
static TxConsequences
|
||||
makeTxConsequences(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
|
||||
@@ -27,12 +27,6 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
TxConsequences
|
||||
CronSet::makeTxConsequences(PreflightContext const& ctx)
|
||||
{
|
||||
return TxConsequences{ctx.tx, TxConsequences::normal};
|
||||
}
|
||||
|
||||
NotTEC
|
||||
CronSet::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace ripple {
|
||||
class CronSet : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Custom};
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
|
||||
explicit CronSet(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
@@ -38,9 +38,6 @@ public:
|
||||
static XRPAmount
|
||||
calculateBaseFee(ReadView const& view, STTx const& tx);
|
||||
|
||||
static TxConsequences
|
||||
makeTxConsequences(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
|
||||
@@ -330,9 +330,6 @@ DeleteAccount::preclaim(PreclaimContext const& ctx)
|
||||
if (sleAccount->isFieldPresent(sfHookNamespaces) ||
|
||||
sleAccount->isFieldPresent(sfHooks))
|
||||
return tecHAS_OBLIGATIONS;
|
||||
|
||||
if (sleAccount->isFieldPresent(sfHookAdministrator))
|
||||
return tecHAS_OBLIGATIONS;
|
||||
}
|
||||
|
||||
// When fixNFTokenRemint is enabled, we don't allow an account to be
|
||||
|
||||
@@ -1038,9 +1038,7 @@ ValidNewAccountRoot::finalize(
|
||||
if ((tt == ttPAYMENT || tt == ttIMPORT || tt == ttGENESIS_MINT ||
|
||||
tt == ttREMIT || tt == ttAMM_CREATE ||
|
||||
tt == ttXCHAIN_ADD_CLAIM_ATTESTATION ||
|
||||
tt == ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION ||
|
||||
(tt == ttHOOK_SET &&
|
||||
view.rules().enabled(featureHookAdministrator))) &&
|
||||
tt == ttXCHAIN_ADD_ACCOUNT_CREATE_ATTESTATION) &&
|
||||
isTesSuccess(result))
|
||||
{
|
||||
std::uint32_t const startingSeq{
|
||||
|
||||
@@ -26,12 +26,6 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
TxConsequences
|
||||
Invoke::makeTxConsequences(PreflightContext const& ctx)
|
||||
{
|
||||
return TxConsequences{ctx.tx, TxConsequences::normal};
|
||||
}
|
||||
|
||||
NotTEC
|
||||
Invoke::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace ripple {
|
||||
class Invoke : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Custom};
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
|
||||
explicit Invoke(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
@@ -39,9 +39,6 @@ public:
|
||||
static XRPAmount
|
||||
calculateBaseFee(ReadView const& view, STTx const& tx);
|
||||
|
||||
static TxConsequences
|
||||
makeTxConsequences(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
|
||||
@@ -704,21 +704,6 @@ SetHook::calculateBaseFee(ReadView const& view, STTx const& tx)
|
||||
TER
|
||||
SetHook::preclaim(ripple::PreclaimContext const& ctx)
|
||||
{
|
||||
if (ctx.tx.isFieldPresent(sfHookAdministrator))
|
||||
{
|
||||
auto const& administrator = ctx.tx.getAccountID(sfHookAdministrator);
|
||||
auto const& sle = ctx.view.read(keylet::account(administrator));
|
||||
if (!sle)
|
||||
return tecNO_DST;
|
||||
|
||||
if (!sle->isFieldPresent(sfHookAdministrator))
|
||||
return tecNO_PERMISSION;
|
||||
|
||||
if (sle->getAccountID(sfHookAdministrator) !=
|
||||
ctx.tx.getAccountID(sfAccount))
|
||||
return tecNO_PERMISSION;
|
||||
}
|
||||
|
||||
auto const& hookSets = ctx.tx.getFieldArray(sfHooks);
|
||||
|
||||
for (auto const& hookSetObj : hookSets)
|
||||
@@ -758,46 +743,12 @@ SetHook::preflight(PreflightContext const& ctx)
|
||||
return ret;
|
||||
|
||||
if (ctx.rules.enabled(fixInvalidTxFlags) &&
|
||||
ctx.tx.getFlags() & tfSetHookMask)
|
||||
ctx.tx.getFlags() & tfUniversalMask)
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "SetHook: Invalid flags set.";
|
||||
return temINVALID_FLAG;
|
||||
}
|
||||
|
||||
if (ctx.tx.isFlag(tfNewAccount) &&
|
||||
!ctx.rules.enabled(featureHookAdministrator))
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "SetHook: New account flag set but hook "
|
||||
"administrator amendment is not enabled.";
|
||||
return temDISABLED;
|
||||
}
|
||||
|
||||
if (ctx.tx.isFieldPresent(sfDestination))
|
||||
{
|
||||
if (!ctx.rules.enabled(featureHookAdministrator))
|
||||
{
|
||||
JLOG(ctx.j.trace())
|
||||
<< "HookSet: Hook administrator amendment not enabled.";
|
||||
return temDISABLED;
|
||||
}
|
||||
|
||||
if (ctx.tx.isFlag(tfNewAccount))
|
||||
{
|
||||
JLOG(ctx.j.trace())
|
||||
<< "HookSet: Both new account flag and destination set. "
|
||||
"New account flag and destination cannot be set at the same "
|
||||
"time.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
if (ctx.tx.getAccountID(sfDestination) ==
|
||||
ctx.tx.getAccountID(sfAccount))
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "HookSet: Redundant hook administrator.";
|
||||
return temREDUNDANT;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ctx.tx.isFieldPresent(sfHooks))
|
||||
{
|
||||
JLOG(ctx.j.trace())
|
||||
@@ -1337,23 +1288,6 @@ struct KeyletComparator
|
||||
}
|
||||
};
|
||||
|
||||
AccountID
|
||||
randomAccountAddress(ReadView const& view, uint256 const& pseudoOwnerKey)
|
||||
{
|
||||
// This number must not be changed without an amendment
|
||||
constexpr std::uint16_t maxAccountAttempts = 256;
|
||||
for (std::uint16_t i = 0; i < maxAccountAttempts; ++i)
|
||||
{
|
||||
ripesha_hasher rsh;
|
||||
auto const hash = sha512Half(i, view.info().parentHash, pseudoOwnerKey);
|
||||
rsh(hash.data(), hash.size());
|
||||
AccountID const ret{static_cast<ripesha_hasher::result_type>(rsh)};
|
||||
if (!view.read(keylet::account(ret)))
|
||||
return ret;
|
||||
}
|
||||
return beast::zero;
|
||||
}
|
||||
|
||||
TER
|
||||
SetHook::setHook()
|
||||
{
|
||||
@@ -1373,69 +1307,11 @@ SetHook::setHook()
|
||||
.app = ctx_.app,
|
||||
.rules = ctx_.view().rules()};
|
||||
|
||||
auto targetAccount = ctx.tx[~sfDestination].value_or(account_);
|
||||
if (ctx_.tx.isFlag(tfNewAccount))
|
||||
{
|
||||
// create the new account
|
||||
auto const newAccount = randomAccountAddress(ctx_.view(), uint256{});
|
||||
if (newAccount == beast::zero)
|
||||
return tecDUPLICATE;
|
||||
|
||||
auto sleNewAccount = std::make_shared<SLE>(keylet::account(newAccount));
|
||||
sleNewAccount->setAccountID(sfAccount, newAccount);
|
||||
sleNewAccount->setFieldAmount(sfBalance, STAmount{});
|
||||
sleNewAccount->setFieldU32(sfOwnerCount, 1); // ltHook
|
||||
std::uint32_t const seqno{
|
||||
ctx_.view().rules().enabled(featureXahauGenesis)
|
||||
? ctx_.view().info().parentCloseTime.time_since_epoch().count()
|
||||
: ctx_.view().rules().enabled(featureDeletableAccounts)
|
||||
? ctx_.view().seq()
|
||||
: 1};
|
||||
sleNewAccount->setFieldU32(sfSequence, seqno);
|
||||
sleNewAccount->setFieldU32(sfFlags, lsfDisableMaster);
|
||||
|
||||
sleNewAccount->setAccountID(sfHookAdministrator, account_);
|
||||
|
||||
auto sleFees = view().peek(keylet::fees());
|
||||
if (sleFees && view().rules().enabled(featureXahauGenesis))
|
||||
{
|
||||
auto actIdx = sleFees->isFieldPresent(sfAccountCount)
|
||||
? sleFees->getFieldU64(sfAccountCount)
|
||||
: 0;
|
||||
sleNewAccount->setFieldU64(sfAccountIndex, actIdx);
|
||||
sleFees->setFieldU64(sfAccountCount, actIdx + 1);
|
||||
view().update(sleFees);
|
||||
}
|
||||
|
||||
// fund AccountReserve + ObjectReserve (ltHook)
|
||||
auto const requiredDrops = ctx_.view().fees().accountReserve(1);
|
||||
|
||||
auto sourceSle = ctx_.view().peek(keylet::account(account_));
|
||||
if (!sourceSle)
|
||||
return tefINTERNAL;
|
||||
|
||||
auto const sourceCurrentReserve = ctx_.view().fees().accountReserve(
|
||||
sourceSle->getFieldU32(sfOwnerCount));
|
||||
|
||||
auto const sourceBalance = sourceSle->getFieldAmount(sfBalance).xrp();
|
||||
|
||||
if (sourceBalance < sourceCurrentReserve + requiredDrops)
|
||||
return tecUNFUNDED;
|
||||
|
||||
sourceSle->setFieldAmount(sfBalance, sourceBalance - requiredDrops);
|
||||
ctx_.view().update(sourceSle);
|
||||
|
||||
sleNewAccount->setFieldAmount(sfBalance, requiredDrops);
|
||||
ctx_.view().insert(sleNewAccount);
|
||||
|
||||
targetAccount = newAccount;
|
||||
}
|
||||
|
||||
const int blobMax = hook::maxHookWasmSize();
|
||||
auto const accountKeylet = keylet::account(account_);
|
||||
auto const hookKeylet = keylet::hook(account_);
|
||||
|
||||
auto const hookKeylet = keylet::hook(targetAccount);
|
||||
|
||||
auto accountSLE = view().peek(keylet::account(targetAccount));
|
||||
auto accountSLE = view().peek(accountKeylet);
|
||||
|
||||
ripple::STArray newHooks{sfHooks, 8};
|
||||
auto newHookSLE = std::make_shared<SLE>(hookKeylet);
|
||||
|
||||
@@ -30,12 +30,6 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
TxConsequences
|
||||
SetRemarks::makeTxConsequences(PreflightContext const& ctx)
|
||||
{
|
||||
return TxConsequences{ctx.tx, TxConsequences::normal};
|
||||
}
|
||||
|
||||
NotTEC
|
||||
SetRemarks::validateRemarks(STArray const& remarks, beast::Journal const& j)
|
||||
{
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace ripple {
|
||||
class SetRemarks : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Custom};
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Normal};
|
||||
|
||||
explicit SetRemarks(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
@@ -39,9 +39,6 @@ public:
|
||||
static XRPAmount
|
||||
calculateBaseFee(ReadView const& view, STTx const& tx);
|
||||
|
||||
static TxConsequences
|
||||
makeTxConsequences(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <xrpld/app/main/Application.h>
|
||||
#include <xrpld/app/misc/AmendmentTable.h>
|
||||
#include <xrpld/app/misc/NetworkOPs.h>
|
||||
#include <xrpld/core/Config.h>
|
||||
#include <xrpld/rpc/detail/TransactionSign.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/json/json_writer.h>
|
||||
@@ -545,6 +546,25 @@ doServerDefinitions(RPC::JsonContext& context)
|
||||
features[to_string(h)][jss::majority] =
|
||||
t.time_since_epoch().count();
|
||||
|
||||
// getJson's enabled is on-ledger; [features] also apply here.
|
||||
for (auto const& name : features.getMemberNames())
|
||||
{
|
||||
Json::Value& entry = features[name];
|
||||
entry[jss::ledger_enabled] = entry[jss::enabled].asBool();
|
||||
}
|
||||
for (auto const& h : context.app.config().features)
|
||||
{
|
||||
Json::Value& entry = features[to_string(h)];
|
||||
if (!entry.isMember(jss::name))
|
||||
{
|
||||
if (auto const fname = featureToName(h); !fname.empty())
|
||||
entry[jss::name] = fname;
|
||||
}
|
||||
if (!entry.isMember(jss::ledger_enabled))
|
||||
entry[jss::ledger_enabled] = false;
|
||||
entry[jss::enabled] = true;
|
||||
}
|
||||
|
||||
lastFeatures = features;
|
||||
{
|
||||
const std::string out = Json::FastWriter().write(features);
|
||||
|
||||
Reference in New Issue
Block a user