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 // 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 // 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. // 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. /** Amendments that this server supports and the default voting behavior.
Whether they are enabled depends on the Rules defined in the validated 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); uritoken(AccountID const& issuer, Blob const& uri);
Keylet Keylet
cron(uint32_t timestamp, AccountID const& id); cron(uint32_t timestamp, std::optional<AccountID> const& id = std::nullopt);
/** AMM entry */ /** AMM entry */
Keylet Keylet

View File

@@ -50,6 +50,7 @@ XRPL_FEATURE(DID, Supported::no, VoteBehavior::DefaultNo
XRPL_FIX (DisallowIncomingV1, Supported::yes, VoteBehavior::DefaultYes) XRPL_FIX (DisallowIncomingV1, Supported::yes, VoteBehavior::DefaultYes)
XRPL_FEATURE(XChainBridge, Supported::no, VoteBehavior::DefaultNo) XRPL_FEATURE(XChainBridge, Supported::no, VoteBehavior::DefaultNo)
XRPL_FEATURE(AMM, Supported::yes, 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(ExtendedHookState, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(Cron, Supported::yes, VoteBehavior::DefaultNo) XRPL_FEATURE(Cron, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (InvalidTxFlags, Supported::yes, VoteBehavior::DefaultYes) 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 // Examples: 100M → ~5.4e-12, 1B → ~5.4e-11, 10B → ~5.4e-10, 100B → ~5.4e-9
// (negligible). // (negligible).
Keylet Keylet
cron(uint32_t timestamp, AccountID const& id) cron(uint32_t timestamp, std::optional<AccountID> const& id)
{ {
static const uint256 ns = indexHash(LedgerNameSpace::CRON); 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[10] = static_cast<uint8_t>((timestamp >> 8) & 0xFFU);
h[11] = static_cast<uint8_t>((timestamp >> 0) & 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 // final 20 bytes are account ID
std::memcpy(h + 12, accHash.cdata(), 20); std::memcpy(h + 12, accHash.cdata(), 20);

View File

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

View File

@@ -93,6 +93,16 @@ Cron::doApply()
auto& view = ctx_.view(); auto& view = ctx_.view();
auto const& tx = ctx_.tx; 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); AccountID const& id = tx.getAccountID(sfOwner);
auto sle = view.peek(keylet::account(id)); auto sle = view.peek(keylet::account(id));