Пример #1
0
static bool nc_msg_block(struct nc_conn *conn)
{
	struct const_buffer buf = { conn->msg.data, conn->msg.hdr.data_len };
	struct bp_block block;
	bp_block_init(&block);

	bool rc = false;

	if (!deser_bp_block(&block, &buf))
		goto out;
	bp_block_calc_sha256(&block);
	char hexstr[BU256_STRSZ];
	bu256_hex(hexstr, &block.sha256);

	log_debug("net: %s block %s",
			conn->addr_str, hexstr);

	if (!bp_block_valid(&block)) {
		log_info("net: %s invalid block %s",
			conn->addr_str, hexstr);
		goto out;
	}

    if (!conn->nci->block_process(&block, &conn->msg.hdr, &buf))
    goto out;

	rc = true;

out:
	bp_block_free(&block);
	return rc;
}
Пример #2
0
static bool read_block_msg(struct p2p_message *msg, int64_t fpos)
{
	/* unknown records are invalid */
	if (strncmp(msg->hdr.command, "block",
		    sizeof(msg->hdr.command)))
		return false;

	bool rc = false;

	struct bp_block block;
	bp_block_init(&block);

	struct const_buffer buf = { msg->data, msg->hdr.data_len };
	if (!deser_bp_block(&block, &buf)) {
		fprintf(plog, "brd: block deser fail\n");
		goto out;
	}
	bp_block_calc_sha256(&block);

	if (!bp_block_valid(&block)) {
		fprintf(plog, "brd: block not valid\n");
		goto out;
	}

	rc = process_block(&block, fpos);

out:
	bp_block_free(&block);
	return rc;
}
Пример #3
0
static void read_test_msg(struct blkdb *db, struct bp_utxo_set *uset,
			  const struct p2p_message *msg, int64_t fpos)
{
	assert(strncmp(msg->hdr.command, "block",
		       sizeof(msg->hdr.command)) == 0);

	struct bp_block block;
	bp_block_init(&block);

	struct const_buffer buf = { msg->data, msg->hdr.data_len };
	assert(deser_bp_block(&block, &buf) == true);
	bp_block_calc_sha256(&block);

	assert(bp_block_valid(&block) == true);

	struct blkinfo *bi = bi_new();
	bu256_copy(&bi->hash, &block.sha256);
	bp_block_copy_hdr(&bi->hdr, &block);
	bi->n_file = 0;
	bi->n_pos = fpos + P2P_HDR_SZ;

	assert(blkdb_add(db, bi) == true);

	/* if best chain, mark TX's as spent */
	if (bu256_equal(&db->hashBestChain, &bi->hdr.sha256)) {
		if (!spend_block(uset, &block, bi->height)) {
			char hexstr[BU256_STRSZ];
			bu256_hex(hexstr, &bi->hdr.sha256);
			fprintf(stderr, 
				"chain-verf: block fail %u %s\n",
				bi->height, hexstr);
			assert(!"spend_block");
		}
	}

	bp_block_free(&block);
}
Пример #4
0
static void runtest(const char *json_fn_base, const char *ser_fn_base)
{
	char *fn = test_filename(json_fn_base);
	json_t *meta = read_json(fn);
	assert(json_is_object(meta));

	char *ser_fn = test_filename(ser_fn_base);
	int fd = file_seq_open(ser_fn);
	if (fd < 0) {
		perror(ser_fn);
		exit(1);
	}

	struct p2p_message msg = {};
	bool read_ok = false;
	bool rc = fread_message(fd, &msg, &read_ok);
	assert(rc);
	assert(read_ok);
	assert(!strncmp(msg.hdr.command, "block", 12));

	close(fd);

	const char *hashstr = json_string_value(json_object_get(meta, "hash"));
	assert(hashstr != NULL);

	unsigned int size = json_integer_value(json_object_get(meta, "size"));
	assert((24 + msg.hdr.data_len) == size);

	struct bp_block block;
	bp_block_init(&block);

	struct const_buffer buf = { msg.data, msg.hdr.data_len };

	rc = deser_bp_block(&block, &buf);
	assert(rc);

	cstring *gs = cstr_new_sz(100000);
	ser_bp_block(gs, &block);

	if (gs->len != msg.hdr.data_len) {
		fprintf(stderr, "gs->len %ld, msg.hdr.data_len %u\n",
			(long)gs->len, msg.hdr.data_len);
		assert(gs->len == msg.hdr.data_len);
	}
	assert(memcmp(gs->str, msg.data, msg.hdr.data_len) == 0);

	bp_block_calc_sha256(&block);

	char hexstr[BU256_STRSZ];
	bu256_hex(hexstr, &block.sha256);

	if (strcmp(hexstr, hashstr)) {
		fprintf(stderr, "block: wanted hash %s,\n       got    hash %s\n",
			hashstr, hexstr);
		assert(!strcmp(hexstr, hashstr));
	}

	rc = bp_block_valid(&block);
	assert(rc);

	bp_block_free(&block);
	cstr_free(gs, true);
	free(msg.data);
	free(fn);
	free(ser_fn);
	json_decref(meta);
}
Пример #5
0
static bool nc_msg_block(struct nc_conn *conn)
{
	struct const_buffer buf = { conn->msg.data, conn->msg.hdr.data_len };
	struct bp_block block;
	bp_block_init(&block);

	bool rc = false;

	if (!deser_bp_block(&block, &buf))
		goto out;
	bp_block_calc_sha256(&block);
	char hexstr[BU256_STRSZ];
	bu256_hex(hexstr, &block.sha256);

	if (debugging) {
		fprintf(plog, "net: %s block %s\n",
			conn->addr_str,
			hexstr);
	}

	if (!bp_block_valid(&block)) {
		fprintf(plog, "net: %s invalid block %s\n",
			conn->addr_str,
			hexstr);
		goto out;
	}

	/* check for duplicate block */
	if (blkdb_lookup(&db, &block.sha256) ||
	    have_orphan(&block.sha256))
		goto out_ok;

	struct iovec iov[2];
	iov[0].iov_base = &conn->msg.hdr;	// TODO: endian bug?
	iov[0].iov_len = sizeof(conn->msg.hdr);
	iov[1].iov_base = (void *) buf.p;	// cast away 'const'
	iov[1].iov_len = buf.len;
	size_t total_write = iov[0].iov_len + iov[1].iov_len;

	/* store current file position */
	off64_t fpos64 = lseek64(blocks_fd, 0, SEEK_CUR);
	if (fpos64 == (off64_t)-1) {
		fprintf(plog, "blocks: lseek64 failed %s\n",
			strerror(errno));
		goto out;
	}

	/* write new block to disk */
	errno = 0;
	ssize_t bwritten = writev(blocks_fd, iov, ARRAY_SIZE(iov));
	if (bwritten != total_write) {
		fprintf(plog, "blocks: write failed %s\n",
			strerror(errno));
		goto out;
	}
	/* process block */
	if (!process_block(&block, fpos64)) {
		fprintf(plog, "blocks: process-block failed\n");
		goto out;
	}

out_ok:
	rc = true;

out:
	bp_block_free(&block);
	return rc;
}