示例#1
0
/* Send a preimage for the old commit tx.  The one we've just committed to is
 * in peer->us.commit. */
void queue_pkt_revocation(struct peer *peer)
{
	UpdateRevocation *u = tal(peer, UpdateRevocation);

	update_revocation__init(u);

	assert(peer->commit_tx_counter > 0);
	assert(peer->us.commit);
	assert(peer->us.commit->prev);
	assert(!peer->us.commit->prev->revocation_preimage);

	/* We have their signature on the current one, right? */
	assert(peer->us.commit->sig);

	peer->us.commit->prev->revocation_preimage
		= tal(peer->us.commit->prev, struct sha256);
	peer_get_revocation_preimage(peer, peer->commit_tx_counter-1,
				     peer->us.commit->prev->revocation_preimage);
	u->revocation_preimage
		= sha256_to_proto(u, peer->us.commit->prev->revocation_preimage);

	u->next_revocation_hash = sha256_to_proto(u,
						  &peer->us.next_revocation_hash);
	u->ack = peer_outgoing_ack(peer);

	queue_pkt(peer, PKT__PKT_UPDATE_REVOCATION, u);
}
示例#2
0
void queue_pkt_open(struct peer *peer, OpenChannel__AnchorOffer anchor)
{
	OpenChannel *o = tal(peer, OpenChannel);

	/* Set up out commit info now: rest gets done in setup_first_commit
	 * once anchor is established. */
	peer->local.commit = new_commit_info(peer);
	peer->local.commit->revocation_hash = peer->local.next_revocation_hash;
	peer_get_revocation_hash(peer, 1, &peer->local.next_revocation_hash);

	open_channel__init(o);
	o->revocation_hash = sha256_to_proto(o, &peer->local.commit->revocation_hash);
	o->next_revocation_hash = sha256_to_proto(o, &peer->local.next_revocation_hash);
	o->commit_key = pubkey_to_proto(o, peer->dstate->secpctx,
					&peer->local.commitkey);
	o->final_key = pubkey_to_proto(o, peer->dstate->secpctx,
				       &peer->local.finalkey);
	o->delay = tal(o, Locktime);
	locktime__init(o->delay);
	o->delay->locktime_case = LOCKTIME__LOCKTIME_BLOCKS;
	o->delay->blocks = rel_locktime_to_blocks(&peer->local.locktime);
	o->initial_fee_rate = peer->local.commit_fee_rate;
	if (anchor == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR)
		assert(peer->local.offer_anchor == CMD_OPEN_WITH_ANCHOR);
	else {
		assert(anchor == OPEN_CHANNEL__ANCHOR_OFFER__WONT_CREATE_ANCHOR);
		assert(peer->local.offer_anchor == CMD_OPEN_WITHOUT_ANCHOR);
	}
		
	o->anch = anchor;
	o->min_depth = peer->local.mindepth;
	queue_pkt(peer, PKT__PKT_OPEN, o);
}
示例#3
0
/* Send a preimage for the old commit tx.  The one we've just committed to is
 * in peer->local.commit. */
