static void read_data(void) { if (!opt_hexdata) { fprintf(stderr, "no input data\n"); exit(1); } cstring *txbuf = hex2str(opt_hexdata); if (!txbuf) { fprintf(stderr, "invalid input data\n"); exit(1); } struct const_buffer cbuf = { txbuf->str, txbuf->len }; if (!deser_bp_tx(&tx, &cbuf)) { fprintf(stderr, "TX decode failed\n"); exit(1); } cstr_free(txbuf, true); }
static void test_tx_valid(bool is_valid, struct bp_hashtab *input_map, cstring *tx_ser, bool enforce_p2sh) { struct bp_tx tx; bp_tx_init(&tx); struct const_buffer buf = { tx_ser->str, tx_ser->len }; assert(deser_bp_tx(&tx, &buf) == true); if (is_valid) { /* checking for valid tx; !bp_tx_valid implies test fail */ assert(bp_tx_valid(&tx) == true); } else { /* checking for invalid tx; bp_tx_valid==false implies test * succeeded; no more work to do; bp_tx_valid==true * implies the test will detect the invalid condition * further down in the code */ if (bp_tx_valid(&tx) == false) goto out; } bp_tx_calc_sha256(&tx); unsigned int i; for (i = 0; i < tx.vin->len; i++) { struct bp_txin *txin; txin = parr_idx(tx.vin, i); assert(txin != NULL); cstring *scriptPubKey = bp_hashtab_get(input_map, &txin->prevout); if (scriptPubKey == NULL) { if (!is_valid) { /* if testing tx_invalid.json, missing input * is invalid, and therefore correct */ continue; } char tx_hexstr[BU256_STRSZ], hexstr[BU256_STRSZ]; bu256_hex(tx_hexstr, &tx.sha256); bu256_hex(hexstr, &txin->prevout.hash); dump_comments(); fprintf(stderr, "tx-valid: TX %s\n" "tx-valid: prevout (%s, %u) not found\n", tx_hexstr, hexstr, txin->prevout.n); assert(scriptPubKey != NULL); } bool rc = bp_script_verify(txin->scriptSig, scriptPubKey, &tx, i, enforce_p2sh ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, 0); if (rc != is_valid) { char tx_hexstr[BU256_STRSZ]; bu256_hex(tx_hexstr, &tx.sha256); dump_comments(); fprintf(stderr, "tx-valid: TX %s\n" "tx-valid: txin %u script verification failed\n", tx_hexstr, i); assert(rc == is_valid); } } out: bp_tx_free(&tx); }
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); }