示例#1
0
文件: base58.c 项目: libbitc/libbitc
static void runtest_encdec(const char *json_base_fn)
{
	char *json_fn = test_filename(json_base_fn);
	cJSON *tests = read_json(json_fn);
	assert((tests->type & 0xFF) == cJSON_Array);

	unsigned int idx;

	for (idx = 0; idx < cJSON_GetArraySize(tests); idx++) {

	    cJSON *test = cJSON_GetArrayItem(tests, idx);
	    assert((test->type & 0xFF) == cJSON_Array);
	    assert(cJSON_GetArraySize(test) == 2);

            cJSON *j_raw = cJSON_GetArrayItem(test, 0);
            cJSON *j_enc = cJSON_GetArrayItem(test, 1);
            assert((j_raw->type & 0xFF) == cJSON_String);
            assert((j_enc->type & 0xFF) == cJSON_String);

            test_encode(j_raw->valuestring,
                        j_enc->valuestring);
            test_decode(j_raw->valuestring,
                        j_enc->valuestring);
	}

	free(json_fn);
	cJSON_Delete(tests);
}
示例#2
0
文件: base58.c 项目: libbitc/libbitc
static void runtest_keys_valid(const char *json_base_fn)
{
	char *json_fn = test_filename(json_base_fn);
	cJSON *tests = read_json(json_fn);
	assert((tests->type & 0xFF) == cJSON_Array);

	unsigned int idx;

	for (idx = 0; idx < cJSON_GetArraySize(tests); idx++) {

	    cJSON *test = cJSON_GetArrayItem(tests, idx);
	    assert((test->type & 0xFF) == cJSON_Array);
	    assert(cJSON_GetArraySize(test) == 3);

		cJSON *j_base58 = cJSON_GetArrayItem(test, 0);
		cJSON *j_payload = cJSON_GetArrayItem(test, 1);
		assert((j_base58->type & 0xFF) == cJSON_String);
		assert((j_payload->type & 0xFF) == cJSON_String);

		cJSON *j_meta = cJSON_GetArrayItem(test, 2);
		assert((j_meta->type & 0xFF) == cJSON_Object);

		cJSON *j_addrtype = cJSON_GetObjectItem(j_meta, "addrType");
		assert(!j_addrtype || ((j_addrtype->type & 0xFF) == cJSON_String));

		cJSON *j_compress = cJSON_GetObjectItem(j_meta, "isCompressed");
		assert(!j_compress || ((j_compress->type & 0xFF) == cJSON_True) ||
		       ((j_compress->type & 0xFF) == cJSON_False));

		bool is_privkey = ((cJSON_GetObjectItem(j_meta, "isPrivkey")->type & 0xFF) == cJSON_True);
		bool is_testnet = ((cJSON_GetObjectItem(j_meta, "isTestnet")->type & 0xFF) == cJSON_True);

		if (is_privkey) {
			test_privkey_valid_enc(
			    j_base58->valuestring,
				hex2str(j_payload->valuestring),
				((j_compress->type & 0xFF) == cJSON_True),
				is_testnet);
			test_privkey_valid_dec(
				j_base58->valuestring,
				hex2str(j_payload->valuestring),
				((j_compress->type & 0xFF) == cJSON_True),
				is_testnet);
		} else {
			test_pubkey_valid_enc(
				j_base58->valuestring,
				hex2str(j_payload->valuestring),
				j_addrtype->valuestring,
				is_testnet);
			test_pubkey_valid_dec(
				j_base58->valuestring,
				hex2str(j_payload->valuestring),
				j_addrtype->valuestring,
				is_testnet);
		}
	}

	free(json_fn);
	cJSON_Delete(tests);
}
示例#3
0
static void runtest(bool is_valid, const char *basefn)
{
	char *fn = test_filename(basefn);
	json_t *tests = read_json(fn);
	assert(json_is_array(tests));

	unsigned int idx;
	for (idx = 0; idx < json_array_size(tests); idx++) {
		json_t *test = json_array_get(tests, idx);
		assert(json_is_array(test));

		const char *scriptSigEnc =
			json_string_value(json_array_get(test, 0));
		const char *scriptPubKeyEnc =
			json_string_value(json_array_get(test, 1));
		assert(scriptSigEnc != NULL);
		assert(scriptPubKeyEnc != NULL);

		cstring *scriptSig = parse_script_str(scriptSigEnc);
		cstring *scriptPubKey = parse_script_str(scriptPubKeyEnc);
		assert(scriptSig != NULL);
		assert(scriptPubKey != NULL);

		test_script(is_valid, scriptSig, scriptPubKey,
			    idx, scriptSigEnc, scriptPubKeyEnc);

		cstr_free(scriptSig, true);
		cstr_free(scriptPubKey, true);
	}

	json_decref(tests);
	free(fn);
}
示例#4
0
 const char * tmpnam(char * buffer){
     const char * name = test_filename(NULL, NULL);
     if(NULL != buffer){
         STRCPY(buffer, name);
     }
     return name;
 }