void queue_pkt_revocation(struct peer *peer)
{
	UpdateRevocation *u = tal(peer, UpdateRevocation);
	struct commit_info *ci;

	update_revocation__init(u);

	assert(peer->local.commit);
	ci = peer->local.commit->prev;
	assert(ci);
	assert(!ci->revocation_preimage);

	/* We have their signature on the current one, right? */
	assert(peer->local.commit->sig);

	ci->revocation_preimage = tal(ci, struct sha256);
	peer_get_revocation_preimage(peer, ci->commit_num,
				     ci->revocation_preimage);

	u->revocation_preimage = sha256_to_proto(u, ci->revocation_preimage);

	u->next_revocation_hash = sha256_to_proto(u,
						  &peer->local.next_revocation_hash);

	queue_pkt(peer, PKT__PKT_UPDATE_REVOCATION, u);

	/* BOLT #2:
	 *
	 * The node sending `update_revocation` MUST add the local unacked
	 * changes to the set of remote acked changes.
	 */
	/* Note: this means the unacked changes as of the commit we're
	 * revoking */
	add_acked_changes(&peer->remote.commit->acked_changes, ci->unacked_changes);
	apply_changeset(peer, &peer->remote, THEIRS,
			ci->unacked_changes, tal_count(ci->unacked_changes));

	if (tal_count(ci->unacked_changes))
		remote_changes_pending(peer);

	/* We should never look at this again. */
	ci->unacked_changes = tal_free(ci->unacked_changes);

	/* That revocation has committed us to changes in the current commitment.
	 * Any acked changes come from their commitment, so those are now committed
	 * by both of us.
	 */
	peer_both_committed_to(peer, ci->acked_changes, OURS);
}
示例#4
0
void queue_pkt_htlc_add(struct peer *peer, struct htlc *htlc)
{
	UpdateAddHtlc *u = tal(peer, UpdateAddHtlc);
	union htlc_staging stage;

	update_add_htlc__init(u);

	u->id = htlc->id;
	u->amount_msat = htlc->msatoshis;
	u->r_hash = sha256_to_proto(u, &htlc->rhash);
	u->expiry = abs_locktime_to_proto(u, &htlc->expiry);
	u->route = tal(u, Routing);
	routing__init(u->route);
	u->route->info.data = tal_dup_arr(u, u8,
					  htlc->routing,
					  tal_count(htlc->routing),
					  0);
	u->route->info.len = tal_count(u->route->info.data);

	/* BOLT #2:
	 *
	 * The sending node MUST add the HTLC addition to the unacked
	 * changeset for its remote commitment
	 */
	if (!cstate_add_htlc(peer->remote.staging_cstate, htlc, OURS))
		fatal("Could not add HTLC?");

	stage.add.add = HTLC_ADD;
	stage.add.htlc = htlc;
	add_unacked(&peer->remote, &stage);

	remote_changes_pending(peer);

	queue_pkt(peer, PKT__PKT_UPDATE_ADD_HTLC, u);
}
示例#5
0
void queue_pkt_htlc_add(struct peer *peer,
		  const struct htlc_progress *htlc_prog)
{
	UpdateAddHtlc *u = tal(peer, UpdateAddHtlc);

	update_add_htlc__init(u);
	assert(htlc_prog->stage.type == HTLC_ADD);

	u->id = htlc_prog->stage.add.htlc.id;
	u->amount_msat = htlc_prog->stage.add.htlc.msatoshis;
	u->r_hash = sha256_to_proto(u, &htlc_prog->stage.add.htlc.rhash);
	u->expiry = abs_locktime_to_proto(u, &htlc_prog->stage.add.htlc.expiry);
	/* FIXME: routing! */
	u->route = tal(u, Routing);
	routing__init(u->route);

	/* We're about to send this, so their side will have it from now on. */
	if (!funding_b_add_htlc(peer->them.staging_cstate,
				htlc_prog->stage.add.htlc.msatoshis,
				&htlc_prog->stage.add.htlc.expiry,
				&htlc_prog->stage.add.htlc.rhash,
				htlc_prog->stage.add.htlc.id))
		fatal("Could not add HTLC?");

	peer_add_htlc_expiry(peer, &htlc_prog->stage.add.htlc.expiry);
	
	queue_pkt_with_ack(peer, PKT__PKT_UPDATE_ADD_HTLC, u,
			   add_our_htlc_ourside,
			   tal_dup(peer, struct channel_htlc,
				   &htlc_prog->stage.add.htlc));
}
示例#6
0
void queue_pkt_anchor(struct peer *peer)
{
	OpenAnchor *a = tal(peer, OpenAnchor);

	open_anchor__init(a);
	a->txid = sha256_to_proto(a, &peer->anchor.txid.sha);
	a->output_index = peer->anchor.index;
	a->amount = peer->anchor.satoshis;

	/* This shouldn't happen! */
	if (!setup_first_commit(peer)) {
		queue_pkt_err(peer,
			      pkt_err(peer,
				      "Own anchor has insufficient funds"));
		return;
	}

	/* Sign their commit sig */
	peer->them.commit->sig = tal(peer->them.commit,
				     struct bitcoin_signature);
	peer->them.commit->sig->stype = SIGHASH_ALL;
	peer_sign_theircommit(peer, peer->them.commit->tx,
			      &peer->them.commit->sig->sig);
	a->commit_sig = signature_to_proto(a, &peer->them.commit->sig->sig);

	queue_pkt(peer, PKT__PKT_OPEN_ANCHOR, a);
}
示例#7
0
void queue_pkt_anchor(struct peer *peer)
{
	OpenAnchor *a = tal(peer, OpenAnchor);

	open_anchor__init(a);
	a->txid = sha256_to_proto(a, &peer->anchor.txid.sha);
	a->output_index = peer->anchor.index;
	a->amount = peer->anchor.satoshis;

	/* This shouldn't happen! */
	if (!setup_first_commit(peer)) {
		queue_pkt_err(peer,
			      pkt_err(peer,
				      "Own anchor has insufficient funds"));
		return;
	}

	queue_pkt(peer, PKT__PKT_OPEN_ANCHOR, a);
}
示例#8
0
void queue_pkt_htlc_fulfill(struct peer *peer,
		      const struct htlc_progress *htlc_prog)
{
	UpdateFulfillHtlc *f = tal(peer, UpdateFulfillHtlc);
	size_t n;

	update_fulfill_htlc__init(f);
	assert(htlc_prog->stage.type == HTLC_FULFILL);

	f->id = htlc_prog->stage.fulfill.id;
	f->r = sha256_to_proto(f, &htlc_prog->stage.fulfill.r);

	/* We're about to send this, so their side will have it from now on. */
	n = funding_htlc_by_id(&peer->them.staging_cstate->a, f->id);
	funding_a_fulfill_htlc(peer->them.staging_cstate, n);

	queue_pkt_with_ack(peer, PKT__PKT_UPDATE_FULFILL_HTLC, f,
			   fulfill_their_htlc_ourside, int2ptr(f->id));
}
示例#9
0
	return ret;
}

