fix: base validate_unsigned DUST validity window on wall-clock time#1877
Open
ozgb wants to merge 3 commits into
Open
fix: base validate_unsigned DUST validity window on wall-clock time#1877ozgb wants to merge 3 commits into
ozgb wants to merge 3 commits into
Conversation
pallet_midnight's validate_unsigned (tx-pool path) computed the DUST validity-window reference time `tblock` from the last produced block's on-chain timestamp plus a MaxSkippedSlots margin. When block production stalls, that stored timestamp goes stale, so `tblock` lags real time and transactions with a creation time near "now" are wrongly rejected with OutOfDustValidityWindow, even though the next block would accept them. Base `tblock` on the true expected next block time instead: the current wall-clock time rounded up to the next AURA slot boundary. Wall-clock time is supplied via a new `wall_clock::now_millis()` host function (the runtime's validate path registers no offchain extension, so sp_io::offchain::timestamp() is unavailable there) and injected into the pallet through a new Config type `WallClockMillis: Get<u64>`. Determinism is preserved: the bump lives only in validate_unsigned; block import/execution goes through pre_dispatch, which uses the unbumped on-chain timestamp. Removes the now-unused MaxSkippedSlots storage (metadata change). Issue: #1856 Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Oscar Bailey <79094698+ozgb@users.noreply.github.com>
Jina ReviewJina was blocked while reviewing this PR. Review: https://app.usejina.com/reviews/763a68d1-d38c-400e-afa7-afb23336832c
|
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Oscar Bailey <79094698+ozgb@users.noreply.github.com>
Jina ReviewJina was blocked while reviewing this PR. Review: https://app.usejina.com/reviews/a52aebb1-ffbb-471f-8cbb-17032fa16ef2
|
Contributor
Author
|
/bot rebuild-metadata |
1 similar comment
Contributor
Author
|
/bot rebuild-metadata |
This comment has been minimized.
This comment has been minimized.
Signed-off-by: Oscar Bailey <79094698+ozgb@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
pallet_midnight'svalidate_unsigned(the tx-pool validation path) computed the DUSTvalidity-window reference time
tblockfrom the last produced block's on-chain timestamp,plus a
MaxSkippedSlotsmargin. When block production stalls (network hiccup, missed AURAslots beyond
MaxSkippedSlots), that stored timestamp goes stale, sotblocklags real time.A transaction whose creation time (
ctime) is near "now" is then wrongly rejected during poolvalidation with
OutOfDustValidityWindow(ctime > tblock) — even though the next block,whenever produced, would carry a timestamp ≈ now and accept it.
This change bases
tblockon the true expected next block time: the current wall-clocktime rounded up to the next AURA slot boundary, so pool validation tracks real time
regardless of how long production has stalled. The
MaxSkippedSlotsmargin is dropped.How
wall_clock::now_millis()host function (ledger/src/host_api/clock.rs) reading thenode's system clock. A host function is required because the runtime's
validate_transactionpath registers no offchain extension, so
sp_io::offchain::timestamp()would panic there.HostFunctionsexecutor tuples (node/src/service.rs).Configassociated typeWallClockMillis: Get<u64>(production wires it to the host fn; mocks return the deterministic on-chain mock timestamp).
validate_unsignednow setstblock= wall-clock now rounded up to the next slot boundary.Determinism is preserved: the wall-clock bump lives only in
validate_unsigned(poolpath). Block import/execution goes through the pallet's own
pre_dispatch, which uses the raw,unbumped on-chain timestamp — deterministic across nodes. A non-deterministic wall-clock in
validate_unsigneddoes not affect consensus.Removes the now-unused
MaxSkippedSlotsstorage item (it only ever held its default; no setterexists). This is a metadata change.
Two explanatory
TODOcomments were added deliberately, noting that once a custom transactionpool exists, this host fn should be replaced by a timestamp (offchain) extension scoped to the
validation call.
🗹 TODO before merging
/bot rebuild-metadata) —MaxSkippedSlotsstorage removedsend_mn_transactionon a dev node, confirm noOutOfDustValidityWindow📌 Submission Checklist
git commit -s) for the DCO🧪 Testing Evidence
cargo check— 0 errors acrossmidnight-node-ledger,pallet-midnight,pallet-cnight-observation-mock,midnight-node-runtime,midnight-node(andmidnight-node --features runtime-benchmarks, covering the benchmarkHostFunctionstuple).cargo fmt --check— clean on all modified crates.cargo test -p pallet-midnight— 21 passed, 2 ignored.test_validation_works,test_validation_fails, andtest_pre_dispatch_*all pass (no fixture adjustment needed;the new
tblocklands closer toctimethan the old+12s, staying inside the window).cargo test -p pallet-cnight-observation— 43 passed, 1 ignored (exercises the modified mock).Please describe any additional testing aside from CI:
🔱 Fork Strategy
Adding a host function means a node must have it registered before running a runtime that calls
it. An old node importing/validating with a new runtime would fail to resolve the
wall_clock::now_milliswasm import — upgrade nodes with (or before) the runtime.Links
Closes #1856