示例#5
0
文件: base58.c 项目: Artogn/picocoin
static void runtest_encdec(const char *base_fn)
{
	char *fn = NULL;

	fn = test_filename(base_fn);
	json_t *data = read_json(fn);
	assert(json_is_array(data));

	size_t n_tests = json_array_size(data);
	unsigned int i;

	for (i = 0; i < n_tests; i++) {
		json_t *inner;

		inner = json_array_get(data, i);
		assert(json_is_array(inner));

		json_t *j_raw = json_array_get(inner, 0);
		json_t *j_enc = json_array_get(inner, 1);
		assert(json_is_string(j_raw));
		assert(json_is_string(j_enc));

		test_encode(json_string_value(j_raw),
			    json_string_value(j_enc));
		test_decode(json_string_value(j_raw),
			    json_string_value(j_enc));
	}

	free(fn);
	json_decref(data);
}
示例#6
0
static void testit(const char *ser_fn_base)
{
	char *ser_fn = test_filename(ser_fn_base);
	void *data = NULL;
	size_t data_len = 0;

	bool rc = bu_read_file(ser_fn, &data, &data_len, 10*1000*1000);
	assert(rc == true);

	struct const_buffer buf = { data, data_len };

	struct mbuf_reader mbr;
	mbr_init(&mbr, &buf);

	rc = mbr_read(&mbr);
	assert(rc == true);
	assert(mbr.eof == false);
	assert(mbr.error == false);

	assert(!strncmp(mbr.msg.hdr.command, "block", 12));

	rc = mbr_read(&mbr);
	assert(rc == false);
	assert(mbr.eof == true);
	assert(mbr.error == false);

	mbr_free(&mbr);
	free(data);
	free(ser_fn);
}
示例#7
0
int main(int argc , char ** argv) {

  test_dirname();
  test_filename();
  test_alloc_filename_empty_strings();
  exit(0);

}
示例#8
0
int main(int argc, char **argv)
{
    myname = "filetest";

    test_bare_file();
    test_absolute_file();
    test_relative_file();
    test_dot();
    test_filename();
    test_fileperms();
    return 0;
}
示例#9
0
static void runtest(const char *ser_fn_base)
{
	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);

	struct bitc_block block;
	bitc_block_init(&block);

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

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

	unsigned int n_tx, n_out;
	for (n_tx = 0; n_tx < block.vtx->len; n_tx++) {
		struct bitc_tx *tx = parr_idx(block.vtx, n_tx);

		for (n_out = 0; n_out < tx->vout->len; n_out++) {
			struct bitc_txout *txout;

			txout = parr_idx(tx->vout, n_out);
			test_txout(txout);
		}
	}

	bitc_block_free(&block);
	free(msg.data);
	free(ser_fn);
}
示例#10
0
文件: base58.c 项目: libbitc/libbitc
static void runtest_keys_invalid(const char *json_base_fn)
{
	char *json_fn = test_filename(json_base_fn);
	cJSON *tests = read_json(json_fn);
	assert((tests->type & 0xFF) == cJSON_Array);

	unsigned int idx;

	for (idx = 0; idx < cJSON_GetArraySize(tests); idx++) {

	    cJSON *test = cJSON_GetArrayItem(tests, idx);
	    assert((test->type & 0xFF) == cJSON_Array);
	    assert(cJSON_GetArraySize(test) == 1);

	    cJSON *j_base58 = cJSON_GetArrayItem(test, 0);
	    assert((j_base58->type & 0xFF) == cJSON_String);

	    unsigned char addrtype;
	    cstring *payload = base58_decode_check(&addrtype, j_base58->valuestring);
	    bool is_valid = (payload != NULL);

	    if (is_valid)
			if ((addrtype == PUBKEY_ADDRESS_TEST) ||
				(addrtype == PUBKEY_ADDRESS) ||
				(addrtype == SCRIPT_ADDRESS_TEST) ||
				(addrtype == SCRIPT_ADDRESS))
				    is_valid = (payload->len == RIPEMD160_DIGEST_LENGTH);
			else if
				((addrtype == PRIVKEY_ADDRESS_TEST) ||
				(addrtype == PRIVKEY_ADDRESS))
                is_valid = (payload->len == 32 ||
                            (payload->len == 33 && payload->str[32] == 1));
            else is_valid = false;

	    cstr_free(payload, true);
	    assert(!is_valid);
	}

	free(json_fn);
	cJSON_Delete(tests);
}
示例#11
0
static void runtest(bool is_valid, const char *basefn)
{
	char *fn = test_filename(basefn);
	json_t *tests = read_json(fn);
	assert(json_is_array(tests));

	struct bp_hashtab *input_map = bp_hashtab_new_ext(
		input_hash, input_equal,
		free, input_value_free);

	comments = parr_new(8, free);

	unsigned int idx;
	for (idx = 0; idx < json_array_size(tests); idx++) {
		json_t *test = json_array_get(tests, idx);

		if (!json_is_array(json_array_get(test, 0))) {
			const char *cmt =
				json_string_value(json_array_get(test, 0));
			if (cmt)
				parr_add(comments, strdup(cmt));
			continue;			/* comments */
		}

		assert(json_is_array(test));
		assert(json_array_size(test) == 3);
		assert(json_is_string(json_array_get(test, 1)));
		assert(json_is_boolean(json_array_get(test, 2)));

		json_t *inputs = json_array_get(test, 0);
		assert(json_is_array(inputs));

		bp_hashtab_clear(input_map);

		unsigned int i;
		for (i = 0; i < json_array_size(inputs); i++) {
			json_t *input = json_array_get(inputs, i);
			assert(json_is_array(input));

			const char *prev_hashstr =
				json_string_value(json_array_get(input, 0));
			int prev_n =
				json_integer_value(json_array_get(input, 1));
			const char *prev_pubkey_enc =
				json_string_value(json_array_get(input, 2));

			assert(prev_hashstr != NULL);
			assert(json_is_integer(json_array_get(input, 1)));
			assert(prev_pubkey_enc != NULL);

			struct bp_outpt *outpt;
			outpt = malloc(sizeof(*outpt));
			hex_bu256(&outpt->hash, prev_hashstr);
			outpt->n = prev_n;

			cstring *script = parse_script_str(prev_pubkey_enc);
			assert(script != NULL);

			bp_hashtab_put(input_map, outpt, script);
		}

		const char *tx_hexser =
			json_string_value(json_array_get(test, 1));
		assert(tx_hexser != NULL);

		bool enforce_p2sh = json_is_true(json_array_get(test, 2));

		cstring *tx_ser = hex2str(tx_hexser);
		assert(tx_ser != NULL);

		test_tx_valid(is_valid, input_map, tx_ser, enforce_p2sh);

		cstr_free(tx_ser, true);

		if (comments->len > 0) {
			parr_free(comments, true);
			comments = parr_new(8, free);
		}
	}

	parr_free(comments, true);
	comments = NULL;

	bp_hashtab_unref(input_map);
	json_decref(tests);
	free(fn);
}
示例#12
0
static bool go(bool result_only, size_t object_size, size_t binary_size, const char* name) {

    // setup
    if (!result_only) {
        printf("%s: ================\n", name);
        printf("%s: setting up size %i\n", name, (int)object_size);
    }
    if (!setup_test(object_size)) {
        fprintf(stderr, "%s: failed to get setup result.\n", name);
        return false;
    }

    // if this isn't a benchmark (the file creators), nothing left to do
    if (!is_benchmark()) {
        teardown_test();
        if (!result_only)
            printf("%s: done\n", name);
        return true;
    }

    // figure out a reasonable number of iterations between checking the time
    int iterations;
    #ifdef __arm__
    iterations = 1;
    #else
    iterations = 32;
    #endif
    for (size_t i = 5; i > object_size; --i)
        iterations <<= 3;

    uint32_t hash_result;

    // warm up
    if (!result_only)
        printf("%s: warming for %.0f seconds \n", name, WARM_TIME);
    double start_time = dtime();
    while (true) {
        for (int i = 0; i < iterations; ++i) {
            hash_result = 0;
            if (!run_wrapper(&hash_result)) {
                fprintf(stderr, "%s: failed to get benchmark result.\n", name);
                return false;
            }
        }
        if (dtime() - start_time > WARM_TIME)
            break;
    }

    // run tests
    if (!result_only)
        printf("%s: running for %.0f seconds\n", name, WORK_TIME);
    int total_iterations = 0;
    start_time = dtime();
    double end_time;
    while (true) {
        for (int i = 0; i < iterations; ++i) {
            hash_result = HASH_INITIAL_VALUE;
            if (!run_wrapper(&hash_result)) {
                fprintf(stderr, "%s: failed to get benchmark result.\n", name);
                return false;
            }
            ++total_iterations;
        }
        end_time = dtime();
        if (end_time - start_time > WORK_TIME)
            break;
    }

    // print results
    double per_time = (end_time - start_time) / (double)total_iterations * (1000.0 * 1000.0);
    if (result_only) {
        printf("%f\n", per_time);
    } else {
        printf("%s: %i iterations took %f seconds\n", name, total_iterations, end_time - start_time);
        printf("%s: %f microseconds per iteration\n", name, per_time);
        printf("%s: hash result of last run: %08x\n", name, hash_result);
    }

    // write score
    if (!result_only) {
        FILE* file = fopen("results.csv", "a");
        fprintf(file, "\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",%i,%f,%i,%i,\"%08x\"\n",
                name, test_language(), test_version(), test_filename(), test_format(),
                (int)object_size, per_time, (int)binary_size,
                #if BENCHMARK_SIZE_OPTIMIZED
                1,
                #else
                0,
                #endif
                hash_result);
        fclose(file);
    }

    teardown_test();

    return true;
}
示例#13
0
文件: tx.c 项目: Artogn/picocoin
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);

	void *data = NULL;
	size_t data_len = 0;

	bool rc = bu_read_file(ser_fn, &data, &data_len, 100 * 1024 * 1024);
	assert(rc);

	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(data_len == size);

	struct bp_tx tx;
	bp_tx_init(&tx);

	struct const_buffer buf = { data, data_len };

	rc = deser_bp_tx(&tx, &buf);
	assert(rc);

	cstring *gs = cstr_new_sz(10000);
	ser_bp_tx(gs, &tx);

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

	bp_tx_calc_sha256(&tx);

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

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

	assert(tx.vin->len == 1);
	assert(tx.vout->len == 2);

	struct bp_tx tx_copy;
	bp_tx_init(&tx_copy);

	bp_tx_copy(&tx_copy, &tx);
	bp_tx_calc_sha256(&tx_copy);
	assert(bu256_equal(&tx_copy.sha256, &tx.sha256) == true);

	bp_tx_free(&tx);
	bp_tx_free(&tx_copy);
	cstr_free(gs, true);
	free(data);
	free(fn);
	free(ser_fn);
	json_decref(meta);
}
示例#14
0
int main ( int argc, char ** argv )
{
    printf("*****  %s  *****\n",TITLE);
    SetupLib(argc,argv,NAME,PROG_UNKNOWN);

    printf("term width = %d\n",GetTermWidth(80,0));

 #ifdef HAVE_FIEMAP
    printf("* HAVE_FIEMAP defined!\n");
 #endif
 #ifdef FS_IOC_FIEMAP
    printf("* FS_IOC_FIEMAP defined!\n");
 #endif

 #if defined(TEST) && defined(DEBUG)
    if (0)
    {
	id6_t * id6 = (id6_t*)iobuf;
	PRINT("sizeof(id6_t)=%zd, %p,%p,%p -> %zu,%zu,%zu\n",
		sizeof(id6_t),
		id6, id6+1, id6+2,
		(ccp)id6-iobuf, (ccp)(id6+1)-iobuf, (ccp)(id6+2)-iobuf );
    }
 #endif

    if ( argc < 2 )
	help_exit();

    int cmd_stat;
    const CommandTab_t * cmd_ct = ScanCommand(&cmd_stat,argv[1],CommandTab);
    if (!cmd_ct)
    {
	PrintCommandError(CommandTab,argv[1],cmd_stat,0);
	help_exit();
    }

    argv[1] = argv[0];
    argv++;
    argc--;

    switch(cmd_ct->id)
    {
	case CMD_TEST:			return test(argc,argv); break;

	case CMD_FILENAME:		test_filename(argc,argv); break;
	case CMD_MATCH_PATTERN:		test_match_pattern(argc,argv); break;
	case CMD_OPEN_DISC:		test_open_disc(argc,argv); break;
	case CMD_HEXDUMP:		test_hexdump(argc,argv); break;

 #ifdef HAVE_OPENSSL
	case CMD_SHA1:			test_sha1(); break;
 #endif
 #ifndef NO_BZIP2
	case CMD_BZIP2:			test_bzip2(argc,argv); break;
 #endif
 #ifdef HAVE_WORK_DIR
	case CMD_WIIMM:			test_wiimm(argc,argv); break;
 #endif

	case CMD_DEVELOP:		develop(argc,argv); break;

	//case CMD_HELP:
	default:
	    help_exit();
    }

    CloseAll();

    if (SIGINT_level)
	ERROR0(ERR_INTERRUPT,"Program interrupted by user.");

    return max_error;
}
示例#15
0
文件: base58.c 项目: Artogn/picocoin
static void runtest_keys_valid(const char *base_fn)
{
	char *fn = NULL;

	fn = test_filename(base_fn);
	json_t *data = read_json(fn);
	assert(json_is_array(data));

	size_t n_tests = json_array_size(data);
	unsigned int i;

	for (i = 0; i < n_tests; i++) {
		json_t *inner;

		inner = json_array_get(data, i);
		assert(json_is_array(inner));

		json_t *j_base58 = json_array_get(inner, 0);
		json_t *j_payload = json_array_get(inner, 1);
		assert(json_is_string(j_base58));
		assert(json_is_string(j_payload));

		json_t *j_meta = json_array_get(inner, 2);
		assert(json_is_object(j_meta));

		json_t *j_addrtype = json_object_get(j_meta, "addrType");
		assert(!j_addrtype || json_is_string(j_addrtype));

		json_t *j_compress = json_object_get(j_meta, "isCompressed");
		assert(!j_compress || json_is_true(j_compress) ||
		       json_is_false(j_compress));

		bool is_privkey = json_is_true(json_object_get(j_meta, "isPrivkey"));
		bool is_testnet = json_is_true(json_object_get(j_meta, "isTestnet"));

		if (is_privkey) {
			test_privkey_valid_enc(
				json_string_value(j_base58),
				hex2str(json_string_value(j_payload)),
				json_is_true(j_compress),
				is_testnet);
			test_privkey_valid_dec(
				json_string_value(j_base58),
				hex2str(json_string_value(j_payload)),
				json_is_true(j_compress),
				is_testnet);
		} else {
			test_pubkey_valid_enc(
				json_string_value(j_base58),
				hex2str(json_string_value(j_payload)),
				json_string_value(j_addrtype),
				is_testnet);
			test_pubkey_valid_dec(
				json_string_value(j_base58),
				hex2str(json_string_value(j_payload)),
				json_string_value(j_addrtype),
				is_testnet);
		}
	}

	free(fn);
	json_decref(data);
}
示例#16
0
int main(int argc , char ** argv) {
  test_runpath_list();
  test_config( argv[1] );
  test_filename();
  exit(0);
}
示例#17
0
static void runtest(const char *json_base_fn, const char *ser_in_fn,
		    const char *block_in_hash, const char *tx_in_hash)
{
	/* read wallet data */
	char *json_fn = test_filename(json_base_fn);
	json_t *wallet = read_json(json_fn);
	assert(wallet != NULL);

	/* read block data containing incoming payment */
	char *fn = test_filename(ser_in_fn);
	void *data;
	size_t data_len;
	assert(bu_read_file(fn, &data, &data_len, 1 * 1024 * 1024) == true);

	struct bp_block block_in;
	bp_block_init(&block_in);
	struct const_buffer buf = { data, data_len };

	assert(deser_bp_block(&block_in, &buf) == true);
	bp_block_calc_sha256(&block_in);

	/* verify block-in data matches expected block-in hash */
	bu256_t check_hash;
	assert(hex_bu256(&check_hash, block_in_hash) == true);

	assert(bu256_equal(&block_in.sha256, &check_hash) == true);

	/* load key that has received an incoming payment */
	struct bp_key key;
	assert(bp_key_init(&key) == true);

	load_json_key(wallet, &key);

	/* load key into keyset */
	struct bp_keyset ks;
	bpks_init(&ks);

	assert(bpks_add(&ks, &key) == true);

	/* find key matches in block */
	parr *matches;
	matches = bp_block_match(&block_in, &ks);
	assert(matches != NULL);
	assert(matches->len == 1);

	struct bp_block_match *match = parr_idx(matches, 0);
	assert(match->n == 1);			/* match 2nd tx, index 1 */

	/* get matching transaction */
	struct bp_tx *tx = parr_idx(block_in.vtx, match->n);
	bp_tx_calc_sha256(tx);

	/* verify txid matches expected */
	char tx_hexstr[BU256_STRSZ];
	bu256_hex(tx_hexstr, &tx->sha256);
	assert(strcmp(tx_hexstr, tx_in_hash) == 0);

	/* verify mask matches 2nd txout (1 << 1) */
	BIGNUM tmp_mask;
	BN_init(&tmp_mask);
	BN_one(&tmp_mask);
	BN_lshift(&tmp_mask, &tmp_mask, 1);
	assert(BN_cmp(&tmp_mask, &match->mask) == 0);

	/* build merkle tree, tx's branch */
	parr *mtree = bp_block_merkle_tree(&block_in);
	assert(mtree != NULL);
	parr *mbranch = bp_block_merkle_branch(&block_in, mtree, match->n);
	assert(mbranch != NULL);

	/* verify merkle branch for tx matches expected */
	bu256_t mrk_check;
	bp_check_merkle_branch(&mrk_check, &tx->sha256, mbranch, match->n);
	assert(bu256_equal(&mrk_check, &block_in.hashMerkleRoot) == true);

	/* release resources */
	parr_free(mtree, true);
	parr_free(mbranch, true);
	BN_clear_free(&tmp_mask);
	parr_free(matches, true);
	bpks_free(&ks);
	bp_key_free(&key);
	bp_block_free(&block_in);
	json_decref(wallet);
	free(data);
	free(fn);
	free(json_fn);
}
示例#18
0
文件: block.c 项目: aido/picocoin
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);
}