Bitcoin SV has recently been subjected to attacks by a malicious actor with substantial hash power in an attempt to defraud millions of dollars’ worth of BSV. Events like this always force you to look at elements of Bitcoin in ways you might not have considered outside of the new context.
This article outlines these recent attacks and the subsequent mobilisation efforts in response, as well as discussing the steps taken that eventually lead to a positive outcome. It also examines the Bitcoin white paper in the context of the attacks, looking at the scenario presented and determining the correct response.
TL;DR: I am 100% confident that the actions taken by the miners were what the white paper expected of them. I’m also more confident than ever in the resilience of Bitcoin, even in the face of overwhelming hash power.
On June 24, 2021, a 4 block reorganisation was observed on the BSV mainnet that involved a new Hathor merged miner “Zulupool”. At the time, it had the characteristics of a poorly connected node with significant hash power simply having an accidental reorg. The Bitcoin SV Infrastructure Team reached out to this miner to offer technical assistance in improving their connections to other miners but didn’t receive a response.
During the first week of July, further reorgs of similar length occurred. We reached out a second time and Zulupool responded indicating that it wasn’t actually them mining those blocks. Rather, it was the attacker impersonating them by using the Zulupool name in the coinbase string and paying to the Zulupool payout address. For reasons we will explain later in this article, we believe the real Zulupool’s claim to be credible and that it was not actually mining the blocks involved with the reorgs.
The Bitcoin SV Infrastructure Team immediately set about building tools to detect the presence of double-spends, in addition to engaging Bitcoin Association team members and miners in the Bitcoin SV ecosystem to establish communication channels and determine an appropriate response. Bitcoin Association also reached out to exchanges to alert them, as well as to see if we could identify any victims of double-spending. During this first wave of attacks, we were not informed of any victims; we did however put into place tools for automating detection and notification. (We later learned from public court filings by the Bitmart digital asset exchange that it suffered losses from double-spent BSV coins illegally traded by the attacker for other coins.)
Once these tools were in place, the attacker went dormant for several weeks.
On August 3 and 4, on three separate occasions, an unknown malicious attacker secretly mined hidden chains of blocks containing several million USD worth of BSV double-spent transactions. The attacker then released these long chains of blocks all at once on the BSV network, temporarily overtaking the honest chain. This time, the attacker was impersonating honest miner TAAL.
Preparations put in place after the earlier attacks enabled the Bitcoin SV Infrastructure Team to detect these fraudulent blocks within seconds of their release and rapidly communicate to well-known and honest miners who chose to reject the fraudulent blocks with their own hash power, eventually overtaking the attacker’s fork and preventing the double-spends from happening. At the same time, Bitcoin Association contacted exchanges to let them know what was happening and recommended a protective response that would keep them in sync with what the majority of miners had chosen to do.
After three failed attempts to steal funds from exchanges on August 3 and 4, the attacker finally acquiesced as it became evident that honest miners would continue to reject hidden blocks containing double-spends.
During this time, Bitcoin Association published the command that had been used by the honest miners to invalidate the attacker’s previously hidden blocks containing double-spends. This action was taken because it was known that it might take some time for the attacker’s chain to be overtaken by honest miners; this also gave other (non-mining) operators of the Bitcoin SV Node software (such as applications operating as block listeners) the mechanism to follow the chain that the honest majority miners were building upon in anticipation of it becoming the longest chain. No double-spends were allowed to occur during this second wave of attacks. The attacker spent an estimated $200,000 USD in the hope of deriving a greater financial gain through fraud but failed to do so, resulting in a $200,000 loss. In the meantime, the network continued unimpeded, processing a record-breaking volume of transactions and even several record-setting 1 GB blocks.
Miners, charged with the responsibility of enforcing the rules laid out in the Bitcoin protocol, essentially took action to reject invalid transactions and therefore blocks that contained them, on the basis of the ‘first seen rule’ as defined in the Bitcoin white paper.
First seen means precisely what it says: first seen.
Determining first seen requires direct observation at the time of the event whose order must be determined. The Bitcoin blockchain provides a mechanism of converting the direct observations of a set of peer nodes into an accurate record of observed first seen events.
We must however be careful to distinguish between two subjective points of view when discussing the first seen rule.
The first is the view of the participants active on the network at the time of the event. They have direct first-hand knowledge of first seen by observation. Where two related events are a significant time period apart (more than broadcast latency) this view is uncontested. Let’s call this the ‘observed point-of-view (PoV)’.
The other view is of someone at a later time catching up on the history. Let call this the ‘historical PoV’. Since they were not present and able to directly observe the order of events at the time of occurrence, they must rely on the record that nodes produce via the longest chain of blocks. If those who observed the event act upon the first seen rule reliably, as they did recently to produce the record, then the question of which, out of two contested events (double-spends) is the first seen from the historical PoV matches the observed PoV which is the main goal of Bitcoin. By having a record of this correct order, new participants can join the network with an accurate view of the state of all UTXOs and ensure that all future transactions they confirm spend Bitcoins that both a) exist and b) have not already been spent.
There is the potential for ambiguity for a short period from the historical PoV if there are multiple active chain tips with contested points of view (competing blocks that contain double-spends) at the time a new participant joins. But this is a relatively rare occurrence and is typically resolved quickly. This is only relevant for someone who joins the network during this period. Others, even if only listening, are still able to observe; they simply don’t participate in creating the record. Nevertheless, for the vast majority of transactions that are not contested, it remains clear that an event occurred even during this window.
What is interesting is whether the Bitcoin white paper describes the observed or the historical point-of-view, as this speaks to the question of whether a longer chain of blocks containing a clearly false record should be accepted. If it describes the observed point of view, then there is no question that nodes that know a record (block) is incorrect should reject it. It only becomes relevant from the historical point of view when you cannot know the order of events and must rely on the consensus of nodes.
My own interpretation is that the white paper describes a mechanism for converting the historical PoV into a reliable record such that it can serve as an accurate historical PoV.
There are several statements in the white paper that simply do not make sense if considered from the historical PoV, some of which are detailed in the next section.
‘[A] peer-to-peer distributed timestamp server to generate computational proof of the chronological order of transactions.’
Note that in order for a chronological proof to be generated in the first place, that chronological order must first be determined by subjective observations of events as they happen. The acceptance of those observations (in the form of a block) by a majority of nodes at that time is the confirmation required that the observations were correct and agreed by the majority of all active observing nodes at the time.
‘Transactions that are computationally impractical to reverse would protect sellers from fraud…’
That is, that once a transaction is received and accepted, its reversal is deemed to be fraud by the author.
“We need a way for the payee to know that the previous owners did not sign any earlier transactions. For our purposes, the earliest transaction is the one that counts, so we don’t care about later attempts to double-spend.”
Note that it is not possible for two versions of a transaction to appear in the longest chain of blocks; nor is it possible to determine with certainty which of two competing blocks occurred or were publicly broadcast first in real wall-clock time from block timestamps alone. So, the term ‘earliest’ here can only apply to the subjective view observed by nodes active on the network at the time.
There is no special weighting or other consideration given to transactions in a block to override the notion of ‘earliest’.
“The only way to confirm the absence of a transaction is to be aware of all transactions”
‘All transactions’ includes both confirmed and unconfirmed transactions.
“To accomplish this without a trusted party, transactions must be publicly announced”
This public broadcast is critical so that the subjective observations can be made by all active nodes on the network, which brings us back to…
“The payee needs proof that at the time of each transaction, the majority of nodes agreed it was the first received”
From the payee’s perspective, this matters because they want to know the Bitcoins they are receiving are valid.
Again, this is only possible when considering the subjective view observed by nodes active on the network at the time of the double-spend event. And it is the reason transactions must be publicly announced.
“New transactions are broadcast to all nodes”
This is quite unambiguous. Hiding a transaction whilst simultaneously broadcasting a conflicting transaction not only violates this rule, but defines explicitly that the broadcast transaction is valid whilst the hidden transaction is the invalid double spend.
“When a node finds a proof-of-work, it broadcasts the block to all nodes”
This rule makes clear exactly when a block needs to be broadcast, which is immediately upon finding a valid proof-of-work and forming the valid header.
“Nodes accept the block only if all transactions in it are valid and not already spent.”
As we have previously seen, ‘not already spent’ is from the point-of-view of the observer. If they have previously seen a conflicting version of any transaction in the new block, then the block is not valid.
“If two nodes broadcast different versions of the next block simultaneously, some nodes may receive one or the other first. In that case, they work on the first one they received, but save the other branch in case it becomes longer. The tie will be broken when the next proof-of-work is found and one branch becomes longer; the nodes that were working on the other branch will then switch to the longer one.”
Satoshi does not address the case of hidden competing blocks in this section, only competing blocks that are broadcast at almost exactly the same time. Competing blocks seen at very different times are only addressed in the section of the whitepaper that deals with attacks on the network.
“Once the transaction is sent, the dishonest sender starts working in secret on a parallel chain containing an alternate version of his transaction”
“To get the probability the attacker could still catch up now”
“To solve this, we proposed a peer-to-peer network using proof-of-work to record a public history of transactions that quickly becomes computationally impractical for an attacker to change if honest nodes control a majority of CPU power”
The point of the timestamp server is to prevent an ‘attacker’ from changing the record of PUBLIC history that is already subjectively observed and agreed by the majority of nodes on the network at the earlier point in time when the events actually happened. That record includes the order in which events (transactions and blocks) were seen. It does not imply that a successful hidden block attack should be deemed the honest version of that record, especially not when everyone active on the chain at the time of the events knows that it isn’t.
“They vote with their CPU power, expressing their acceptance of valid blocks by working on extending them and rejecting invalid blocks by refusing to work on them”
This comes down to the definition of a valid block. We already know from Section 5 that it must only contain valid transactions, and from Section 2 that valid transactions must be the first seen out of any set of double spends as subjectively observed by honest participants at the time.
“nodes can leave and rejoin the network at will, accepting the longest proof-of-work chain as proof of what happened while they were gone”
There is a significant distinction between accepting the longest proof-of-work chain as proof of what happened while you weren’t present and accepting it if you were present and know that it was not valid. The original goal outlined in section 1 is to generate that proof and it is incumbent on those nodes active at the time to produce it. The white paper is clear that an invalid history must be rejected by nodes with knowledge of that invalidity and write the correct history in its place, ensuring that it becomes part of the longest proof-of-work chain.
That is exactly what the honest miners present at the time of the attack did.
Bitcoin is an economic system that describes intended behaviour. As such, software and algorithms do not override it. The software itself is an implementation of an algorithm that can automate the enforcement of the goal in almost all cases, but algorithms are never perfect. In an adversarial system, every attempt to encode a rule algorithmically creates the potential for that algorithm to be used in a way that wasn’t intended to instead attack the system. And the reality is that some rules are simply difficult to encode in an attack-proof manner.
An example of this would be encoding rules to detect and automatically orphan blocks that contain double-spends. I know from having attempted to define a workable rule set for this purpose many times, that it is easy to do for the common scenarios and would likely protect users very well; however, it opens up many potential attack vectors that could cause chain splits with well-timed actions by an attacker.
Even the first seen rule itself is difficult to encode reliably in the presence of network latency, and whilst it could be resolved via encoding forced block races in most cases, complex cases involving multiple sets of double-spends can cause two sets of nodes to permanently disagree and persistently split from one another. I’m pretty sure this is why the original Bitcoin was coded the way it was, instead of enforcing this rule ruthlessly down to the millisecond.
The point is that code isn’t perfect and sometimes humans intervene. This has happened throughout Bitcoin’s history. The goal of Bitcoin is to produce a persistent and reliable record of what happened on the network. That goal is met by nodes observing, recording and if necessary, taking manual action to ensure the record is accurate and absent of fraud. These actions can be taken by many miners independently and with little or no coordination because truth is relatively easy to find consensus upon.
Those records go well beyond what is recorded in the blockchain. And those records are also being put to good use as further evidence of past events. It is a far more manual process to match up the log files of hundreds of independent machines, but that evidence is just as useful.
There have been a lot of questions and comments about the role of MinerID in addressing these recent attacks. What we saw there was something unusual in that the attacker was impersonating other miners (Zulupool and then TAAL) and even using those miners’ payout addresses. In the case of TAAL being impersonated, this was readily apparent because TAAL routinely signs their blocks with MinerID, so the presence of large numbers of blocks that were not signed immediately created a red flag that impersonation was in play. It also happened to make it easier to identify attacker blocks in this case.
MinerID can play many further roles in building trust with miners through hard-earned proof-of-work reputation. It will, in the future, ensure miners have fast and reliable communication channels to each other in the event of attack scenarios or other critical network-wide events.
For more details on MinerID see: https://github.com/bitcoin-sv-specs/brfc-minerid
Whilst the response put in place was effective and can be repeated, it can be improved upon further. There are several default behavioural changes to the Bitcoin SV Node software that can be put into place and a raft of other mitigating measures, tools, operational processes etc.
For obvious security reasons, these measures will be disclosed only once they are ready to be deployed, so as not to flag any potential vectors of attack. Many of the best minds in Bitcoin infrastructure have been working on these issues throughout and will continue to do so until all of the learnings that have been absorbed from these incidents have been turned into operational and code responses.
One of the primary issues this highlights though is the need for active monitoring of events on the network and the availability of skilled human operators, as well as strong communication channels between corporate actors. Any financial system worth existing has 24/7 operations centres monitoring systems continuously. These already exist on the Bitcoin SV network, but that operational monitoring capability is now much stronger and interconnected than it was.
Ultimately, the Bitcoin white paper described a set of required behaviours for the Bitcoin protocol to function correctly. Most of this can be automated algorithmically and in time more of it will. But it is not always practical to express a rule algorithmically without opening up potential attack vectors when the algorithm is used maliciously, which is why human judgement and intervention is occasionally required. Bitcoin is not code, it is a system of multiple independent parties enforcing a ruleset and rejecting violations of that ruleset by other parties.