示例#1
0
/* Process various packets: return an error packet on failure. */
Pkt *accept_pkt_open(struct peer *peer, const Pkt *pkt)
{
	struct rel_locktime locktime;
	const OpenChannel *o = pkt->open;

	if (!proto_to_rel_locktime(o->delay, &locktime))
		return pkt_err(peer, "Invalid delay");
	if (o->delay->locktime_case != LOCKTIME__LOCKTIME_BLOCKS)
		return pkt_err(peer, "Delay in seconds not accepted");
	if (o->delay->blocks > peer->dstate->config.locktime_max)
		return pkt_err(peer, "Delay too great");
	if (o->min_depth > peer->dstate->config.anchor_confirms_max)
		return pkt_err(peer, "min_depth too great");
	if (o->initial_fee_rate < peer->dstate->config.commitment_fee_rate_min)
		return pkt_err(peer, "Commitment fee rate too low");
	if (o->anch == OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR)
		peer->remote.offer_anchor = CMD_OPEN_WITH_ANCHOR;
	else if (o->anch == OPEN_CHANNEL__ANCHOR_OFFER__WONT_CREATE_ANCHOR)
		peer->remote.offer_anchor = CMD_OPEN_WITHOUT_ANCHOR;
	else
		return pkt_err(peer, "Unknown offer anchor value");

	if (peer->remote.offer_anchor == peer->local.offer_anchor)
		return pkt_err(peer, "Only one side can offer anchor");

	if (!proto_to_rel_locktime(o->delay, &peer->remote.locktime))
		return pkt_err(peer, "Malformed locktime");
	peer->remote.mindepth = o->min_depth;
	peer->remote.commit_fee_rate = o->initial_fee_rate;
	if (!proto_to_pubkey(peer->dstate->secpctx,
			     o->commit_key, &peer->remote.commitkey))
		return pkt_err(peer, "Bad commitkey");
	if (!proto_to_pubkey(peer->dstate->secpctx,
			     o->final_key, &peer->remote.finalkey))
		return pkt_err(peer, "Bad finalkey");

	/* Set up their commit info now: rest gets done in setup_first_commit
	 * once anchor is established. */
	peer->remote.commit = new_commit_info(peer);
	proto_to_sha256(o->revocation_hash, &peer->remote.commit->revocation_hash);
	proto_to_sha256(o->next_revocation_hash,
			&peer->remote.next_revocation_hash);

	/* Witness script for anchor. */
	peer->anchor.witnessscript
		= bitcoin_redeem_2of2(peer, peer->dstate->secpctx,
				      &peer->local.commitkey,
				      &peer->remote.commitkey);
	return NULL;
}
示例#2
0
Pkt *accept_pkt_revocation(struct peer *peer, const Pkt *pkt)
{
	const UpdateRevocation *r = pkt->update_revocation;
	struct commit_info *ci = peer->remote.commit->prev;

	/* BOLT #2:
	 *
	 * The receiver of `update_revocation` MUST check that the
	 * SHA256 hash of `revocation_preimage` matches the previous commitment
	 * transaction, and MUST fail if it does not.
	 */
	if (!check_preimage(r->revocation_preimage, &ci->revocation_hash))
		return pkt_err(peer, "complete preimage incorrect");

	/* They're revoking the previous one. */
	assert(!ci->revocation_preimage);
	ci->revocation_preimage = tal(ci, struct sha256);

	proto_to_sha256(r->revocation_preimage, ci->revocation_preimage);

	// save revocation preimages in shachain
	if (!shachain_add_hash(&peer->their_preimages, 0xFFFFFFFFFFFFFFFFL - ci->commit_num, ci->revocation_preimage))
		return pkt_err(peer, "preimage not next in shachain");

	/* Save next revocation hash. */
	proto_to_sha256(r->next_revocation_hash,
			&peer->remote.next_revocation_hash);

	/* BOLT #2:
	 *
	 * The receiver of `update_revocation`... MUST add the remote
	 * unacked changes to the set of local acked changes.
	 */
	add_acked_changes(&peer->local.commit->acked_changes, ci->unacked_changes);
	apply_changeset(peer, &peer->local, OURS,
			ci->unacked_changes,
			tal_count(ci->unacked_changes));

	/* Should never examine these again. */
	ci->unacked_changes = tal_free(ci->unacked_changes);

	/* That revocation has committed them to changes in the current commitment.
	 * Any acked changes come from our commitment, so those are now committed
	 * by both of us.
	 */
	peer_both_committed_to(peer, ci->acked_changes, THEIRS);
	
	return NULL;
}
示例#3
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;
}
示例#4
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);
}
示例#5
0
static void update_rhash(const Sha256Hash *rhash,
                         bool received,
                         size_t *num_updates,
                         struct sha256 *old_our_rhash,
                         struct sha256 *old_their_rhash,
                         struct sha256 *our_rhash,
                         struct sha256 *their_rhash)
{
    /* Update rhash (and save old one for checking) */
    if (received) {
        *old_their_rhash = *their_rhash;
        proto_to_sha256(rhash, their_rhash);
    } else {
        *old_our_rhash = *our_rhash;
        proto_to_sha256(rhash, our_rhash);
    }
    /* If they care, we count number of updates. */
    if (num_updates)
        (*num_updates)++;
}
示例#6
0
Pkt *accept_pkt_revocation(struct peer *peer, const Pkt *pkt)
{
	const UpdateRevocation *r = pkt->update_revocation;

	/* FIXME: Save preimage in shachain too. */
	if (!check_preimage(r->revocation_preimage,
			    &peer->them.commit->prev->revocation_hash))
		return pkt_err(peer, "complete preimage incorrect");

	/* They're revoking the previous one. */
	assert(!peer->them.commit->prev->revocation_preimage);
	peer->them.commit->prev->revocation_preimage
		= tal(peer->them.commit->prev, struct sha256);

	proto_to_sha256(r->revocation_preimage,
			peer->them.commit->prev->revocation_preimage);

	/* Save next revocation hash. */
	proto_to_sha256(r->next_revocation_hash,
			&peer->them.next_revocation_hash);

	return NULL;
}
示例#7
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);
}
示例#8
0
Pkt *accept_pkt_anchor(struct peer *peer, const Pkt *pkt)
{
	const OpenAnchor *a = pkt->open_anchor;

	/* They must be offering anchor for us to try accepting */
	assert(peer->local.offer_anchor == CMD_OPEN_WITHOUT_ANCHOR);
	assert(peer->remote.offer_anchor == CMD_OPEN_WITH_ANCHOR);

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

	if (!setup_first_commit(peer))
		return pkt_err(peer, "Insufficient funds for fee");

	return NULL;
}
int main(int argc, char *argv[])
{
	const tal_t *ctx = tal_arr(NULL, char, 0);
	struct sha256 seed, revocation_hash, their_rhash;
	OpenChannel *o1, *o2;
	Update *update;
	struct bitcoin_tx *anchor, *commit;
	struct sha256_double anchor_txid;
	struct pkt *pkt;
	struct bitcoin_signature sig;
	EC_KEY *privkey;
	bool testnet;
	struct pubkey pubkey1, pubkey2;
	u8 *redeemscript;
	int64_t delta;
	size_t i, p2sh_out;

	err_set_progname(argv[0]);

	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<seed> <anchor-tx> <open-channel-file1> <open-channel-file2> <commit-privkey> <update-protobuf> [previous-updates]\n"
			   "Accept a new update message",
			   "Print this message.");

 	opt_parse(&argc, argv, opt_log_stderr_exit);

	if (argc < 6)
		opt_usage_exit_fail("Expected 5+ arguments");

	if (!hex_decode(argv[1], strlen(argv[1]), &seed, sizeof(seed)))
		errx(1, "Invalid seed '%s' - need 256 hex bits", argv[1]);
	
	anchor = bitcoin_tx_from_file(ctx, argv[2]);
	bitcoin_txid(anchor, &anchor_txid);
	o1 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open;
	o2 = pkt_from_file(argv[4], PKT__PKT_OPEN)->open;

	privkey = key_from_base58(argv[5], strlen(argv[5]), &testnet, &pubkey1);
	if (!privkey)
		errx(1, "Invalid private key '%s'", argv[5]);
	if (!testnet)
		errx(1, "Private key '%s' not on testnet!", argv[5]);

	update = pkt_from_file(argv[6], PKT__PKT_UPDATE)->update;
	
	/* Figure out cumulative delta since anchor. */
	delta = update->delta;
	for (i = 7; i < argc; i++) {
		Update *u = pkt_from_file(argv[i], PKT__PKT_UPDATE)->update;
		delta += u->delta;
	}

	/* Get next revocation hash. */
	shachain_from_seed(&seed, argc - 6, &revocation_hash);
	sha256(&revocation_hash,
	       revocation_hash.u.u8, sizeof(revocation_hash.u.u8));
	
	/* Get pubkeys */
	if (!proto_to_pubkey(o1->anchor->pubkey, &pubkey2))
		errx(1, "Invalid o1 commit pubkey");
	if (pubkey_len(&pubkey1) != pubkey_len(&pubkey2)
	    || memcmp(pubkey1.key, pubkey2.key, pubkey_len(&pubkey2)) != 0)
		errx(1, "o1 pubkey != this privkey");
	if (!proto_to_pubkey(o2->anchor->pubkey, &pubkey2))
		errx(1, "Invalid o2 final pubkey");

	/* This is what the anchor pays to; figure out whick output. */
	redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);
	p2sh_out = find_p2sh_out(anchor, redeemscript);

	/* Now create THEIR new commitment tx to spend 2/2 output of anchor. */
	proto_to_sha256(update->revocation_hash, &their_rhash);
	commit = create_commit_tx(ctx, o2, o1, &their_rhash, delta,
				  &anchor_txid, p2sh_out);

	/* If contributions don't exceed fees, this fails. */
	if (!commit)
		errx(1, "Delta too large");

	/* Sign it for them. */
	sign_tx_input(ctx, commit, 0, redeemscript, tal_count(redeemscript),
		      privkey, &pubkey1, &sig.sig);

	pkt = update_accept_pkt(ctx, &sig.sig, &revocation_hash);
	if (!write_all(STDOUT_FILENO, pkt, pkt_totlen(pkt)))
		err(1, "Writing out packet");

	tal_free(ctx);
	return 0;
}
示例#10
0
/*
 * We add changes to both our staging cstate (as they did when they sent
 * it) and theirs (as they will when we ack it).
 */
