Why does XT exist and what changes are in it?

Emperor Bob

New Member
Aug 19, 2015
Why does XT exist?

Back in the bad old subversion/sourceforge days, while Mike was building bitcoinj (the library running in most Android and Desktop SPV implementations), getting Core to merge patches to help support SPV clients was relatively straightforward.

Over time, getting anything merged into Bitcoin Core has become harder. Now to some extent, that's a good thing, the bar in terms of security and performance needs to increase.

The problem is that that goal often conflicts with the goal of making full nodes useful to other bitcoin clients on the network.

More and more of the goals Mike was trying to achieve (with bitcoinj, with Lighthouse) in terms of letting anyone use those products without relying on a central server, became harder over time.

The breaking point was pull request 4351: https://github.com/bitcoin/bitcoin/pull/4351

It got merged, then reverted when it turned out to allow overrunning the 32MB limit on network messages, then attempts at fixing that and getting the code merged back in went nowhere. There were a lot of arguments about the proper role of full nodes, whether ever serving unauthenticated data (if nothing better could be done) was justifiable, and, of course, the inevitable personality clashes.

At that point there were a few options:

1. Force users of lighthouse to run their own full node and use the RPC commands.
2. Use a centralized server as a fallback.
3. Fork Bitcoin Core, and hope there's enough uptake to support Lighthouse users.

A few more patches, and a blocksize limit change later, here we all are.

I'll keep posting to this thread with descriptions of the various patches in XT, what they do, why they're not accepted in Core. Hopefully this helps demistify the changes, and Bitcoin development as well:


- getutxos
- Fixes for inv blinding.
Last edited:
  • Like
Reactions: AdrianX and Bloomie

Emperor Bob

New Member
Aug 19, 2015
getutxos, the patch that started XT

You can see it here: https://github.com/bitcoinxt/bitcoinxt/commit/44da097f68b7a1842889c4c46949e289c6ec8cd8
It's also described by the following BIP: https://github.com/bitcoin/bips/blob/master/bip-0064.mediawiki

What does it do?

It lets any peer ask a full node to validate the spentness of a set of outpoints, and return information about the transaction it came from, if unspent.

An outpoint is just the technical term for one of the outputs of a transaction. If you pay a merchant and send the change back to yourself, that's 2 outpoints.

What is this useful for?

SPV clients simply lack the ability to evaluate the spentness of an arbitrary transaction outpoint. This proved to be a problem when building Lighthouse, a peer-to-peer crowdfunding tool: Central to it's design was a transaction of type "SIGHASH_ANYONE_CAN_PAY", meaning independent users can pay part of the transaction with their wallet independently of the others, and send that part to the fundraiser. Much like kickstarter, the transaction is only valid if enough independent pledges are collected.

The problem is that the person organizing the fundraiser would have no idea if the pledges being sent in were valid or not, and couldn't see if and when a pledge became invalid due to the user spending the funds in another transaction. getutxos was designed to expose such information.

Why did it not make it into Core?

It did, for a few hours. Then it got reverted. There was some opposition before it got merged, and then more after, and a bug with message sizes was found. At that point the maintainers decided reverting was the right move.

Some of the objections:

  1. The bitset of spentness/unspentness is entirely unauthenticated, and thus a node can lie easily to its peers.
  2. While returning the source transaction ensures that the outpoint was spendable at some time in the past, it cannot guarantee that this is still the case (the node can still lie by omission). Furthermore, this in theory could be abused to store the UTXO to store data (although that concern was seen as more secondary).
  3. Because of the unverifiability, allowing peers to use and rely on this data was "encouraging bad security practices".
Underlying the whole technical debate was a philosophical one: If we can provide unauthenticated data, and there's no good way to actually authenticate it within the current architectural constraints, should we provide the functionality in the meantime, or wait until it can be fully authenticated?

Bitcoin Core chose the later, and XT was created to allow the former.

Thus the (software) fork was born.
Last edited:
  • Like
Reactions: Bloomie

Emperor Bob

New Member
Aug 19, 2015
Fixes for inv blinding attack

The current commits are 0df4843 and bba09af.

What does it do

This is a partial fix for a well documented denial of service attack called "inv blinding".

What's an "inv" anyway?

Bitcoin's transmission protocol for blocks and transactions works as follows:
  1. Whenever I receive new data (a block or a transaction), I send an inv message to my peers indicating what I have newly available for transfer (this is a list of hashes, which keeps the message short).
  2. Any of my peers can then check if they have this information handy, and request anything they don't yet have, using the getdata message.
  3. I will the send the requested data to that peer.
  4. After receiving this new information they send an inv to their peers, and the process repeats until everyone in the network has received the information.
This is designed to avoid broadcasting a block or a whole bunch of data to peers who already have it.

What is inv blinding?

Instead of replying to the getdata message with the requested data, I just ignore the message. The node on the other end will wait for 2 minutes before assuming I won't reply.

In addition, during that 2 minutes, even if one of its other peers also advertises the same data using its inv message, the node will not request the data (because it knows it's waiting for it already). Only once the 2 minute waiting period is over, will we ask another peer.

To add insult to injury, the peer can advertise the same data using inv repeatedly. 2 minutes becomes 4,6,8... any number that a malicious peer wants.

This leads to serious problems for the targeted node, as it becomes completely oblivious to existence of a particular transaction. This could be used for various evil things.

How do the patches fix this?

There are two patches:

The first one ignores invs from a peer after the first one. This means the attacker only gets to blind the target for 2 minutes.
The second one reduces the download delay to 20 seconds instead of 2 minutes. That number is meant to be high enough that any functioning peer can return the requested information within that time, but short enough not to give the attacker a big opportunity.

Why isn't it in Core?

A pull request fixing this vulnerability was opened by kaczw over a year ago. The pull request was considered entirely acceptable, but due to the massive issue churn that bitcoin goes through, was shelved.

An alternate approach that refactored and fixed a lot of related code all at once was preferred instead. Unfortunately it sat in limbo for almost a year, and hasn't made it into core.

Tom Harding wrote a simpler variant of the original patch by kaczw . That pull request is still waiting for full review. It was merged more urgently into XT, which has a much shorter review queue and a bigger exposure to DOS risk (because it has fewer nodes).
  • Like
Reactions: Bloomie


Jan 23, 2024
Buying cryptocurrency and holding is old news. With copy trading, you can profit from the experience of seasoned traders by copying their moves. Learn the ropes of the market without the stress of making every decision yourself. Click and start copying their trades to earn profits. Interested to know more? Comment below and let's discuss. Remember, investing in cryptocurrencies carries risks, which is why it's always important to do your own research and consult with a financial advisor if needed. C d 1 9 2 2 1 @ g m a i l . c o m