The BIP that ensured Bitcoin's fixed monetary supply.

Until 2014 there was a bug in Bitcoin that would have lead to infinite inflation. Thankfully the bug was fixed, capping the total supply at 21,000,000 bitcoins.

What was the inflation bug?

From bip42:

As is well known, Satoshi was a master programmer whose knowledge of C++ was surpassed only by his knowledge of Japanese culture. The code below:

int64_t nSubsidy = 50 * COIN;
// Subsidy is cut in half every 210,000 blocks
// which will occur approximately every 4 years.
nSubsidy >>= (nHeight / 210000);

is carefully written to rely on undefined behaviour in the C++ specification – perhaps so it can be hardware accelerated in future.

What is undefined behavior?

"Undefined behavior" is the name given to certain valid expressions in the C++ language whose implementation the standards leave undefined. For example, accessing an array out of bounds or shifting an integer beyond its bit range. Undefined behavior is almost always a bug.

When such undefined behaviors are encountered by a compiler, it is left to the compiler writer’s discretion to determine how best to handle them. This means the program is technically allowed to do anything from crashing to opening a web socket and downloading a YouTube video when it encounters undefined behavior. Thankfully, most compiler writers are reasonable, and instead they usually attempt to keep your program functioning in the presence of these unsavory expressions.

The primary problem with writing programs that exhibit undefined behavior is that they immediately become non-portable. Since the standard does not define how the behavior could be handled, different compilers and even different versions of the same compiler or the same compiler targeting different platforms could all handle the behavior in completely different ways. This means that the program writer cannot know in advance what effect their code will have.

Despite this lack of guarantee, there is often enough conformance between compilers to lull programmers into the belief that such behavior is actually well-defined.

Demonstrating the inflation bug

// satoshis_infinite_inflation_bug.cpp

#include <iostream>
#include <iomanip>
#include <stdint.h>
using namespace std;

int main(int argc, char* argv[]) {
  int64_t minerReward = INT64_MAX;

  for (int32_t shift = 0; shift < 128; shift++) {
    cout << "#"
         << std::dec << std::setw(3) << std::setfill('0')
         << shift
         << ": "
         << std::hex << std::setw(16) << std::setfill('0')
         << (minerReward >> shift) << endl;
  }

  return 0;
}
gcc -std=c++98 satoshis_infinite_inflation_bug.cpp -o satoshis_infinite_inflation_bug

Output:

#000: 7fffffffffffffff
#001: 3fffffffffffffff
#002: 1fffffffffffffff
#003: 0fffffffffffffff
#004: 07ffffffffffffff
#005: 03ffffffffffffff
#006: 01ffffffffffffff
#007: 00ffffffffffffff
#008: 007fffffffffffff
#009: 003fffffffffffff
#010: 001fffffffffffff
#011: 000fffffffffffff
#012: 0007ffffffffffff
... snip ...
#061: 0000000000000003
#062: 0000000000000001
#063: 0000000000000000
#064: 7fffffffffffffff
#065: 3fffffffffffffff
#066: 1fffffffffffffff
#067: 0fffffffffffffff
#068: 07ffffffffffffff
... snip ...

What specific undefined behavior was fixed by bip42?

Shifting a 64-bit signed integer value to the right by more than its bit range of 63 bits. From the C++98 standard, §5.8 "Shift operators"

The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.

incoming(1): bitcoin

Last update on 7E4B15, edited 1 times. 1/1thh