Pkt *accept_pkt_htlc_add(struct peer *peer, const Pkt *pkt)
{
	const UpdateAddHtlc *u = pkt->update_add_htlc;
	struct sha256 rhash;
	struct abs_locktime expiry;
	struct htlc *htlc;
	union htlc_staging stage;

	/* BOLT #2:
	 *
	 * `amount_msat` MUST BE greater than 0.
	 */
	if (u->amount_msat == 0)
		return pkt_err(peer, "Invalid amount_msat");

	proto_to_sha256(u->r_hash, &rhash);
	if (!proto_to_abs_locktime(u->expiry, &expiry))
		return pkt_err(peer, "Invalid HTLC expiry");

	if (abs_locktime_is_seconds(&expiry))
		return pkt_err(peer, "HTLC expiry in seconds not supported!");

	/* BOLT #2:
	 *
	 * A node MUST NOT add a HTLC if it would result in it
	 * offering more than 300 HTLCs in the remote commitment transaction.
	 */
	if (tal_count(peer->remote.staging_cstate->side[THEIRS].htlcs) == 300)
		return pkt_err(peer, "Too many HTLCs");

	/* BOLT #2:
	 *
	 * A node MUST set `id` to a unique identifier for this HTLC
	 * amongst all past or future `update_add_htlc` messages.
	 */
	/* Note that it's not *our* problem if they do this, it's
	 * theirs (future confusion).  Nonetheless, we detect and
	 * error for them. */
	if (htlc_map_get(&peer->remote.htlcs, u->id))
		return pkt_err(peer, "HTLC id %"PRIu64" clashes for you", u->id);

	/* BOLT #2:
	 *
	 * ...and the receiving node MUST add the HTLC addition to the
	 * unacked changeset for its local commitment. */
	htlc = peer_new_htlc(peer, u->id, u->amount_msat, &rhash,
			     abs_locktime_to_blocks(&expiry),
			     u->route->info.data, u->route->info.len,
			     NULL, THEIRS);

	/* BOLT #2:
	 *
	 * A node MUST NOT offer `amount_msat` it cannot pay for in
	 * the remote commitment transaction at the current `fee_rate` (see
	 * "Fee Calculation" ).  A node SHOULD fail the connection if
	 * this occurs.
	 */
	if (!cstate_add_htlc(peer->local.staging_cstate, htlc, THEIRS)) {
		tal_free(htlc);
		return pkt_err(peer, "Cannot afford %"PRIu64" milli-satoshis"
			       " in our commitment tx",
			       u->amount_msat);
	}

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

	return NULL;
}
示例#11
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;
}
示例#12
0
/*
 * We add changes to both our staging cstate (as they did when they sent
 * it) and theirs (as they will when we ack it).
 */
