Beispiel #1
0
Pkt *accept_pkt_htlc_fulfill(struct peer *peer, const Pkt *pkt)
{
	const UpdateFulfillHtlc *f = pkt->update_fulfill_htlc;
	size_t n_us, n_them;
	struct sha256 r, rhash;
	Pkt *err;

	err = find_commited_htlc(peer, f->id, &n_us, &n_them);
	if (err)
		return err;

	/* Now, it must solve the HTLC rhash puzzle. */
	proto_to_sha256(f->r, &r);
	sha256(&rhash, &r, sizeof(r));

	if (!structeq(&rhash, &peer->us.staging_cstate->a.htlcs[n_us].rhash))
		return pkt_err(peer, "Invalid r for %"PRIu64, f->id);

	/* Same ID must have same rhash */
	assert(structeq(&rhash, &peer->them.staging_cstate->b.htlcs[n_them].rhash));

	funding_a_fulfill_htlc(peer->us.staging_cstate, n_us);
	funding_b_fulfill_htlc(peer->them.staging_cstate, n_them);
	return NULL;
}
Beispiel #2
0
static bool check_preimage(const Sha256Hash *preimage, const struct sha256 *hash)
{
	struct sha256 h;

	proto_to_sha256(preimage, &h);
	sha256(&h, &h, sizeof(h));
	return structeq(&h, hash);
}
Beispiel #3
0
bool check_proof_byhash(const struct protocol_proof *proof,
			const struct block *b,
			const struct protocol_txrefhash *txrefhash)
{
	struct protocol_double_sha merkle;
	u16 shardnum = le16_to_cpu(proof->pos.shard);

	assert(structeq(&b->sha, &proof->pos.block));

	/* Can't be right if shard doesn't exist. */
	if (shardnum >= (1 << b->hdr->shard_order))
		return false;

	/* Can't be the right one if not within shard */
	if (proof->pos.txoff >= b->shard_nums[shardnum])
		return false;

	proof_merkles_to(txrefhash, proof, &merkle);

	return structeq(&b->merkles[shardnum], &merkle);
}
Beispiel #4
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();
}
Beispiel #5
0
static void check_preimage(const Sha256Hash *preimage,
                           const struct sha256 *old,
                           const struct sha256 *h,
                           const char *file)
{
    struct sha256 sha;

    if (!h)
        return;

    proto_to_sha256(preimage, &sha);
    sha256(&sha, &sha, sizeof(sha));
    if (!structeq(&sha, old))
        errx(1, "Invalid preimage in %s!", file);
}
Beispiel #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;
}
Beispiel #7
0
Pkt *accept_pkt_htlc_fulfill(struct peer *peer, const Pkt *pkt)
{
	const UpdateFulfillHtlc *f = pkt->update_fulfill_htlc;
	struct htlc *htlc;
	struct sha256 rhash;
	struct rval r;
	Pkt *err;
	union htlc_staging stage;

	err = find_commited_htlc(peer, f->id, &htlc);
	if (err)
		return err;

	/* Now, it must solve the HTLC rhash puzzle. */
	proto_to_rval(f->r, &r);
	sha256(&rhash, &r, sizeof(r));

	if (!structeq(&rhash, &htlc->rhash))
		return pkt_err(peer, "Invalid r for %"PRIu64, f->id);

	/* We can relay this upstream immediately. */
	our_htlc_fulfilled(peer, htlc, &r);

	/* BOLT #2:
	 *
	 * ... and the receiving node MUST add the HTLC fulfill/fail
	 * to the unacked changeset for its local commitment.
	 */
	cstate_fulfill_htlc(peer->local.staging_cstate, htlc, OURS);

	stage.fulfill.fulfill = HTLC_FULFILL;
	stage.fulfill.htlc = htlc;
	stage.fulfill.r = r;
	add_unacked(&peer->local, &stage);
	return NULL;
}
Beispiel #8
0
int main(void)
{
	void *ctx = tal(NULL, char);
	char *p;
	bool test_net;
	struct protocol_address addr, addr2;
	struct protocol_pubkey pubkey, pubkey2;
	EC_KEY *key;

	memset(&addr, 0xFF, sizeof(addr));
	/* Normal net */
	p = pettycoin_to_base58(ctx, false, &addr, false);
	assert(tal_parent(p) == ctx);
	assert(p[0] == 'P');
	assert(strlen(p) < BASE58_ADDR_MAX_LEN);
	assert(strspn(p, enc) == strlen(p));
	memset(&addr2, 0, sizeof(addr2));
	assert(pettycoin_from_base58(&test_net, &addr2, p, strlen(p)));
	assert(test_net == false);
	assert(structeq(&addr, &addr2));

	/* Test net */
	p = pettycoin_to_base58(ctx, true, &addr, false);
	assert(tal_parent(p) == ctx);
	assert(p[0] == 'q');
	assert(strlen(p) < BASE58_ADDR_MAX_LEN);
	assert(strspn(p, enc) == strlen(p));
	memset(&addr2, 0, sizeof(addr2));
	assert(pettycoin_from_base58(&test_net, &addr2, p, strlen(p)));
	assert(test_net == true);
	assert(structeq(&addr, &addr2));

	/* Bitcoin-style, normal net */
	p = pettycoin_to_base58(ctx, false, &addr, true);
	assert(tal_parent(p) == ctx);
	assert(strstarts(p, "P-1"));
	assert(strlen(p) < BASE58_ADDR_MAX_LEN + 2);
	assert(strspn(p+2, enc) == strlen(p+2));
	memset(&addr2, 0, sizeof(addr2));
	assert(pettycoin_from_base58(&test_net, &addr2, p, strlen(p)));
	assert(test_net == false);
	assert(structeq(&addr, &addr2));

	/* Bitcoin-style, test net */
	p = pettycoin_to_base58(ctx, true, &addr, true);
	assert(tal_parent(p) == ctx);
	assert(strstarts(p, "P-m") || strstarts(p, "P-n"));
	assert(strlen(p) < BASE58_ADDR_MAX_LEN + 2);
	assert(strspn(p+2, enc) == strlen(p+2));
	memset(&addr2, 0, sizeof(addr2));
	assert(pettycoin_from_base58(&test_net, &addr2, p, strlen(p)));
	assert(test_net == true);
	assert(structeq(&addr, &addr2));

	/* From our test gateway key */
	key = key_from_base58("P-cRhETWFwVpi7q8Vjs7KqvYYGZC5htvT3ddnd9hJk5znSohTBHRkT",
			      strlen("P-cRhETWFwVpi7q8Vjs7KqvYYGZC5htvT3ddnd9hJk5znSohTBHRkT"),
			      &test_net, &pubkey);
	assert(key);
	assert(test_net == true);

	/* Check pubkey is correct. */
	pubkey_to_addr(&pubkey, &addr);
	p = pettycoin_to_base58(ctx, true, &addr, true);
	assert(streq(p, "P-muzRJJzenB7uKzokx21W2QGobfDEZfiH1u"));

	/* Check we can return it OK (bitcoin style) */
	p = key_to_base58(ctx, true, key, true);
	assert(streq(p, "P-cRhETWFwVpi7q8Vjs7KqvYYGZC5htvT3ddnd9hJk5znSohTBHRkT"));

	/* Now, turn it into pettcoin-style key. */
	p = key_to_base58(ctx, true, key, false);
	assert(strspn(p, enc) == strlen(p));

	/* Convert back, check it is OK. */
	EC_KEY_free(key);
	key = key_from_base58(p, strlen(p), &test_net, &pubkey2);
	assert(key);
	assert(test_net == true);
	assert(structeq(&pubkey, &pubkey2));
	EC_KEY_free(key);

	/* FIXME: Test non-test network keys! */

	tal_free(ctx);
	return 0;
}
Beispiel #9
0
bool txwatch_eq(const struct txwatch *w, const struct sha256_double *txid)
{
	return structeq(&w->txid, txid);
}
Beispiel #10
0
bool txowatch_eq(const struct txowatch *w, const struct txwatch_output *out)
{
	return structeq(&w->out.txid, &out->txid)
		&& w->out.index == out->index;
}