Beispiel #1
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 #2
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 #3
0
/* Inefficient, but blk*.dat can have zero(?) padding. */
bool next_block_header_prefix(struct file *f, off_t *off, const u32 marker)
{
	while (*off + sizeof(u32) <= f->len) {
		u32 val;

		/* Inefficent, but don't expect it to be far. */
		val = pull_u32(f, off);
		*off -= 4;

		if (val == marker)
			return true;
		(*off)++;
	}
	return false;
}
Beispiel #4
0
static bool pull_foo(const char **p, size_t *len, struct foo *foo)
{
	int ret;

	ret = pull_u64(p, len, &foo->vu64) +
		pull_u32(p, len, &foo->vu32) +
		pull_u16(p, len, &foo->vu16) +
		pull_u8(p, len, &foo->vu8) +
		pull_uchar(p, len, &foo->vuchar) +
		pull_s64(p, len, &foo->vs64) +
		pull_s32(p, len, &foo->vs32) +
		pull_s16(p, len, &foo->vs16) +
		pull_s8(p, len, &foo->vs8) +
		pull_char(p, len, &foo->vchar) +
		pull_bytes(p, len, foo->bytes, sizeof(foo->bytes));

	if (ret != 11)
		ok1(len == 0 && *p == NULL);
	return ret == 11;
}
Beispiel #5
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;
}