Skip to content

Use Bitcoin Median time and Height for expiry/sweeping #909

@Kukks

Description

@Kukks

Summary

Use Bitcoin's Median Time Past (MTP) and block height for expiry/sweeping calculations instead of relying on system time, improving security and consistency with Bitcoin consensus rules.

Context

Background

Currently, arkd supports two scheduling modes for expiry/sweeping:

  1. BlockHeight-based: Uses blockTimestamp.Height + batchExpiry
  2. UnixTime-based: Uses blockTimestamp.Time + batchExpiry.Seconds()

For UnixTime mode, the scheduler compares against time.Now() (system time) instead of Bitcoin's Median Time Past (MTP). This is a security concern because:

  • System time can be manipulated by the operator or via NTP attacks
  • Bitcoin's MTP is consensus-critical and resistant to timestamp manipulation
  • Using MTP aligns with Bitcoin's own time-based validation rules (BIP-113)

The wallet already fetches Mediantime from NBXplorer's blockchain info, but the scheduler doesn't use it.

Technical Approach

  1. Modify the scheduler interface to accept chain context (MTP, current height)
  2. Update AfterNow() in gocron/service.go to use chain MTP instead of time.Now()
  3. Refactor expiry calculations in service.go and sweeper.go to:
    • For height mode: current_height + expiry_blocks
    • For time mode: chain_mtp + expiry_seconds
  4. Add configuration option to choose between height-based and time-based expiry (defaulting to height for better security)

Acceptance Criteria

  • Scheduler uses chain MTP instead of system time for time-based expiry
  • Both height-based and time-based modes tested with edge cases
  • No regression in sweep scheduling accuracy
  • Documentation updated for operator config

Cross-Repo Impact

  • ts-sdk/go-sdk/rust-sdk: May need updates if they expose expiry scheduling config
  • wallet: No direct impact (uses SDK APIs)

Complexity Estimate

Medium (1-2 days) — Requires careful testing of time-based edge cases

Suggested Assignee

louisinger or altafan — both familiar with the scheduler and sweeper internals

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions