diff --git a/bitcoin/block.c b/bitcoin/block.c index dc478291d8df..424f4f52becb 100644 --- a/bitcoin/block.c +++ b/bitcoin/block.c @@ -4,6 +4,88 @@ #include #include +static void sha256_varint(struct sha256_ctx *ctx, u64 val) +{ + u8 vt[VARINT_MAX_LEN]; + size_t vtlen; + vtlen = varint_put(vt, val); + sha256_update(ctx, vt, vtlen); +} + +static void bitcoin_block_pull_dynafed_params(const u8 **cursor, size_t *len, struct sha256_ctx *shactx) +{ + u8 type; + u64 l1, l2; + pull(cursor, len, &type, 1); + sha256_update(shactx, &type, 1); + switch ((enum dynafed_params_type)type) { + case DYNAFED_PARAMS_NULL: + break; + case DYNAFED_PARAMS_COMPACT: + /* "scriptPubKey" used for block signing */ + l1 = pull_varint(cursor, len); + sha256_varint(shactx, l1); + sha256_update(shactx, *cursor, l1); + pull(cursor, len, NULL, l1); + + /* signblock_witness_limit */ + sha256_update(shactx, *cursor, 4); + pull(cursor, len, NULL, 4); + + /* Skip elided_root */ + sha256_update(shactx, *cursor, 32); + pull(cursor, len, NULL, 32); + break; + + case DYNAFED_PARAMS_FULL: + /* "scriptPubKey" used for block signing */ + l1 = pull_varint(cursor, len); + sha256_varint(shactx, l1); + sha256_update(shactx, *cursor, l1); + pull(cursor, len, NULL, l1); + + /* signblock_witness_limit */ + sha256_update(shactx, *cursor, 4); + pull(cursor, len, NULL, 4); + + /* fedpeg_program */ + l1 = pull_varint(cursor, len); + sha256_varint(shactx, l1); + sha256_update(shactx, *cursor, l1); + pull(cursor, len, NULL, l1); + + /* fedpegscript */ + l1 = pull_varint(cursor, len); + sha256_varint(shactx, l1); + sha256_update(shactx, *cursor, l1); + pull(cursor, len, NULL, l1); + + /* extension space */ + l2 = pull_varint(cursor, len); + sha256_varint(shactx, l2); + for (size_t i = 0; i < l2; i++) { + l1 = pull_varint(cursor, len); + sha256_varint(shactx, l1); + sha256_update(shactx, *cursor, l1); + pull(cursor, len, NULL, l1); + } + break; + } +} + +static void bitcoin_block_pull_dynafed_details(const u8 **cursor, size_t *len, struct sha256_ctx *shactx) +{ + bitcoin_block_pull_dynafed_params(cursor, len, shactx); + bitcoin_block_pull_dynafed_params(cursor, len, shactx); + + /* Consume the signblock_witness */ + u64 numwitnesses = pull_varint(cursor, len); + for (size_t i=0; i ... */ struct bitcoin_block * bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams, @@ -12,8 +94,10 @@ bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams, struct bitcoin_block *b; u8 *linear_tx; const u8 *p; - size_t len, i, num; + size_t len, i, num, templen; struct sha256_ctx shactx; + bool is_dynafed; + u32 height; if (hexlen && hex[hexlen-1] == '\n') hexlen--; @@ -42,16 +126,27 @@ bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams, sha256_le32(&shactx, b->hdr.timestamp); if (is_elements(chainparams)) { - b->elements_hdr = tal(b, struct elements_block_hdr); - b->elements_hdr->block_height = pull_le32(&p, &len); - - size_t challenge_len = pull_varint(&p, &len); - b->elements_hdr->proof.challenge = tal_arr(b->elements_hdr, u8, challenge_len); - pull(&p, &len, b->elements_hdr->proof.challenge, challenge_len); - - size_t solution_len = pull_varint(&p, &len); - b->elements_hdr->proof.solution = tal_arr(b->elements_hdr, u8, solution_len); - pull(&p, &len, b->elements_hdr->proof.solution, solution_len); + /* A dynafed block is signalled by setting the MSB of the version. */ + is_dynafed = (b->hdr.version >> 31 == 1); + + /* elements_header.height */ + height = pull_le32(&p, &len); + sha256_le32(&shactx, height); + + if (is_dynafed) { + bitcoin_block_pull_dynafed_details(&p, &len, &shactx); + } else { + /* elemens_header.challenge */ + templen = pull_varint(&p, &len); + sha256_varint(&shactx, templen); + sha256_update(&shactx, p, templen); + pull(&p, &len, NULL, templen); + + /* elements_header.solution. Not hashed since it'd be + * a circular dependency. */ + templen = pull_varint(&p, &len); + pull(&p, &len, NULL, templen); + } } else { b->hdr.target = pull_le32(&p, &len); @@ -60,7 +155,7 @@ bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams, b->hdr.nonce = pull_le32(&p, &len); sha256_le32(&shactx, b->hdr.nonce); } - sha256_double_done(&shactx, &b->hdr.hash); + sha256_double_done(&shactx, &b->hdr.hash.shad); num = pull_varint(&p, &len); b->tx = tal_arr(b, struct bitcoin_tx *, num); @@ -80,30 +175,7 @@ bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams, void bitcoin_block_blkid(const struct bitcoin_block *b, struct bitcoin_blkid *out) { - struct sha256_ctx shactx; - u8 vt[VARINT_MAX_LEN]; - size_t vtlen; - - sha256_init(&shactx); - sha256_le32(&shactx, b->hdr.version); - sha256_update(&shactx, &b->hdr.prev_hash, sizeof(b->hdr.prev_hash)); - sha256_update(&shactx, &b->hdr.merkle_hash, sizeof(b->hdr.merkle_hash)); - sha256_le32(&shactx, b->hdr.timestamp); - - if (is_elements(chainparams)) { - size_t clen = tal_bytelen(b->elements_hdr->proof.challenge); - sha256_le32(&shactx, b->elements_hdr->block_height); - - vtlen = varint_put(vt, clen); - sha256_update(&shactx, vt, vtlen); - sha256_update(&shactx, b->elements_hdr->proof.challenge, clen); - /* The solution is skipped, since that'd create a circular - * dependency apparently */ - } else { - sha256_le32(&shactx, b->hdr.target); - sha256_le32(&shactx, b->hdr.nonce); - } - sha256_double_done(&shactx, &out->shad); + *out = b->hdr.hash; } /* We do the same hex-reversing crud as txids. */ diff --git a/bitcoin/block.h b/bitcoin/block.h index cf0c913b506b..7f82b8aa55ce 100644 --- a/bitcoin/block.h +++ b/bitcoin/block.h @@ -10,6 +10,12 @@ struct chainparams; +enum dynafed_params_type { + DYNAFED_PARAMS_NULL, + DYNAFED_PARAMS_COMPACT, + DYNAFED_PARAMS_FULL, +}; + struct bitcoin_blkid { struct sha256_double shad; }; @@ -23,22 +29,11 @@ struct bitcoin_block_hdr { le32 timestamp; le32 target; le32 nonce; - struct sha256_double hash; -}; - -struct elements_block_proof { - u8 *challenge; - u8 *solution; -}; - -struct elements_block_hdr { - u32 block_height; - struct elements_block_proof proof; + struct bitcoin_blkid hash; }; struct bitcoin_block { struct bitcoin_block_hdr hdr; - struct elements_block_hdr *elements_hdr; /* tal_count shows now many */ struct bitcoin_tx **tx; }; diff --git a/contrib/pyln-testing/pyln/testing/utils.py b/contrib/pyln-testing/pyln/testing/utils.py index 3071d57441c7..759e48556061 100644 --- a/contrib/pyln-testing/pyln/testing/utils.py +++ b/contrib/pyln-testing/pyln/testing/utils.py @@ -443,17 +443,6 @@ def __init__(self, bitcoin_dir="/tmp/bitcoind-test", rpcport=None): self.rpc = SimpleBitcoinProxy(btc_conf_file=self.conf_file) self.prefix = 'elementsd' - def generate_block(self, numblocks=1, wait_for_mempool=0): - if wait_for_mempool: - if isinstance(wait_for_mempool, str): - wait_for_mempool = [wait_for_mempool] - if isinstance(wait_for_mempool, list): - wait_for(lambda: all(txid in self.rpc.getrawmempool() for txid in wait_for_mempool)) - else: - wait_for(lambda: len(self.rpc.getrawmempool()) >= wait_for_mempool) - # As of 0.16, generate() is removed; use generatetoaddress. - return self.rpc.generate(numblocks) - def getnewaddress(self): """Need to get an address and then make it unconfidential """