Beispiel #1
0
/* Encoding is <blockhdr> <varint-num-txs> <tx>... */
struct bitcoin_block *bitcoin_block_from_hex(const tal_t *ctx,
					     const char *hex, size_t hexlen)
{
	struct bitcoin_block *b;
	u8 *linear_tx;
	const u8 *p;
	size_t len, i, num;

	if (hexlen && hex[hexlen-1] == '\n')
		hexlen--;

	/* Set up the block for success. */
	b = tal(ctx, struct bitcoin_block);

	/* De-hex the array. */
	len = hex_data_size(hexlen);
	p = linear_tx = tal_arr(ctx, u8, len);
	if (!hex_decode(hex, hexlen, linear_tx, len))
		return tal_free(b);

	pull(&p, &len, &b->hdr, sizeof(b->hdr));
	num = pull_varint(&p, &len);
	b->tx = tal_arr(b, struct bitcoin_tx *, num);
	for (i = 0; i < num; i++)
		b->tx[i] = pull_bitcoin_tx(b->tx, &p, &len);

	/* We should end up not overrunning, nor have extra */
	if (!p || len)
		return tal_free(b);

	tal_free(linear_tx);
	return b;
}
Beispiel #2
0
static void read_output(struct space *space, struct file *f, off_t *poff,
			struct bitcoin_transaction_output *output)
{
	output->amount = pull_u64(f, poff);
	output->script_length = pull_varint(f, poff);
	output->script = space_alloc(space, output->script_length);
	pull_bytes(f, poff, output->script, output->script_length);
}
Beispiel #3
0
/* Pulls a varint which specifies a data length: ensures basic sanity to
 * avoid trivial OOM */
static u64 pull_length(const u8 **cursor, size_t *max)
{
	u64 v = pull_varint(cursor, max);
	if (v > *max) {
		*cursor = NULL;
		*max = 0;
		return 0;
	}
	return v;
}
Beispiel #4
0
static void read_input(struct space *space, struct file *f, off_t *poff,
		       struct bitcoin_transaction_input *input)
{
	pull_hash(f, poff, input->hash);
	input->index = pull_u32(f, poff);
	input->script_length = pull_varint(f, poff);
	input->script = space_alloc(space, input->script_length);
	pull_bytes(f, poff, input->script, input->script_length);

	input->sequence_number = pull_u32(f, poff);
}
Beispiel #5
0
void read_bitcoin_transaction(struct space *space,
			      struct bitcoin_transaction *trans,
			      struct file *f, off_t *poff)
{
	size_t i;
	off_t start = *poff;
	SHA256_CTX sha256;

	trans->version = pull_u32(f, poff);
	trans->input_count = pull_varint(f, poff);
	trans->input = space_alloc_arr(space,
				       struct bitcoin_transaction_input,
				       trans->input_count);
	for (i = 0; i < trans->input_count; i++)
		read_input(space, f, poff, trans->input + i);
	trans->output_count = pull_varint(f, poff);
	trans->output = space_alloc_arr(space,
					struct bitcoin_transaction_output,
					trans->output_count);
	for (i = 0; i < trans->output_count; i++)
               read_output(space, f, poff, trans->output + i);
	trans->lock_time = pull_u32(f, poff);

	/* Bitcoin uses double sha (it's not quite known why...) */
	SHA256_Init(&sha256);
	if (likely(f->mmap)) {
		SHA256_Update(&sha256, f->mmap + start, *poff - start);
	} else {
		u8 *buf = tal_arr(NULL, u8, *poff - start);
		file_read(f, start, *poff - start, buf);
		SHA256_Update(&sha256, buf, *poff - start);
		tal_free(buf);
	}
	SHA256_Final(trans->sha256, &sha256);

	SHA256_Init(&sha256);
	SHA256_Update(&sha256, trans->sha256, sizeof(trans->sha256));
	SHA256_Final(trans->sha256, &sha256);
	trans->len = *poff - start;
}
Beispiel #6
0
bool
read_bitcoin_block_header(struct bitcoin_block *block,
			  struct file *f, off_t *off,
			  u8 block_md[SHA256_DIGEST_LENGTH],
			  const u32 marker)
{
	SHA256_CTX sha256;
	off_t start;

	block->D9B4BEF9 = pull_u32(f, off);
	assert(block->D9B4BEF9 == marker);
	block->len = pull_u32(f, off);

	/* Hash only covers version to nonce, inclusive. */
	start = *off;
	block->version = pull_u32(f, off);
	pull_hash(f, off, block->prev_hash);
	pull_hash(f, off, block->merkle_hash);
	block->timestamp = pull_u32(f, off);
	block->target = pull_u32(f, off);
	block->nonce = pull_u32(f, off);

	/* Bitcoin uses double sha (it's not quite known why...) */
	SHA256_Init(&sha256);
	if (likely(f->mmap)) {
		SHA256_Update(&sha256, f->mmap + start, *off - start);
	} else {
		u8 *buf = tal_arr(NULL, u8, *off - start);
		file_read(f, start, *off - start, buf);
		SHA256_Update(&sha256, buf, *off - start);
		tal_free(buf);
	}
	SHA256_Final(block_md, &sha256);

	SHA256_Init(&sha256);
	SHA256_Update(&sha256, block_md, SHA256_DIGEST_LENGTH);
	SHA256_Final(block_md, &sha256);

	block->transaction_count = pull_varint(f, off);

	return block;
}
Beispiel #7
0
static raw_iblt *read_iblt(std::istream &in, size_t *ibltslices, u64 *seed)
{
	std::string ibltstr;

	// If they choose not to IBLT encode.
	if (in.peek() != 'i')
		return NULL;

	std::getline(in, ibltstr, ',');
	if (ibltstr != "iblt")
		throw std::runtime_error("Bad iblt line");

	std::string iblthex;
	std::getline(in, iblthex);
	if (!in)
		throw std::runtime_error("Bad iblt hex line");

	size_t ibltsize = hex_data_size(iblthex.size());
	u8 data[ibltsize];
	if (!hex_decode(iblthex.c_str(), iblthex.size(), data, sizeof(data)))
		throw std::runtime_error("Bad iblt hex");

	const u8 *p = data;
	size_t len = sizeof(data);
	*ibltslices = pull_varint(&p, &len);
	if (!p)
		throw std::runtime_error("Bad iblt size");

	if (len < 16)
		throw std::runtime_error("Bad iblt seed");
	memcpy(seed, p, sizeof(*seed));
	p += 16;
	len -= 16;

	raw_iblt *riblt = new raw_iblt(*ibltslices);
	if (!riblt->read(p, len))
		throw std::runtime_error("Bad iblt");
	
	return riblt;
}