Exemplo n.º 1
0
u32 find_matching_input(const union protocol_tx *tx,
			const struct protocol_input *inp)
{
	unsigned int i;

	/* Figure out which input of other did the spend. */
	for (i = 0; i < num_inputs(tx); i++) {
		if (structeq(&tx_input(tx, i)->input, &inp->input)
		    && tx_input(tx, i)->output == inp->output)
			return i;
	}
	abort();
}
Exemplo n.º 2
0
void complain_bad_amount(struct state *state,
			 struct block *block,
			 const struct protocol_proof *proof,
			 const union protocol_tx *tx,
			 const struct protocol_input_ref *refs,
			 const union protocol_tx *intx[])
{
	struct protocol_pkt_complain_tx_bad_amount *pkt;
	unsigned int i;

	assert(num_inputs(tx));
	log_unusual(state->log, "Block %u ", le32_to_cpu(block->hdr->depth));
	log_add_struct(state->log, struct protocol_double_sha, &block->sha);
	log_add(state->log, " invalid amounts in tx %u of shard %u ",
		proof->pos.txoff, le16_to_cpu(proof->pos.shard));
	log_add_struct(state->log, union protocol_tx, tx);
	log_add(state->log, " with inputs: ");

	pkt = tal_packet(block, struct protocol_pkt_complain_tx_bad_amount,
			 PROTOCOL_PKT_COMPLAIN_TX_BAD_AMOUNT);
	tal_packet_append_proven_tx(&pkt, proof, tx, refs);

	for (i = 0; i < num_inputs(tx); i++) {
		log_add_struct(state->log, union protocol_tx, intx[i]);
		log_add(state->log, " (output %u)",
			le16_to_cpu(tx_input(tx, i)->output));

		tal_packet_append_tx(&pkt, intx[i]);
	}

	publish_complaint(state, block, pkt, NULL);
}
Exemplo n.º 3
0
void complain_bad_input(struct state *state,
			struct block *block,
			const struct protocol_proof *proof,
			const union protocol_tx *tx,
			const struct protocol_input_ref *refs,
			unsigned int bad_input,
			const union protocol_tx *intx)
{
	struct protocol_pkt_complain_tx_bad_input *pkt;

	assert(tx_input(tx, bad_input));
	log_unusual(state->log, "Block %u ", le32_to_cpu(block->hdr->depth));
	log_add_struct(state->log, struct protocol_double_sha, &block->sha);
	log_add(state->log, " invalid due to tx %u in shard %u ",
		proof->pos.txoff, le16_to_cpu(proof->pos.shard));
	log_add_struct(state->log, union protocol_tx, tx);
	log_add(state->log, " with bad input %u ", bad_input);
	log_add_struct(state->log, union protocol_tx, intx);

	pkt = tal_packet(block, struct protocol_pkt_complain_tx_bad_input,
			 PROTOCOL_PKT_COMPLAIN_TX_BAD_INPUT);
	pkt->inputnum = cpu_to_le32(bad_input);

	tal_packet_append_proven_tx(&pkt, proof, tx, refs);
	tal_packet_append_tx(&pkt, intx);

	publish_complaint(state, block, pkt, NULL);
}
Exemplo n.º 4
0
static void json_add_inputs(struct json_result *response, const union protocol_tx *tx)
{
	unsigned int i;

	json_array_start(response, "vin");
	for (i = 0; i < num_inputs(tx); i++)
		json_add_input(response, NULL, tx_input(tx, i));
	json_array_end(response);
}
Exemplo n.º 5
0
static bool find_pending_doublespend(struct state *state,
				     const union protocol_tx *tx)
{
	unsigned int i;

	for (i = 0; i < num_inputs(tx); i++) {
		struct inputhash_elem *ie;
		struct inputhash_iter iter;
		const struct protocol_input *inp = tx_input(tx, i);

		for (ie = inputhash_firstval(&state->inputhash, &inp->input,
				     le16_to_cpu(inp->output), &iter);
		     ie;
		     ie = inputhash_nextval(&state->inputhash, &inp->input,
					    le16_to_cpu(inp->output), &iter)) {
			/* OK, is the tx which spend it pending? */
			if (txhash_get_pending_tx(state, &ie->used_by))
				return true;
		}
	}
	return false;
}
Exemplo n.º 6
0
enum ref_ecode check_tx_refs(struct state *state,
			     const struct block *block,
			     const union protocol_tx *tx,
			     const struct protocol_input_ref *refs,
			     unsigned int *bad_ref,
			     struct block **block_referred_to)
{
	unsigned int i, num = num_inputs(tx);
	bool all_known = true;

	assert(check_refs(state, block, refs, num) == PROTOCOL_ECODE_NONE);
	for (i = 0; i < num; i++) {
		struct block *b;
		struct protocol_txrefhash scratch;
		const struct protocol_txrefhash *txp;

		b = block_ancestor(block, le32_to_cpu(refs[i].blocks_ago));
		txp = txrefhash_in_shard(b->shard[le16_to_cpu(refs[i].shard)],
					 refs[i].txoff, &scratch);
		if (!txp) {
			*bad_ref = i;
			*block_referred_to = b;
			all_known = false;
			/* Keep looking in case there are worse issues. */
			continue;
		}

		if (!structeq(&txp->txhash, &tx_input(tx, i)->input)) {
			*bad_ref = i;
			*block_referred_to = b;
			return ECODE_REF_BAD_HASH;
		}
	}

	if (!all_known)
		return ECODE_REF_UNKNOWN;
	return ECODE_REF_OK;
}