The fix is one comparison. Only bdk_electrum 0.24.1 has it, there’s no fixed 0.23, and LDK Node shipped on 0.23 eight hours later

In BDK’s Electrum client, the loop that gathers fee data for a wallet has a comment on line 588 of the 0.23.2 source that says exactly what it should do:

let prev_tx = self.fetch_tx(outpoint.txid)?;
// Ensure server returns the expected txout.
let txout = prev_tx
.output
.get(vout as usize)

The only check under that comment is that output number vout exists. Nothing checks that prev_tx is the transaction the wallet asked for. fetch_tx sends a txid to the Electrum server, takes back whatever transaction the server returns and caches it under the txid it asked for. The output then goes into a map keyed by the outpoint the wallet asked about, and that map is where BDK gets input values when it works out the fee on a transaction whose inputs the wallet doesn’t own.

So for a parent the wallet doesn’t already hold, a server could answer with any transaction that has enough outputs, and its amount would become that input’s value in the wallet’s fee numbers. That’s as far as I can follow it in the code. fetch_tx also serves the wallet’s own history, and I haven’t traced what a swapped transaction does on that path, or run any of this against a server that lies.

bdk_electrum 0.23.2 against 0.24.1: where the server’s answer was trusted, and the check that 0.24.1 adds.

One comparison, merged in April

The fix is six lines in fetch_tx: compute the txid of what came back and return an error if it isn’t the one requested. It was merged to master on 24 April as PR 2188.

Master isn’t what gets published, though. bdk_electrum 0.24.0 came out on 8 May without the check; I diffed the published sources, and its fetch_tx is the same as 0.23.2’s. The backport, PR 2228, was merged on 16 June into a branch called release/chain-0.23.x, and that name nearly caught me out. I read it as the 0.23 line getting the fix. It’s the release branch for bdk_chain 0.23, and bdk_electrum’s 0.24 releases come off it. The fix sat merged there for 118 days, until 0.24.1 was published on 12 October at 05:29 UTC, 171 days after it first landed.

From merge to release: 171 days, 118 of them merged on the branch that 0.24.1 was cut from.

Who can’t take it

Cargo treats 0.23 and 0.24 as incompatible, the way it treats any minor bump before 1.0. A crate that asks for bdk_electrum 0.23 gets 0.23.2 at most, and no 0.23 release has the check. Moving to 0.24 also moves electrum-client from 0.24 to 0.25, so it takes an edit to the manifest, and cargo update won’t do it.

crates.io lists 11 crates that depend on bdk_electrum. Two use it only in tests. Of the other nine, five ask for 0.23 and four for 0.24. LDK Node is one of the five. Its 0.7.1 release came out at 13:53 UTC on 12 October, eight hours and 24 minutes after 0.24.1, still on bdk_electrum 0.23, and it asks for previous outputs in both its sync and its full scan. It does fill the client’s cache from its own wallet first, so parents it already holds never go to the server. fedimint-ldk-node 0.7.0 asks for 0.23 too. LDK Node’s main branch has moved to 0.24.0, which resolves to 0.24.1 on a fresh lockfile, so its next release should carry the check.

The nine crates on crates.io that depend on bdk_electrum outside tests, by the version they ask for.

Downloads tell it from the other side. On 13 October, the first full day 0.24.1 existed, crates.io counted 2,050 downloads of bdk_electrum, and 530 were 0.24.1. 799 were 0.23.2, the last of the line that has no fix. Downloads are CI runs and mirrors as much as people, so I wouldn’t read them as users, but they’re the only count there is.

Daily crates.io downloads of bdk_electrum, split by whether the version has the txid check. 14 October is partial.

The case where any of this matters is a node pointed at an Electrum server somebody else runs. I don’t know of a way to count LDK Node deployments set up like that. Until LDK Node ships a release on 0.24, the apps built on it can’t get the check without patching LDK Node itself.

BDK’s Electrum txid check took 171 days to ship, and 5 of the 9 crates using it can’t get it was originally published in Coinmonks on Medium, where people are continuing the conversation by highlighting and responding to this story.

By

Leave a Reply

Your email address will not be published. Required fields are marked *