struct pkt *open_channel_pkt(const tal_t *ctx,
			     const struct sha256 *revocation_hash,
			     const struct pubkey *commit,
			     const struct pubkey *final,
			     u32 rel_locktime_seconds,
			     OpenChannel__AnchorOffer offer_anchor,
			     u32 min_depth,
			     u64 commitment_fee)
{
	OpenChannel o = OPEN_CHANNEL__INIT;
	Locktime lt = LOCKTIME__INIT;

	o.revocation_hash = sha256_to_proto(ctx, revocation_hash);
	o.commit_key = pubkey_to_proto(ctx, commit);
	o.final_key = pubkey_to_proto(ctx, final);
	lt.locktime_case = LOCKTIME__LOCKTIME_SECONDS;
	lt.seconds = rel_locktime_seconds;
	o.delay = <
	o.commitment_fee = commitment_fee;
	o.anch = offer_anchor;
	assert(o.anch == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR
	       || o.anch == OPEN_CHANNEL__ANCHOR_OFFER__WONT_CREATE_ANCHOR);

	o.min_depth = min_depth;

	{
		size_t len = open_channel__get_packed_size(&o);
		unsigned char *pb = malloc(len);
示例#10
0
/* Takes complete update history, gets summary of last state. */
struct channel_state *gather_updates(const tal_t *ctx,
                                     const OpenChannel *o1, const OpenChannel *o2,
                                     const OpenAnchor *oa, uint64_t fee,
                                     char **argv,
                                     size_t *num_updates,
                                     struct sha256 *our_rhash,
                                     struct sha256 *their_rhash,
                                     struct signature *their_commit_sig)
{
    Signature *sig = NULL;
    struct sha256 old_our_rhash, old_their_rhash, rhash1, rhash2;
    struct channel_state *cstate;

    /* Start sanity check. */
    cstate = initial_funding(NULL, o1, o2, oa, fee);
    if (!cstate)
        errx(1, "Invalid open combination (need 1 anchor offer)");

    /* If they don't want these, use dummy ones. */
    if (!our_rhash)
        our_rhash = &rhash1;

    if (!their_rhash)
        their_rhash = &rhash2;

    proto_to_sha256(o1->revocation_hash, our_rhash);
    proto_to_sha256(o2->revocation_hash, their_rhash);

    assert(tal_count(cstate->a.htlcs) == 0);
    assert(tal_count(cstate->b.htlcs) == 0);

    /* If o2 sent anchor, it contains their commit sig. */
    if (o2->anch == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR)
        sig = oa->commit_sig;

    if (num_updates)
        *num_updates = 0;
    while (*argv) {
        int64_t delta, amount;
        size_t n;
        bool received;
        Pkt *pkt;

        /* + marks messages sent by us, - for messages from them */
        if (strstarts(*argv, "+")) {
            received = false;
        } else if (strstarts(*argv, "-")) {
            received = true;
        } else
            errx(1, "%s does not start with +/-", *argv);

        pkt = any_pkt_from_file(*argv + 1);
        switch (pkt->pkt_case) {
        case PKT__PKT_OPEN_COMMIT_SIG:
            if (received)
                sig = pkt->open_commit_sig->sig;
            break;
        case PKT__PKT_UPDATE_ADD_HTLC:
            amount = pkt->update_add_htlc->amount_msat;
            if (received) {
                if (!funding_delta(o2, o1, oa, 0, amount,
                                   &cstate->b, &cstate->a))
                    errx(1, "Impossible htlc %llu %s",
                         (long long)amount, *argv);
                add_htlc(&cstate->b, pkt->update_add_htlc,
                         *argv);
            } else {
                if (!funding_delta(o1, o2, oa, 0, amount,
                                   &cstate->a, &cstate->b))
                    errx(1, "Impossible htlc %llu %s",
                         (long long)amount, *argv);
                add_htlc(&cstate->a, pkt->update_add_htlc,
                         *argv);
            }

            update_rhash(pkt->update_add_htlc->revocation_hash,
                         received, num_updates,
                         &old_our_rhash, &old_their_rhash,
                         our_rhash, their_rhash);
            break;

        case PKT__PKT_UPDATE_TIMEDOUT_HTLC:
            if (received) {
                n = find_htlc(&cstate->b,
                              pkt->update_timedout_htlc->r_hash);
                if (n == tal_count(cstate->b.htlcs))
                    errx(1, "Unknown R hash in %s", *argv);
                amount = cstate->b.htlcs[n]->amount_msat;
                if (!funding_delta(o2, o1, oa, 0, -amount,
                                   &cstate->b, &cstate->a))
                    errx(1, "Impossible htlc %llu %s",
                         (long long)amount, *argv);
                remove_htlc(&cstate->b, n);
            } else {
                n = find_htlc(&cstate->a,
                              pkt->update_timedout_htlc->r_hash);
                if (n == tal_count(cstate->a.htlcs))
                    errx(1, "Unknown R hash in %s", *argv);
                amount = cstate->a.htlcs[n]->amount_msat;
                if (!funding_delta(o1, o2, oa, 0, -amount,
                                   &cstate->a, &cstate->b))
                    errx(1, "Impossible htlc %llu %s",
                         (long long)amount, *argv);
                remove_htlc(&cstate->a, n);
            }
            update_rhash(pkt->update_timedout_htlc->revocation_hash,
                         received, num_updates,
                         &old_our_rhash, &old_their_rhash,
                         our_rhash, their_rhash);
            break;

        /* HTLC acceptor sends this to initiator. */
        case PKT__PKT_UPDATE_ROUTEFAIL_HTLC:
            if (received) {
                n = find_htlc(&cstate->a,
                              pkt->update_routefail_htlc->r_hash);
                if (n == tal_count(cstate->a.htlcs))
                    errx(1, "Unknown R hash in %s", *argv);
                amount = cstate->a.htlcs[n]->amount_msat;
                if (!funding_delta(o1, o2, oa, 0, -amount,
                                   &cstate->a, &cstate->b))
                    errx(1, "Impossible htlc %llu %s",
                         (long long)amount, *argv);
                remove_htlc(&cstate->a, n);
            } else {
                n = find_htlc(&cstate->b,
                              pkt->update_routefail_htlc->r_hash);
                if (n == tal_count(cstate->b.htlcs))
                    errx(1, "Unknown R hash in %s", *argv);
                amount = cstate->b.htlcs[n]->amount_msat;
                if (!funding_delta(o2, o1, oa, 0, -amount,
                                   &cstate->b, &cstate->a))
                    errx(1, "Impossible htlc %llu %s",
                         (long long)amount, *argv);
                remove_htlc(&cstate->b, n);
            }
            update_rhash(pkt->update_routefail_htlc->revocation_hash,
                         received, num_updates,
                         &old_our_rhash, &old_their_rhash,
                         our_rhash, their_rhash);
            break;

        case PKT__PKT_UPDATE_FULFILL_HTLC: {
            struct sha256 r_hash, r_val;
            Sha256Hash *rh;

            /* Get hash, to find the HTLC. */
            proto_to_sha256(pkt->update_fulfill_htlc->r, &r_val);
            sha256(&r_hash, &r_val, sizeof(r_val));
            rh = sha256_to_proto(ctx, &r_hash);

            if (received) {
                /* HTLC was us->them, funds go to them. */
                n = find_htlc(&cstate->a, rh);
                if (n == tal_count(cstate->a.htlcs))
                    errx(1, "Unknown R hash in %s", *argv);
                amount = cstate->a.htlcs[n]->amount_msat;
                if (!funding_delta(o1, o2, oa, amount, -amount,
                                   &cstate->a, &cstate->b))
                    errx(1, "Impossible htlc %llu %s",
                         (long long)amount, *argv);
                remove_htlc(&cstate->a, n);
            } else {
                /* HTLC was them->us, funds go to us. */
                n = find_htlc(&cstate->b, rh);
                if (n == tal_count(cstate->b.htlcs))
                    errx(1, "Unknown R hash in %s", *argv);
                amount = cstate->b.htlcs[n]->amount_msat;
                if (!funding_delta(o2, o1, oa, amount, -amount,
                                   &cstate->b, &cstate->a))
                    errx(1, "Impossible htlc %llu %s",
                         (long long)amount, *argv);
                remove_htlc(&cstate->b, n);
            }
            update_rhash(pkt->update_fulfill_htlc->revocation_hash,
                         received, num_updates,
                         &old_our_rhash, &old_their_rhash,
                         our_rhash, their_rhash);
            break;
        }

        case PKT__PKT_UPDATE:
            if (received)
                delta = -pkt->update->delta_msat;
            else
                delta = pkt->update->delta_msat;
            if (!funding_delta(o1, o2, oa, delta, 0,
                               &cstate->a, &cstate->b))
                errx(1, "Impossible funding update %lli %s",
                     (long long)delta, *argv);

            update_rhash(pkt->update->revocation_hash,
                         received, num_updates,
                         &old_our_rhash, &old_their_rhash,
                         our_rhash, their_rhash);
            break;
        case PKT__PKT_UPDATE_ACCEPT:
            if (received)
                sig = pkt->update_accept->sig;

            /* Does not increase num_updates */
            update_rhash(pkt->update_accept->revocation_hash,
                         received, NULL,
                         &old_our_rhash, &old_their_rhash,
                         our_rhash, their_rhash);
            break;
        case PKT__PKT_UPDATE_SIGNATURE:
            if (received) {
                sig = pkt->update_signature->sig;
                check_preimage(pkt->update_signature
                               ->revocation_preimage,
                               &old_their_rhash, their_rhash,
                               *argv);
            } else {
                check_preimage(pkt->update_signature
                               ->revocation_preimage,
                               &old_our_rhash, our_rhash,
                               *argv);
            }
            break;
        case PKT__PKT_UPDATE_COMPLETE:
            if (received) {
                check_preimage(pkt->update_complete
                               ->revocation_preimage,
                               &old_their_rhash, their_rhash,
                               *argv);
            } else {
                check_preimage(pkt->update_complete
                               ->revocation_preimage,
                               &old_our_rhash, our_rhash,
                               *argv);
            }
            break;
        default:
            errx(1, "Unexpected packet type %u", pkt->pkt_case);
        }
        argv++;
    }

    if (their_commit_sig) {
        if (!sig)
            errx(1, "No commit signature message found");
        if (!proto_to_signature(sig, their_commit_sig))
            errx(1, "Invalid signature");
    }

    return cstate;
}