]> Untitled Git - bdk/commitdiff
Merge bitcoindevkit/bdk#2037: Add median-time-past (MTP) calculation to CheckPoint master github/master
authormerge-script <hello@evanlinjin.me>
Sun, 25 Jan 2026 05:04:14 +0000 (05:04 +0000)
committermerge-script <hello@evanlinjin.me>
Sun, 25 Jan 2026 05:04:14 +0000 (05:04 +0000)
b6235360e7232ad8bba2b12049eacdd2a6f9b3ca feat(core): add median-time-past calculation to CheckPoint (志宇)

Pull request description:

  ## Description

  This PR adds the ability to calculate median-time-past (MTP) for `CheckPoint` structures, implementing the functionality described in #2036.

  ## Notes to the reviewers

  `CheckPoint::median_time_past` calculates the MTP value by looking at the previous 11 blocks (including the current block).

  ### Why `ToBlockTime` is a separate trait from `ToBlockHash`

  `ToBlockTime` is intentionally kept as a separate trait with a non-optional return type (`fn to_blocktime(&self) -> u32`).

  For operations like MTP calculation, block times are either fully available or the calculation is meaningless — there's no useful "partial" or "best-effort" result. By using a separate trait, we get compile-time guarantees: methods like `median_time_past()` use `where D: ToBlockTime` bounds, making it explicit which checkpoint data types support time-based operations. Types without block time data (e.g., `BlockHash`, `BlockId`) simply don't implement the trait.

  #### How this differs from `prev_blockhash`

  In contrast, `prev_blockhash() -> Option<BlockHash>` is a method on `ToBlockHash` rather than a separate trait. The `Option` return serves a different purpose — it allows graceful degradation. A `CheckPoint<BlockId>` chain is still useful even without hash linkage validation; callers can simply skip verification when `None` is returned. Additionally, `None` at genesis is semantically meaningful (it marks the chain root), not an error condition.

  For MTP, there's no equivalent "skip if unavailable" — you either have all 11 timestamps or the calculation fails. This binary requirement is better expressed as a trait bound than runtime `Option` handling.

  ## Changelog notice

  ### Added
  - Introduced `ToBlockTime` trait for types that can return a block time.
  - Added `median_time_past()` method to `CheckPoint` for calculating MTP according to BIP113

  ## Checklists

  ### All Submissions:

  * [x] I've signed all my commits
  * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)
  * [x] I ran `cargo fmt` and `cargo clippy` before committing

  ### New Features:

  * [x] I've added tests for the new feature
  * [x] I've added docs for the new feature

  Fixes #2036

ACKs for top commit:
  ValuedMammal:
    ACK b6235360e7232ad8bba2b12049eacdd2a6f9b3ca

Tree-SHA512: fac1c06d27d44a4e419ca53bca3a7d38efe7f7a73fbf60508013a2a4b46c5081d47e02f1d1df5250315203770326db90c436c852c693215c493daa036e6cab9d


Trivial merge