Skip to content

OutOfDustValidityWindow (171): txpool tblock margin too tight under network lag #1856

Description

Symptoms

  • Intermittent transaction rejection at submission:
    1010: Invalid Transaction: Custom error: 171 (OutOfDustValidityWindow).
  • Occurs on the circuit-call ("emit") transaction after a successful deploy;
    the transaction never enters a block.

Environment

  • Network: devnet (rpc.devnet.midnight.network / indexer.devnet.midnight.network)
  • node: midnight-node:2.0.0-rc.3 (ledger crate tag crate-ledger-9.1.0.0-rc.3)
  • proof-server: 9.0.0-rc.5 · client: @midnightntwrk/ledger-v9 (wasm) 1.0.0-rc.3,
    wallet-sdk 4.0.0-beta.2 / 5.0.0-beta.2, midnight-js 5.0.0-beta.4
  • Test harness: compact-end-2-end events suite; host clock NTP-synced.

Steps to Reproduce

  1. Point the compact-end-2-end events suite at devnet (--network devnet).
  2. Run events-demo-emit repeatedly (deploy + circuit-call emit).
  3. Observe intermittent failures at the emit submission with Custom error 171.
    (Observed 3 failures across 6 runs, mixed 170/171.)

Expected Result

  • A freshly built, legitimately-timed transaction is accepted under normal
    devnet block cadence.

Actual Result

  • Rejected with Custom error: 171 (OutOfDustValidityWindow) intermittently.

Impact

  • Blocks ~1/3 of emit transactions on devnet; non-deterministic.
  • Undermines e2e testing reliability on shared deployed environments.
  • No client-side workaround beyond retrying.

How Reproducible

  • Intermittent — correlated with devnet block-production lag at submit time.

Additional Context

  • Root cause (from source, version-matched): the dust well-formedness check
    (ledger dust.rs:815) rejects when ctime > tblock with no tolerance.
    The client stamps ctime = wallet wall-clock "now" (WASM ctime: &Date
    date.get_time()/1000). During txpool validation the node computes
    tblock = last_block_time + slot_duration + slot_duration·MaxSkippedSlots
    (pallets/midnight/src/lib.rs:446-459), which with SLOT_DURATION=6s and
    MaxSkippedSlots=1 is only +12s. If the chain tip lags the client clock
    by more than 12s, ctime > tblock → 171.
  • Hypothesis: the +12s simulation margin (1 slot + 1 skipped slot) is too
    tight for real deployed-network conditions (>1 skipped slot / production lag /
    minor clock skew). Options to evaluate: raise MaxSkippedSlots / the
    simulation margin, apply the existing 30s tblock_err drift to the dust
    check, or have the wallet SDK stamp ctime from a chain-referenced time
    rather than local now.
  • Timezone ruled out: Timestamp is u64 epoch seconds; Date.getTime() is UTC.

Metadata

Metadata

Assignees

Labels

component:nodeNode componenttriagedIssue has been assessed and accepted

Type

Fields

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions