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); }
static void runtest(void) { unsigned int i; struct bp_key keys[4]; /* generate keys */ for (i = 0; i < ARRAY_SIZE(keys); i++) { struct bp_key *key = &keys[i]; assert(bp_key_init(key) == true); assert(bp_key_generate(key) == true); } struct bp_keyset ks; bpks_init(&ks); /* add all but one to keyset */ for (i = 0; i < (ARRAY_SIZE(keys) - 1); i++) assert(bpks_add(&ks, &keys[i]) == true); /* verify all-but-one are in keyset */ for (i = 0; i < (ARRAY_SIZE(keys) - 1); i++) { unsigned char md160[RIPEMD160_DIGEST_LENGTH]; void *pubkey; size_t pklen; assert(bp_pubkey_get(&keys[i], &pubkey, &pklen) == true); bu_Hash160(md160, pubkey, pklen); assert(bpks_lookup(&ks, pubkey, pklen, true) == false); assert(bpks_lookup(&ks, pubkey, pklen, false) == true); assert(bpks_lookup(&ks, md160, sizeof(md160), true) == true); assert(bpks_lookup(&ks, md160, sizeof(md160), false) == false); free(pubkey); } /* verify last key not in keyset */ { unsigned char md160[RIPEMD160_DIGEST_LENGTH]; void *pubkey; size_t pklen; struct bp_key *key = &keys[ARRAY_SIZE(keys) - 1]; assert(bp_pubkey_get(key, &pubkey, &pklen) == true); bu_Hash160(md160, pubkey, pklen); assert(bpks_lookup(&ks, pubkey, pklen, true) == false); assert(bpks_lookup(&ks, pubkey, pklen, false) == false); assert(bpks_lookup(&ks, md160, sizeof(md160), true) == false); assert(bpks_lookup(&ks, md160, sizeof(md160), false) == false); free(pubkey); } bpks_free(&ks); for (i = 0; i < ARRAY_SIZE(keys); i++) { struct bp_key *key = &keys[i]; bp_key_free(key); } }