Merge branch 'dev' into sync-2.4.0

This commit is contained in:
tequ
2025-11-20 10:47:16 +09:00
6 changed files with 29 additions and 7 deletions

View File

@@ -80,7 +80,7 @@ namespace detail {
// Feature.cpp. Because it's only used to reserve storage, and determine how
// large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than
// the actual number of amendments. A LogicError on startup will verify this.
static constexpr std::size_t numFeatures = 108;
static constexpr std::size_t numFeatures = 109;
/** Amendments that this server supports and the default voting behavior.
Whether they are enabled depends on the Rules defined in the validated

View File

@@ -307,7 +307,7 @@ Keylet
uritoken(AccountID const& issuer, Blob const& uri);
Keylet
cron(uint32_t timestamp, AccountID const& id);
cron(uint32_t timestamp, std::optional<AccountID> const& id = std::nullopt);
/** AMM entry */
Keylet

View File

@@ -50,6 +50,7 @@ XRPL_FEATURE(DID, Supported::no, VoteBehavior::DefaultNo
XRPL_FIX (DisallowIncomingV1, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(XChainBridge, Supported::no, VoteBehavior::DefaultNo)
XRPL_FEATURE(AMM, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (CronStacking, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(ExtendedHookState, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(Cron, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (InvalidTxFlags, Supported::yes, VoteBehavior::DefaultYes)

View File

@@ -514,7 +514,7 @@ uritoken(AccountID const& issuer, Blob const& uri)
// Examples: 100M → ~5.4e-12, 1B → ~5.4e-11, 10B → ~5.4e-10, 100B → ~5.4e-9
// (negligible).
Keylet
cron(uint32_t timestamp, AccountID const& id)
cron(uint32_t timestamp, std::optional<AccountID> const& id)
{
static const uint256 ns = indexHash(LedgerNameSpace::CRON);
@@ -529,7 +529,14 @@ cron(uint32_t timestamp, AccountID const& id)
h[10] = static_cast<uint8_t>((timestamp >> 8) & 0xFFU);
h[11] = static_cast<uint8_t>((timestamp >> 0) & 0xFFU);
const uint256 accHash = indexHash(LedgerNameSpace::CRON, timestamp, id);
if (!id.has_value())
{
// final 20 bytes are zero
std::memset(h + 12, 0, 20);
return {ltCRON, uint256::fromVoid(h)};
}
const uint256 accHash = indexHash(LedgerNameSpace::CRON, timestamp, *id);
// final 20 bytes are account ID
std::memcpy(h + 12, accHash.cdata(), 20);

View File

@@ -1502,9 +1502,13 @@ TxQ::accept(Application& app, OpenView& view)
{
uint32_t currentTime =
view.parentCloseTime().time_since_epoch().count();
uint256 klStart = keylet::cron(0, AccountID(beast::zero)).key;
uint256 const klEnd =
keylet::cron(currentTime + 1, AccountID(beast::zero)).key;
bool fixCron = view.rules().enabled(fixCronStacking);
std::optional<AccountID> accountID = std::nullopt;
if (!fixCron)
accountID = AccountID(beast::zero);
uint256 klStart = keylet::cron(0, accountID).key;
uint256 const klEnd = keylet::cron(currentTime + 1, accountID).key;
std::set<AccountID> cronAccs;

View File

@@ -93,6 +93,16 @@ Cron::doApply()
auto& view = ctx_.view();
auto const& tx = ctx_.tx;
if (view.rules().enabled(fixCronStacking))
{
if (auto const seq = tx.getFieldU32(sfLedgerSequence);
seq != view.info().seq)
{
JLOG(j_.warn()) << "Cron: wrong ledger seq=" << seq;
return tefFAILURE;
}
}
AccountID const& id = tx.getAccountID(sfOwner);
auto sle = view.peek(keylet::account(id));