Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 108 additions & 36 deletions bitcoin/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,88 @@
#include <ccan/str/hex/hex.h>
#include <common/type_to_string.h>

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<numwitnesses; i++) {
u64 witsize = pull_varint(cursor, len);
pull(cursor, len, NULL, witsize);
}
}

/* Encoding is <blockhdr> <varint-num-txs> <tx>... */
struct bitcoin_block *
bitcoin_block_from_hex(const tal_t *ctx, const struct chainparams *chainparams,
Expand All @@ -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--;
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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. */
Expand Down
19 changes: 7 additions & 12 deletions bitcoin/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand All @@ -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;
};
Expand Down
11 changes: 0 additions & 11 deletions contrib/pyln-testing/pyln/testing/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
"""
Expand Down