bool bp_block_valid(struct bp_block *block) { bp_block_calc_sha256(block); if (!block->vtx || !block->vtx->len) return false; if (bp_block_ser_size(block) > MAX_BLOCK_SIZE) return false; if (!bp_block_valid_target(block)) return false; time_t now = time(NULL); if (block->nTime > (now + (2 * 60 * 60))) return false; if (!bp_block_valid_merkle(block)) return false; unsigned int i; for (i = 0; i < block->vtx->len; i++) { struct bp_tx *tx; tx = g_ptr_array_index(block->vtx, i); if (!bp_tx_valid(tx)) return false; bool is_coinbase_idx = (i == 0); bool is_coinbase = bp_tx_coinbase(tx); if (is_coinbase != is_coinbase_idx) return false; } return 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); }