Subject: Re: [bitcoin-dev] [patch] Switching Bitcoin Core to sqlite db

From: Gregory Maxwell <[email-masked]>
Date: Sun, 15 Nov 2015 02:10:43 +0000

On Sun, Nov 15, 2015 at 1:45 AM, Peter R <[email-masked]> wrote:
> My previous email described how Type 1 consensus failures can be safely dealt with.  These include many kinds of database exceptions (e.g., the LevelDB fork at block #225,430), or consensus mismatches regarding the max size of a block.

The size of a block is not a type 1 failure. There is a clear, known,
unambiguous, and easily measured rule in the system that a block is
not permitted to have a size over a threshold. A block that violates
this threshold is invalid.   The only way I can see to classify that
as a type 1 failure is to call the violation of any known system rule
a type 1 failure.  "Spends a coin that was already spent" "provides a
signature that doesn't verify with the pubkey" "creates bitcoins out
of thin air" -- these are not logically different than "if size>x
return false".

> Type 2 consensus failures are more severe but also less likely (I’m not aware of a Type 2 consensus failure besides the 92 million bitcoin bug from August 2010).  If Core was to accept a rogue TX that created another 92 million bitcoins, I think it would be a good thing if the other implementations forked away from it (we don’t want bug-for-bug compatibility here).

The only consensus consistency error we've ever that I would have
classified as potentially type 1 had has been the BDB locks issue.
Every other one, including the most recently fixed one (eliminated by
BIP66) was a type 2, by your description. They are _much_ more common;
because if the author understood the possible cases well enough to
create an "I don't know" case, they could have gone one step further
and fully defined it in a consistent way. The fact that an
inconsistency was possible was due to a lack of complete knowledge.

Even in the BDB locks case, I don't know that the type 1 distinction
completely applies, a lower layer piece of software threw an error
that higher layer software didn't know was possible, and so it
interpreted "I don't know" as "no"-- it's not that it chose to treat I
don't know as no, its that it wasn't authored with the possibility of
I don't know in mind, and that exceptions were used to handle general
failures (which should have been treated as no). Once you step back to
the boundary of the calling code (much less the whole application) the
"I don't know" doesn't exist anymore; there.