Fixpoint

2020-01-07

Errata for gbw-node drafts to date, and Bitcoin txid collisions

Filed under: Bitcoin, Software — Jacob Welsh @ 18:11

I've discovered a few mistakes in my wallet code published so far, one from pure carelessness and two from insufficient cognizance of environmental hazards, which together seem interesting enough for a dedicated article.

The first is in the HTTP Basic authentication header in the JSON-RPC client: I slipped in an erroneous space character after the colon in the base64 input, in the course of a hasty and perhaps excessive last-minute style cleanup. I discovered this through basic testing as it broke authentication altogether. I will update the article but preserve the original file for whoever cares to diff.

The second, found in code not yet written up, is the obnoxious but standardized behavior of the SQL SUM function, whereby the sum of the empty set is NULL rather than zero. In Python this becomes the None object then my code passes it to functions that expect integers. I first tried to work around at the Python level, but soon found this to be awkward especially for queries returning multiple columns where some were perfectly well-behaved integers. A fix closer to the source of the problem is found in the standard SQL coalesce function, though having to use this as boilerplate around every use of SUM is not exactly satisfying.

The above fixes are in: draft2/gbw-node.py.

The third and deepest might not even be a problem in practice, but seems to warrant further investigation. From the schema:

CREATE UNIQUE INDEX i_tx_hash ON tx(hash);

The problem is that Bitcoin doesn't guarantee uniqueness of transaction contents - miners can use identical coinbase inputs - despite the fact that the implementation assumes unique transaction hashes! The possibility of collision was realized in 2010,(i) condemning all future implementers to bugwise compatibility, whatever that means. The Power Rangers in their boundless wisdom addressed this in BIP 30 except without solving all that much. Further discussions I've been chewing on include Mirco… Mezzo… Macroflation—Overheated Economy (archived) and of course the forum log. Takeaways so far are that 1) the sky is probably (still) not falling regarding Bitcoin itself, but 2) this could possibly be used by malicious peers to hard-wedge syncing TRB nodes.

The conservative approach for my program would seem to be leaving the schema as is and letting SQL throw an integrity error if you try to monitor the addresses in question. Relaxing the unique constraint should be possible with some further changes to the code, but the question would arise of how exactly the quasi-duplicate outputs should be interpreted. Please speak up in the comments if you know of further references or conclusions on this topic!

  1. Block pair 91722/91880 paying address 1GktTvnY8KGfAS72DhzGYJRyaQNvYrK9Fg and 91812/91842 paying address 16va6NxJrMGe5d2LP6wUzuVnzBBoKQZKom. [^]

3 Comments »

  1. [...] for errata. I'm just now noticing these were added in 2.7, ugh... sorry, 2.6 users. [^]My blog will be going [...]

    Pingback by Draft gbw-node frontend, part 1 « Fixpoint — 2020-01-07 @ 18:17

  2. > though having to use this as boilerplate around every use of SUM is not exactly satisfying

    Not that I can reproduce the item on mysql's notion of sql,

    mysql> select sum("");
    +---------+
    | sum("") |
    +---------+
    | 0 |
    +---------+
    1 row in set (0.00 sec)

    mysql> select sum(0);
    +--------+
    | sum(0) |
    +--------+
    | 0 |
    +--------+
    1 row in set (0.00 sec)

    mysql> select sum("1");
    +----------+
    | sum("1") |
    +----------+
    | 1 |
    +----------+
    1 row in set (0.00 sec)

    mysql> select sum("q");
    +----------+
    | sum("q") |
    +----------+
    | 0 |
    +----------+
    1 row in set, 1 warning (0.00 sec)

    But... what happens if you type out your sum as SUM(0+...) rather than SUM(...) ?

    I don't merely ask because I am trying to provide the immediate solution ; and I certainly do not ask in that exact form because I am merely trying to provide the immediate solution.

    What happens if you deploy the cheap, self-obvious fix that's fitted to the other's idiocy, rather than trying to forever and no matter what speak your own mental language to everyone ?

    Comment by Mircea Popescu — 2020-01-08 @ 10:58

  3. I get the same results in your examples; perhaps it's only when summing a column:

    mysql> select sum(x) from (select 1 as x) as temp;
    +--------+
    | sum(x) |
    +--------+
    | 1 |
    +--------+
    1 row in set (0.00 sec)

    mysql> select sum(x) from (select 1 as x limit 0) as temp;
    +--------+
    | sum(x) |
    +--------+
    | NULL |
    +--------+
    1 row in set (0.00 sec)

    mysql> select sum(0+x) from (select 1 as x limit 0) as temp;
    +----------+
    | sum(0+x) |
    +----------+
    | NULL |
    +----------+
    1 row in set (0.00 sec)

    mysql> select 0+sum(x) from (select 1 as x limit 0) as temp;
    +----------+
    | 0+sum(x) |
    +----------+
    | NULL |
    +----------+
    1 row in set (0.00 sec)

    > What happens if you deploy the cheap, self-obvious fix that's fitted to the other's idiocy, rather than trying to forever and no matter what speak your own mental language to everyone ?

    A happy ending I'd imagine, if at the cost of having to study the other's idiocy in depth for the cheap fix to become obvious. Which strikes me as something you work at quite a bit.

    The link calls to mind the fox and the stork. Though now I wanna know what the hedgehog did!!

    Comment by Jacob Welsh — 2020-01-08 @ 18:39

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by MP-WP. Copyright Jacob Welsh.