On September 18th, 2018, a Bitcoin bug was found. But first things first.
On Tuesday morning, waiting for the release of v0.17 of the Bitcoin update (we were at v0.17rc03; rc = release candidate), something strange happened: instead of ve.017, an update of v0.16 was published, going from v0.16.2 to v0.16.3.
This is quite alarming and unusual because it means that an error has been fixed, which must be fixed before the release of v0.17.
Normally, minor updates are published just before the major updates to which they belong, and almost never near subsequent major updates.
When checking the edit, the title explains that it is a “Fix crash bug with duplicate inputs within a transaction“.
The fix changed:
if (!CheckTransaction(*tx, state, false))
if (!CheckTransaction(*tx, state, true))
In short, this is a major change, from “false” to “true” obviously this change was immediately followed by a functional test, which should have verified the correctness).
Aesthetics of the Bug
From an aesthetic point of view, it is interesting to observe how crucial and devastating such a small change can be. And as experts in the field know, in software, an insignificant comma out of place is enough to cause catastrophes.
Technical details of the Bitcoin Bug
In practice, this change restores the control of duplicate inputs within transactions when processing a block, and not only when inserting transactions into the mempool.
The verification was removed with PR #9049 Remove duplicatable duplicatable-input check from CheckTransaction (dated 31-10-2016), introduced in version v0.14 and commented directly in the code with these words:
// Check for duplicate inputs — note that this check is slow so we skip it in CheckBlock
The comment was inserted by Matt Corallo, alias @TheBlueMatt explaining that the verification during the process of the block was useless, since it was already verified during the insertion in the mempool. This edit, according to Corallo, would have gained between 0.5 and 0.7 thousandths of a second in the block process (which on the current 600 thousand blocks cost about 6 minutes of processing, for a 2015 computer with average performance).
Unfortunately for Coral’s intuition, not all blocks that need to be processed must necessarily go through the mempool, an example is the case of blocks generated by miners.
So, in versions v0.14.0rc1 and v0.14.2 the error can be used to make an assertion fail and crash bitcoind/Bitcoin-Qt.
In version v0.15 the claim that v0.14 crashes has been slightly modified with the result that if the output you try to spend twice has been created in a previous block, then double spending becomes possible, effectively creating inflation.
Versions v0.16 and maybe even v0.17.0rc (also corrected with v0.17.rc4) inherited this feature from v0.15.
Synopsis of vulnerable versions
Synopsis from Bitcoin-wiki CVE-2018-17144
The fix is a soft fork because the new version no longer accepts blocks that can be accepted by versions v0.15, v0.16 and maybe even v0.17rc1- v0.17rc3, before the fix.
- PR #14247 “Fix crash bug with duplicate inputs within a transaction” (18-09-2018 21.57 UTC)
- Bitcoin Core 0.16.3 Released (18-09-2018)
- CVE-2018-17144 Full Disclosure (20-09-2018)
It is in the announcements published last September 18th that this Bitcoin bug is reported.
Then, on September 20th, a post in a public forum announced that the error for all versions from 0.15 that, in addition to crashing, could be exploited to generate inflation.
Although it was immediately removed, the news spread and, as we read in the third announcement, at some point it was believed that now the majority of the computing power had adopted the correction. And that is why it was decided to announce the inflation-generating potential of that error; inflation that only the miners could have generated.
Attribution of the discovery
On September 22nd an article entitled “600 Microseconds” appeared in which an anonymous user – Awemany – attributed himself with the discovery of the vulnerability while he was working on the BitcoinABC code, he timestamped the following message on the BU Slack channel with originstamp.org, a platform that publishes the collected hashes on Bitcoin only once every 24 hours:
Diatribe with Peter Todd
The result is a diatribe. In fact, Peter Todd on Twitter starts to heavily insult Awemany about the time of the announcement which, instead, turned out to be caused by a problem in configuring Peter Todd’s browser in the time zone setting.
Although not a native English speaker, the expression “Lying piece of shit” seems to be synonymous with a heated debate.
The Bitcoin community is very accustomed to public debates and drama, which, however, are punctually explained in detail on Reddit.
Awemany‘s arguments on Reddit
Awemany on Reddit explains what happened with a post entitled “To address concerns about my identity“.
Luke-jr thanks Awemany on Reddit
There are several interventions in the discussion on Reddit: for example, in a post the core developer of Bitcoin, luke-jr thanks Awemany, as you can see in the image below:
There will be no catastrophe, the problem is in the final resolution and closure phase, but a functional test has not yet been made public that can make it possible to reproduce the exploitation of error to generate inflation.
on 23-09-2018, 23.5% of nodes had adopted version v0.16.3
There is a disagreement about the data. For example, according to Luke Dashjr:
The law of Bitcoin always applies: Don’t trust, verify
From a “don’t trust, verify” point of view, it is always necessary:
- Check punctually that the correction is not only a mitigation but a real solution;
- Check if the vulnerability has already been exploited in the past to generate inflation (i.e. redo a rescan, and use the gettxoutsetinfo API command).
And that’s why developer Isidoro Ghezzi modified the bitcoind source code (in different branches of the code), adding extra debug and log information to better analyze the problem.
Yesterday at the BalticHoneyBadger 2018 conference, some of the protagonists, such as Mat Corallo and Bryan Bishop, discussed extensively and with extreme transparency the vulnerability, the communication process and the imminent resolution of the same.
Writing software implies bugs, surely the peer review process showed some loosening since the Coral proposal was approved by what we could call the elite of the Bitcoin protocol development: Gregory Maxwell, Pieter Wuille, Wladimir J. van der Laan, (in addition to the proponent Matt Corallo).
Clearly, too many priorities have left room for errors, even if the name of the function touched, the CheckBlock, should have set off a wake-up call.
Effects on markets
Those who had expected a resounding fall in the value of bitcoin on the markets, because of this vulnerability, were disappointed: bitcoin has a highly developed immune system. Moreover, the transparency that characterizes these events has determined a non-effect. In short, whoever shorted, placed the wrong bet.
What can we deduce from this Bitcoin bug? This vulnerability has been present for two years but no one has exploited it to their advantage.
Either the enemies of Bitcoin wanted to do a noble act and abstained from making a profit, or it’s a further confirmation of the technical superiority of Bitcoin developers.
Surely, this vulnerability has shown the importance of peer-review and how it should always be extended and accurate, even when you think that these are minor changes: developing on the Bitcoin protocol is a complex activity and with unpredictable domino effects, as Antonopoulos also explained some time ago.
Need for a revision of release policies in production
The policies of release and production are obviously under scrutiny within the community. For example, it is thought to impose specific unit tests and functional tests, to have a minimum number of programmers for review and to have a quarantine release, of at least 6 months, on another blockchain, such as that of Litecoin.