void msg_vinv_push(struct msg_vinv *mv, uint32_t msg_type, const bu256_t *hash_in) { if (!mv->invs) mv->invs = parr_new(512, free); struct bp_inv *inv = malloc(sizeof(struct bp_inv)); inv->type = msg_type; bu256_copy(&inv->hash, hash_in); parr_add(mv->invs, inv); }
bool blkdb_init(struct blkdb *db, const unsigned char *netmagic, const bu256_t *genesis_block) { memset(db, 0, sizeof(*db)); db->fd = -1; bu256_copy(&db->block0, genesis_block); memcpy(db->netmagic, netmagic, sizeof(db->netmagic)); db->blocks = bp_hashtab_new_ext(bu256_hash, bu256_equal_, NULL, (bp_freefunc) bi_free); return true; }
static void chain_set(void) { char *name = setting("chain"); const struct chain_info *new_chain = chain_find(name); if (!new_chain) { fprintf(stderr, "chain-set: unknown chain '%s'\n", name); exit(1); } bu256_t new_genesis; if (!hex_bu256(&new_genesis, new_chain->genesis_hash)) { fprintf(stderr, "chain-set: invalid genesis hash %s\n", new_chain->genesis_hash); exit(1); } chain = new_chain; bu256_copy(&chain_genesis, &new_genesis); }
void bp_check_merkle_branch(bu256_t *hash, const bu256_t *txhash_in, const GArray *mrkbranch, unsigned int txidx) { bu256_copy(hash, txhash_in); unsigned int i; for (i = 0; i < mrkbranch->len; i++) { const bu256_t *otherside = &g_array_index(mrkbranch, bu256_t,i); if (txidx & 1) bu_Hash_((unsigned char *)hash, otherside, sizeof(bu256_t), hash, sizeof(bu256_t)); else bu_Hash_((unsigned char *)hash, hash, sizeof(bu256_t), otherside, sizeof(bu256_t)); txidx >>= 1; } }
static bool process_block(const struct bp_block *block, int64_t fpos) { 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; struct blkdb_reorg reorg; if (!blkdb_add(&db, bi, &reorg)) { fprintf(plog, "brd: blkdb add fail\n"); goto err_out; } /* FIXME: support reorg */ assert(reorg.conn == 1); assert(reorg.disconn == 0); /* if best chain, mark TX's as spent */ if (bu256_equal(&db.best_chain->hash, &bi->hdr.sha256)) { if (!spend_block(&uset, block, bi->height)) { char hexstr[BU256_STRSZ]; bu256_hex(hexstr, &bi->hdr.sha256); fprintf(plog, "brd: block spend fail %u %s\n", bi->height, hexstr); /* FIXME: bad record is now in blkdb */ goto err_out; } } return true; err_out: bi_free(bi); return false; }
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); }
static void append_input(char *txid_str, char *vout_str) { bu256_t txid; if (!hex_bu256(&txid, txid_str)) { fprintf(stderr, "invalid txid hex\n"); exit(1); } unsigned int vout = atoi(vout_str); struct bp_txin *txin = calloc(1, sizeof(struct bp_txin)); if (!txin) { fprintf(stderr, "OOM\n"); exit(1); } bp_txin_init(txin); bu256_copy(&txin->prevout.hash, &txid); txin->prevout.n = vout; txin->scriptSig = cstr_new(NULL); txin->nSequence = SEQUENCE_FINAL; parr_add(tx.vin, txin); }