Electrum tip height is truncated with `as u32`

Open Beginner friendly
#2,294 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
82/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
rust

Research direction

Start in crates/electrum/src/bdk_electrum_client.rs at fetch_tip_and_latest_blocks, which is reached by BdkElectrumClient::sync and full_scan when a chain_tip is present. Reproduce the issue with the stub response containing height 4294967396 and inspect the resulting behavior. Done means an out-of-range server-reported height is rejected rather than silently becoming a low, plausible height.

Written by the indexing model from the issue text.

Description

bug

Describe the bug

fetch_tip_and_latest_blocks (used by BdkElectrumClient::sync and full_scan whenever the request has a chain_tip) converts the server-reported tip height with a plain cast (crates/electrum/src/bdk_electrum_client.rs:656-657):

let HeaderNotification { height, .. } = client.block_headers_subscribe()?;
let new_tip_height = height as u32;

HeaderNotification::height is a usize deserialized from the server's JSON response. On 64-bit targets a value of 2^32 + k silently becomes k, so an out-of-range value from a buggy or misbehaving server is processed as a plausible low tip instead of being rejected. Depending on k, the function either takes the "server tip is lower than ours" early return or builds the checkpoint update around height k, far below the server's real tip. Every height-derived value in the update is then wrong.

The h as u32 / height as u32 casts on history heights later in the file cannot overflow today because GetHistoryRes::height is i32, but they follow the same pattern.

This issue was found by AI.

To Reproduce

  1. Point a BdkElectrumClient at a stub server whose blockchain.headers.subscribe response contains "height": 4294967396 (2^32 + 100) and a valid header hex.
  2. Call sync or full_scan with a request whose chain_tip is above height 100.
  3. fetch_tip_and_latest_blocks treats the tip as height 100 and takes the early return, and the sync completes without any error.

Expected behavior

A reported tip height that does not fit in u32 should not be silently truncated into a different, valid-looking height.

Dominant language
Rust
Stars
1.1k
Forks
491
Avg merge
1d 5h
Merged PRs (30d)
1

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from bitcoindevkit/bdk

All issues in bitcoindevkit/bdk

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.