News

One random number generator, two threads

Bitcoin Core merged a fix on 26 August 2026 for a change made eight days earlier that let two threads reach the same random number generator. No release ever carried it, and the reason the generator is there at all is the interesting part.

3 min readBitcoin Core
One random number generator, two threads

What happened

On 26 August 2026 Bitcoin Core merged bugfix: give TxDownloadManager its own RNG, eight days after the change that made it necessary. The transaction download manager had been holding a reference to the message processing thread's random number generator, which is not thread safe, while a second thread could reach the same object through a different lock. The pull request carries the 32.0 milestone, and the finding came from Project Loupe static analysis rather than from anything going wrong on a running node.

What it changes

The interesting question is why a node needs randomness there at all. When a transaction arrives whose parent is missing, it goes into the orphanage. When the parent later shows up, the orphan has to be reconsidered, and Core puts it into the work set of a peer that announced it. If several peers announced the same orphan, it picks one of them by drawing a number: std::advance(it, rng.randrange(num_announcers));. The code says why it is not simply the first announcer: "we don't want to create an issue in which the assigned peer can purposefully stop us from processing the orphan by disconnecting". The randomness is there so that no single peer can decide whether your node ever gets around to a transaction.

The regression came from a genuine improvement. p2p: reconsider orphans when missing inputs are mined, merged on 18 August 2026, extended reconsideration to the case where a missing parent is first seen in a block rather than in the mempool. That path runs on the validation background thread. The generator it borrowed belongs to message processing and is guarded by a different mutex, so the two threads were each holding a lock and neither lock excluded the other.

That is a data race, and the honest description is not that two threads might draw the same number. In C++ a data race is undefined behaviour, so the program has no defined meaning at that point, whatever it happens to do in practice. The fix is one line of ownership: the download manager now holds its own FastRandomContext instead of a reference to somebody else's.

What it does not change

No released version was affected. Bitcoin Core 31.1, the current release, was published on 8 July 2026, which is before either change. Both the regression and the fix lived on the development branch, roughly a week apart, and the version they are headed for has not shipped.

Nothing about consensus moved. Which peer's work set an orphan lands in is transaction relay behaviour, not a validation rule: no coin was ever spendable or unspendable because of this, and nodes that disagreed about the draw would still agree about the chain.

It also does not say the orphan change was a mistake. Reconsidering orphans when their parent is mined is the correct behaviour, and it stayed. What moved was where the randomness comes from.

Context

The orphan improvement has a visible origin. A reviewer noted that when "orphan parents never entered the mempool and were first seen in mined blocks, their now-valid children were not reconsidered and remained in the orphanage", and that this "was likely more visible during the recent wave of Slipstream COLDCARD rescues". Coins being swept off devices with weak seeds were handed straight to a miner rather than broadcast, so the parent transaction appeared for the first time in a block, and anything depending on it sat stuck.

The rest is a pattern this month: two small pull requests, eight days apart, where the second exists because the first widened who touches a shared object. The same shape appears in an invariant that had only ever lived in reviewers' heads until someone wrote the test. Correctness in a codebase this old is mostly a question of which assumptions are written down somewhere a machine can check.

Newsletter

Bitcoin, without the noise

What happened in Bitcoin, what it actually changes, and the sources so you can check us. One issue at a time, straight to your inbox.

  • One email per issue, never a drip campaign
  • No tracking pixels and no shared addresses
  • Unsubscribe from any issue in one click

Get the next issue

One email per issue, no tracking pixels, and unsubscribe from any of them. We do not share your address. Privacy policy