From c2434ad4fb70db024c06eb27364d0a75bcd49d80 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Thu, 23 Jan 2020 13:38:13 +0100 Subject: [PATCH] bitcoin: Compute block hash while parsing This avoids having to re-serialize the block header just to compute the hash. It also frees us from having to carry around all the details in the header and we can hand around a minimal version. --- bitcoin/block.c | 14 ++++++++++++++ bitcoin/block.h | 1 + 2 files changed, 15 insertions(+) diff --git a/bitcoin/block.c b/bitcoin/block.c index 2d48fd56b..dc478291d 100644 --- a/bitcoin/block.c +++ b/bitcoin/block.c @@ -13,6 +13,7 @@ bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams, u8 *linear_tx; const u8 *p; size_t len, i, num; + struct sha256_ctx shactx; if (hexlen && hex[hexlen-1] == '\n') hexlen--; @@ -26,10 +27,19 @@ bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams, if (!hex_decode(hex, hexlen, linear_tx, len)) return tal_free(b); + sha256_init(&shactx); + b->hdr.version = pull_le32(&p, &len); + sha256_le32(&shactx, b->hdr.version); + pull(&p, &len, &b->hdr.prev_hash, sizeof(b->hdr.prev_hash)); + sha256_update(&shactx, &b->hdr.prev_hash, sizeof(b->hdr.prev_hash)); + pull(&p, &len, &b->hdr.merkle_hash, sizeof(b->hdr.merkle_hash)); + sha256_update(&shactx, &b->hdr.merkle_hash, sizeof(b->hdr.merkle_hash)); + b->hdr.timestamp = pull_le32(&p, &len); + sha256_le32(&shactx, b->hdr.timestamp); if (is_elements(chainparams)) { b->elements_hdr = tal(b, struct elements_block_hdr); @@ -45,8 +55,12 @@ bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams, } else { b->hdr.target = pull_le32(&p, &len); + sha256_le32(&shactx, b->hdr.target); + b->hdr.nonce = pull_le32(&p, &len); + sha256_le32(&shactx, b->hdr.nonce); } + sha256_double_done(&shactx, &b->hdr.hash); num = pull_varint(&p, &len); b->tx = tal_arr(b, struct bitcoin_tx *, num); diff --git a/bitcoin/block.h b/bitcoin/block.h index 9fa2b385a..cf0c913b5 100644 --- a/bitcoin/block.h +++ b/bitcoin/block.h @@ -23,6 +23,7 @@ struct bitcoin_block_hdr { le32 timestamp; le32 target; le32 nonce; + struct sha256_double hash; }; struct elements_block_proof {