Pkt *accept_pkt_htlc_add(struct peer *peer, const Pkt *pkt)
{
	const UpdateAddHtlc *u = pkt->update_add_htlc;
	struct sha256 rhash;
	struct abs_locktime expiry;

	/* BOLT #2:
	 *
	 * `amount_msat` MUST BE greater than 0.
	 */
	if (u->amount_msat == 0)
		return pkt_err(peer, "Invalid amount_msat");

	proto_to_sha256(u->r_hash, &rhash);
	if (!proto_to_abs_locktime(u->expiry, &expiry))
		return pkt_err(peer, "Invalid HTLC expiry");

	/* FIXME: Handle block-based expiry! */
	if (!abs_locktime_is_seconds(&expiry))
		return pkt_err(peer, "HTLC expiry in blocks not supported!");

	/* BOLT #2:
	 *
	 * A node MUST NOT add a HTLC if it would result in it
	 * offering more than 1500 HTLCs in either commitment transaction.
	 */
	if (tal_count(peer->them.staging_cstate->a.htlcs) == 1500
	    || tal_count(peer->us.staging_cstate->b.htlcs) == 1500)
		return pkt_err(peer, "Too many HTLCs");

	/* BOLT #2:
	 *
	 * A node MUST NOT set `id` equal to another HTLC which is in
	 * the current staged commitment transaction.
	 */
	if (funding_htlc_by_id(&peer->them.staging_cstate->a, u->id)
	    < tal_count(peer->them.staging_cstate->a.htlcs))
		return pkt_err(peer, "HTLC id %"PRIu64" clashes for you", u->id);

	/* FIXME: Assert this... */
	/* Note: these should be in sync, so this should be redundant! */
	if (funding_htlc_by_id(&peer->us.staging_cstate->b, u->id)
	    < tal_count(peer->us.staging_cstate->b.htlcs))
		return pkt_err(peer, "HTLC id %"PRIu64" clashes for us", u->id);

	/* BOLT #2:
	 *
	 * A node MUST NOT offer `amount_msat` it cannot pay for in
	 * both commitment transactions at the current `fee_rate` (see
	 * "Fee Calculation" ).  A node SHOULD fail the connection if
	 * this occurs.
	 */

	/* FIXME: This is wrong!  We may have already added more txs to
	 * them.staging_cstate, driving that fee up.
	 * We should check against the last version they acknowledged. */
	if (!funding_a_add_htlc(peer->them.staging_cstate,
				u->amount_msat, &expiry, &rhash, u->id))
		return pkt_err(peer, "Cannot afford %"PRIu64" milli-satoshis"
			       " in your commitment tx",
			       u->amount_msat);

	/* If we fail here, we've already changed them.staging_cstate, so
	 * MUST terminate. */
	if (!funding_b_add_htlc(peer->us.staging_cstate,
				u->amount_msat, &expiry, &rhash, u->id))
		return pkt_err(peer, "Cannot afford %"PRIu64" milli-satoshis"
			       " in our commitment tx",
			       u->amount_msat);

	peer_add_htlc_expiry(peer, &expiry);

	/* FIXME: Fees must be sufficient. */
	return NULL;
}