Browse Source

funding: use sides[OURS/THEIRS] instead of a and b.

This is a little clearer, and handling arrays is easier than separate
variables.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 9 years ago
parent
commit
cf7a7a7273
  1. 16
      commit_tx.c
  2. 86
      daemon/packets.c
  3. 107
      daemon/peer.c
  4. 167
      funding.c
  5. 89
      funding.h

16
commit_tx.c

@ -52,8 +52,8 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
uint64_t total;
/* Now create commitment tx: one input, two outputs (plus htlcs) */
tx = bitcoin_tx(ctx, 1, 2 + tal_count(cstate->a.htlcs)
+ tal_count(cstate->b.htlcs));
tx = bitcoin_tx(ctx, 1, 2 + tal_count(cstate->side[OURS].htlcs)
+ tal_count(cstate->side[THEIRS].htlcs));
/* Our input spends the anchor tx output. */
tx->input[0].txid = *anchor_txid;
@ -67,28 +67,28 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
rhash);
tx->output[0].script = scriptpubkey_p2wsh(tx, redeemscript);
tx->output[0].script_length = tal_count(tx->output[0].script);
tx->output[0].amount = cstate->a.pay_msat / 1000;
tx->output[0].amount = cstate->side[OURS].pay_msat / 1000;
/* Second output is a P2WPKH payment to them. */
tx->output[1].script = scriptpubkey_p2wpkh(tx, their_final);
tx->output[1].script_length = tal_count(tx->output[1].script);
tx->output[1].amount = cstate->b.pay_msat / 1000;
tx->output[1].amount = cstate->side[THEIRS].pay_msat / 1000;
/* First two outputs done, now for the HTLCs. */
total = tx->output[0].amount + tx->output[1].amount;
num = 2;
/* HTLCs we've sent. */
for (i = 0; i < tal_count(cstate->a.htlcs); i++) {
if (!add_htlc(tx, num, &cstate->a.htlcs[i],
for (i = 0; i < tal_count(cstate->side[OURS].htlcs); i++) {
if (!add_htlc(tx, num, &cstate->side[OURS].htlcs[i],
our_final, their_final,
rhash, their_locktime, bitcoin_redeem_htlc_send))
return tal_free(tx);
total += tx->output[num++].amount;
}
/* HTLCs we've received. */
for (i = 0; i < tal_count(cstate->b.htlcs); i++) {
if (!add_htlc(tx, num, &cstate->b.htlcs[i],
for (i = 0; i < tal_count(cstate->side[THEIRS].htlcs); i++) {
if (!add_htlc(tx, num, &cstate->side[THEIRS].htlcs[i],
our_final, their_final,
rhash, their_locktime, bitcoin_redeem_htlc_recv))
return tal_free(tx);

86
daemon/packets.c

@ -184,9 +184,9 @@ static void add_our_htlc_ourside(struct peer *peer, void *arg)
struct channel_htlc *htlc = arg;
/* FIXME: must add even if can't pay fee any more! */
if (!funding_a_add_htlc(peer->local.staging_cstate,
htlc->msatoshis, &htlc->expiry,
&htlc->rhash, htlc->id))
if (!funding_add_htlc(peer->local.staging_cstate,
htlc->msatoshis, &htlc->expiry,
&htlc->rhash, htlc->id, OURS))
fatal("FIXME: Failed to add htlc %"PRIu64" to self on ack",
htlc->id);
tal_free(htlc);
@ -209,11 +209,11 @@ void queue_pkt_htlc_add(struct peer *peer,
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->remote.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))
if (!funding_add_htlc(peer->remote.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, THEIRS))
fatal("Could not add HTLC?");
peer_add_htlc_expiry(peer, &htlc_prog->stage.add.htlc.expiry);
@ -230,8 +230,9 @@ static void fulfill_their_htlc_ourside(struct peer *peer, void *arg)
{
size_t n;
n = funding_htlc_by_id(&peer->local.staging_cstate->b, ptr2int(arg));
funding_b_fulfill_htlc(peer->local.staging_cstate, n);
n = funding_htlc_by_id(peer->local.staging_cstate, ptr2int(arg), THEIRS);
assert(n != -1);
funding_fulfill_htlc(peer->local.staging_cstate, n, THEIRS);
}
void queue_pkt_htlc_fulfill(struct peer *peer,
@ -247,8 +248,9 @@ void queue_pkt_htlc_fulfill(struct peer *peer,
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->remote.staging_cstate->a, f->id);
funding_a_fulfill_htlc(peer->remote.staging_cstate, n);
n = funding_htlc_by_id(peer->remote.staging_cstate, f->id, OURS);
assert(n != -1);
funding_fulfill_htlc(peer->remote.staging_cstate, n, OURS);
their_commit_changed(peer);
queue_pkt_with_ack(peer, PKT__PKT_UPDATE_FULFILL_HTLC, f,
@ -260,8 +262,9 @@ static void fail_their_htlc_ourside(struct peer *peer, void *arg)
{
size_t n;
n = funding_htlc_by_id(&peer->local.staging_cstate->b, ptr2int(arg));
funding_b_fail_htlc(peer->local.staging_cstate, n);
n = funding_htlc_by_id(peer->local.staging_cstate, ptr2int(arg), THEIRS);
assert(n != -1);
funding_fail_htlc(peer->local.staging_cstate, n, THEIRS);
}
void queue_pkt_htlc_fail(struct peer *peer,
@ -279,8 +282,9 @@ void queue_pkt_htlc_fail(struct peer *peer,
fail_reason__init(f->reason);
/* We're about to send this, so their side will have it from now on. */
n = funding_htlc_by_id(&peer->remote.staging_cstate->a, f->id);
funding_a_fail_htlc(peer->remote.staging_cstate, n);
n = funding_htlc_by_id(peer->remote.staging_cstate, f->id, OURS);
assert(n != -1);
funding_fail_htlc(peer->remote.staging_cstate, n, OURS);
their_commit_changed(peer);
queue_pkt_with_ack(peer, PKT__PKT_UPDATE_FAIL_HTLC, f,
@ -309,10 +313,10 @@ void queue_pkt_commit(struct peer *peer)
&ci->map);
log_debug(peer->log, "Signing tx for %u/%u msatoshis, %zu/%zu htlcs",
ci->cstate->a.pay_msat,
ci->cstate->b.pay_msat,
tal_count(ci->cstate->a.htlcs),
tal_count(ci->cstate->b.htlcs));
ci->cstate->side[OURS].pay_msat,
ci->cstate->side[THEIRS].pay_msat,
tal_count(ci->cstate->side[OURS].htlcs),
tal_count(ci->cstate->side[THEIRS].htlcs));
/* BOLT #2:
*
@ -563,8 +567,8 @@ Pkt *accept_pkt_htlc_add(struct peer *peer, const Pkt *pkt)
* A node MUST NOT add a HTLC if it would result in it
* offering more than 300 HTLCs in either commitment transaction.
*/
if (tal_count(peer->remote.staging_cstate->a.htlcs) == 300
|| tal_count(peer->local.staging_cstate->b.htlcs) == 300)
if (tal_count(peer->remote.staging_cstate->side[OURS].htlcs) == 300
|| tal_count(peer->local.staging_cstate->side[THEIRS].htlcs) == 300)
return pkt_err(peer, "Too many HTLCs");
/* BOLT #2:
@ -572,14 +576,12 @@ Pkt *accept_pkt_htlc_add(struct peer *peer, const Pkt *pkt)
* A node MUST NOT set `id` equal to another HTLC which is in
* the current staged commitment transaction.
*/
if (funding_htlc_by_id(&peer->remote.staging_cstate->a, u->id)
< tal_count(peer->remote.staging_cstate->a.htlcs))
if (funding_htlc_by_id(peer->remote.staging_cstate, u->id, OURS) != -1)
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->local.staging_cstate->b, u->id)
< tal_count(peer->local.staging_cstate->b.htlcs))
if (funding_htlc_by_id(peer->local.staging_cstate, u->id, THEIRS) != -1)
return pkt_err(peer, "HTLC id %"PRIu64" clashes for us", u->id);
/* BOLT #2:
@ -593,16 +595,16 @@ Pkt *accept_pkt_htlc_add(struct peer *peer, const Pkt *pkt)
/* 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->remote.staging_cstate,
u->amount_msat, &expiry, &rhash, u->id))
if (!funding_add_htlc(peer->remote.staging_cstate,
u->amount_msat, &expiry, &rhash, u->id, OURS))
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->local.staging_cstate,
u->amount_msat, &expiry, &rhash, u->id))
if (!funding_add_htlc(peer->local.staging_cstate,
u->amount_msat, &expiry, &rhash, u->id, THEIRS))
return pkt_err(peer, "Cannot afford %"PRIu64" milli-satoshis"
" in our commitment tx",
u->amount_msat);
@ -623,19 +625,19 @@ static Pkt *find_commited_htlc(struct peer *peer, uint64_t id,
* current commitment transaction, and MUST fail the
* connection if it does not.
*/
*n_us = funding_htlc_by_id(&peer->local.commit->cstate->a, id);
if (*n_us == tal_count(peer->local.commit->cstate->a.htlcs))
*n_us = funding_htlc_by_id(peer->local.commit->cstate, id, OURS);
if (*n_us == -1)
return pkt_err(peer, "Did not find HTLC %"PRIu64, id);
/* They must not fail/fulfill twice, so it should be in staging, too. */
*n_us = funding_htlc_by_id(&peer->local.staging_cstate->a, id);
if (*n_us == tal_count(peer->local.staging_cstate->a.htlcs))
*n_us = funding_htlc_by_id(peer->local.staging_cstate, id, OURS);
if (*n_us == -1)
return pkt_err(peer, "Already removed HTLC %"PRIu64, id);
/* FIXME: Assert this... */
/* Note: these should match. */
*n_them = funding_htlc_by_id(&peer->remote.staging_cstate->b, id);
if (*n_them == tal_count(peer->remote.staging_cstate->b.htlcs))
*n_them = funding_htlc_by_id(peer->remote.staging_cstate, id, THEIRS);
if (*n_them == -1)
return pkt_err(peer, "Did not find your HTLC %"PRIu64, id);
return NULL;
@ -653,8 +655,8 @@ Pkt *accept_pkt_htlc_fail(struct peer *peer, const Pkt *pkt)
/* FIXME: Save reason. */
funding_a_fail_htlc(peer->local.staging_cstate, n_us);
funding_b_fail_htlc(peer->remote.staging_cstate, n_them);
funding_fail_htlc(peer->local.staging_cstate, n_us, OURS);
funding_fail_htlc(peer->remote.staging_cstate, n_them, THEIRS);
their_commit_changed(peer);
return NULL;
}
@ -674,14 +676,14 @@ Pkt *accept_pkt_htlc_fulfill(struct peer *peer, const Pkt *pkt)
proto_to_sha256(f->r, &r);
sha256(&rhash, &r, sizeof(r));
if (!structeq(&rhash, &peer->local.staging_cstate->a.htlcs[n_us].rhash))
if (!structeq(&rhash, &peer->local.staging_cstate->side[OURS].htlcs[n_us].rhash))
return pkt_err(peer, "Invalid r for %"PRIu64, f->id);
/* Same ID must have same rhash */
assert(structeq(&rhash, &peer->remote.staging_cstate->b.htlcs[n_them].rhash));
assert(structeq(&rhash, &peer->remote.staging_cstate->side[THEIRS].htlcs[n_them].rhash));
funding_a_fulfill_htlc(peer->local.staging_cstate, n_us);
funding_b_fulfill_htlc(peer->remote.staging_cstate, n_them);
funding_fulfill_htlc(peer->local.staging_cstate, n_us, OURS);
funding_fulfill_htlc(peer->remote.staging_cstate, n_them, THEIRS);
their_commit_changed(peer);
return NULL;
}

107
daemon/peer.c

@ -263,18 +263,18 @@ static bool committed_to_htlcs(const struct peer *peer)
i = peer->local.commit;
while (i && !i->revocation_preimage) {
if (tal_count(i->cstate->a.htlcs))
if (tal_count(i->cstate->side[OURS].htlcs))
return true;
if (tal_count(i->cstate->b.htlcs))
if (tal_count(i->cstate->side[THEIRS].htlcs))
return true;
i = i->prev;
}
i = peer->remote.commit;
while (i && !i->revocation_preimage) {
if (tal_count(i->cstate->a.htlcs))
if (tal_count(i->cstate->side[OURS].htlcs))
return true;
if (tal_count(i->cstate->b.htlcs))
if (tal_count(i->cstate->side[THEIRS].htlcs))
return true;
i = i->prev;
}
@ -820,20 +820,22 @@ static struct channel_htlc *htlc_by_index(const struct commit_info *ci,
assert(index >= 2);
index -= 2;
if (index < tal_count(ci->cstate->a.htlcs))
return cast_const(struct channel_htlc *, ci->cstate->a.htlcs)
if (index < tal_count(ci->cstate->side[OURS].htlcs))
return cast_const(struct channel_htlc *,
ci->cstate->side[OURS].htlcs)
+ index;
index -= tal_count(ci->cstate->a.htlcs);
assert(index < tal_count(ci->cstate->b.htlcs));
return cast_const(struct channel_htlc *, ci->cstate->b.htlcs) + index;
index -= tal_count(ci->cstate->side[OURS].htlcs);
assert(index < tal_count(ci->cstate->side[THEIRS].htlcs));
return cast_const(struct channel_htlc *, ci->cstate->side[THEIRS].htlcs)
+ index;
}
static bool htlc_a_offered(const struct commit_info *ci, size_t index)
static bool htlc_this_side_offered(const struct commit_info *ci, size_t index)
{
assert(index >= 2);
index -= 2;
return index < tal_count(ci->cstate->a.htlcs);
return index < tal_count(ci->cstate->side[OURS].htlcs);
}
/* Create a HTLC refund collection */
@ -1012,7 +1014,7 @@ static void resolve_cheating(struct peer *peer)
connect_input(ci, &steal_tx->input[n], ci->map[i]);
h = htlc_by_index(ci, i);
if (htlc_a_offered(ci, i)) {
if (htlc_this_side_offered(ci, i)) {
wscripts[n]
= bitcoin_redeem_htlc_send(wscripts,
&peer->remote.finalkey,
@ -1341,8 +1343,8 @@ static void resolve_our_unilateral(struct peer *peer)
*/
peer->closing_onchain.resolved[1] = tx;
num_ours = tal_count(ci->cstate->a.htlcs);
num_theirs = tal_count(ci->cstate->b.htlcs);
num_ours = tal_count(ci->cstate->side[OURS].htlcs);
num_theirs = tal_count(ci->cstate->side[THEIRS].htlcs);
/* BOLT #onchain:
*
@ -1391,8 +1393,8 @@ static void resolve_their_unilateral(struct peer *peer)
peer->closing_onchain.resolved[0] = tx;
/* Note the reversal, since ci is theirs, we are B */
num_ours = tal_count(ci->cstate->b.htlcs);
num_theirs = tal_count(ci->cstate->a.htlcs);
num_ours = tal_count(ci->cstate->side[THEIRS].htlcs);
num_theirs = tal_count(ci->cstate->side[OURS].htlcs);
/* BOLT #onchain:
*
@ -1651,8 +1653,8 @@ struct bitcoin_tx *peer_create_close_tx(struct peer *peer, u64 fee)
peer->local.finalkey.der[2], peer->local.finalkey.der[3],
peer->remote.finalkey.der[0], peer->remote.finalkey.der[1],
peer->remote.finalkey.der[2], peer->remote.finalkey.der[3],
cstate.a.pay_msat / 1000,
cstate.b.pay_msat / 1000);
cstate.side[OURS].pay_msat / 1000,
cstate.side[THEIRS].pay_msat / 1000);
return create_close_tx(peer->dstate->secpctx, peer,
peer->closing.our_script,
@ -1660,8 +1662,8 @@ struct bitcoin_tx *peer_create_close_tx(struct peer *peer, u64 fee)
&peer->anchor.txid,
peer->anchor.index,
peer->anchor.satoshis,
cstate.a.pay_msat / 1000,
cstate.b.pay_msat / 1000);
cstate.side[OURS].pay_msat / 1000,
cstate.side[THEIRS].pay_msat / 1000);
}
void peer_calculate_close_fee(struct peer *peer)
@ -1901,18 +1903,20 @@ bool setup_first_commit(struct peer *peer)
/* Revocation hashes already filled in, from pkt_open */
peer->local.commit->cstate = initial_funding(peer,
peer->local.offer_anchor
== CMD_OPEN_WITH_ANCHOR,
peer->anchor.satoshis,
peer->local.commit_fee_rate);
peer->anchor.satoshis,
peer->local.commit_fee_rate,
peer->local.offer_anchor
== CMD_OPEN_WITH_ANCHOR ?
OURS : THEIRS);
if (!peer->local.commit->cstate)
return false;
peer->remote.commit->cstate = initial_funding(peer,
peer->remote.offer_anchor
== CMD_OPEN_WITH_ANCHOR,
peer->anchor.satoshis,
peer->remote.commit_fee_rate);
peer->anchor.satoshis,
peer->remote.commit_fee_rate,
peer->remote.offer_anchor
== CMD_OPEN_WITH_ANCHOR ?
OURS : THEIRS);
if (!peer->remote.commit->cstate)
return false;
@ -2009,12 +2013,12 @@ static void json_getpeers(struct command *cmd,
}
last = p->local.commit->cstate;
json_add_num(response, "our_amount", last->a.pay_msat);
json_add_num(response, "our_fee", last->a.fee_msat);
json_add_num(response, "their_amount", last->b.pay_msat);
json_add_num(response, "their_fee", last->b.fee_msat);
json_add_htlcs(response, "our_htlcs", &last->a);
json_add_htlcs(response, "their_htlcs", &last->b);
json_add_num(response, "our_amount", last->side[OURS].pay_msat);
json_add_num(response, "our_fee", last->side[OURS].fee_msat);
json_add_num(response, "their_amount", last->side[THEIRS].pay_msat);
json_add_num(response, "their_fee", last->side[THEIRS].fee_msat);
json_add_htlcs(response, "our_htlcs", &last->side[OURS]);
json_add_htlcs(response, "their_htlcs", &last->side[THEIRS]);
/* Any changes since then? */
if (p->local.staging_cstate->changes != last->changes)
@ -2061,8 +2065,8 @@ static void check_htlc_expiry(struct peer *peer, void *unused)
/* Check their currently still-existing htlcs for expiry:
* We eliminate them from staging as we go. */
for (i = 0; i < tal_count(peer->remote.staging_cstate->a.htlcs); i++) {
struct channel_htlc *htlc = &peer->remote.staging_cstate->a.htlcs[i];
for (i = 0; i < tal_count(peer->remote.staging_cstate->side[OURS].htlcs); i++) {
struct channel_htlc *htlc = &peer->remote.staging_cstate->side[OURS].htlcs[i];
/* Not a seconds-based expiry? */
if (!abs_locktime_is_seconds(&htlc->expiry))
@ -2119,8 +2123,8 @@ static void do_newhtlc(struct peer *peer, struct newhtlc *newhtlc)
* A node MUST NOT add a HTLC if it would result in it
* offering more than 300 HTLCs in either commitment transaction.
*/
if (tal_count(peer->local.staging_cstate->a.htlcs) == 300
|| tal_count(peer->remote.staging_cstate->b.htlcs) == 300) {
if (tal_count(peer->local.staging_cstate->side[OURS].htlcs) == 300
|| tal_count(peer->remote.staging_cstate->side[THEIRS].htlcs) == 300) {
command_fail(newhtlc->jsoncmd, "Too many HTLCs");
}
@ -2131,9 +2135,9 @@ static void do_newhtlc(struct peer *peer, struct newhtlc *newhtlc)
* both commitment transactions at the current `fee_rate`
*/
cstate = copy_funding(newhtlc, peer->remote.staging_cstate);
if (!funding_b_add_htlc(cstate, newhtlc->htlc.msatoshis,
&newhtlc->htlc.expiry, &newhtlc->htlc.rhash,
newhtlc->htlc.id)) {
if (!funding_add_htlc(cstate, newhtlc->htlc.msatoshis,
&newhtlc->htlc.expiry, &newhtlc->htlc.rhash,
newhtlc->htlc.id, THEIRS)) {
command_fail(newhtlc->jsoncmd,
"Cannot afford %"PRIu64
" milli-satoshis in their commit tx",
@ -2142,9 +2146,9 @@ static void do_newhtlc(struct peer *peer, struct newhtlc *newhtlc)
}
cstate = copy_funding(newhtlc, peer->local.staging_cstate);
if (!funding_a_add_htlc(cstate, newhtlc->htlc.msatoshis,
&newhtlc->htlc.expiry, &newhtlc->htlc.rhash,
newhtlc->htlc.id)) {
if (!funding_add_htlc(cstate, newhtlc->htlc.msatoshis,
&newhtlc->htlc.expiry, &newhtlc->htlc.rhash,
newhtlc->htlc.id, OURS)) {
command_fail(newhtlc->jsoncmd,
"Cannot afford %"PRIu64
" milli-satoshis in our commit tx",
@ -2251,11 +2255,10 @@ static size_t find_their_committed_htlc(struct peer *peer,
const struct sha256 *rhash)
{
/* Must be in last committed cstate. */
if (funding_find_htlc(&peer->remote.commit->cstate->a, rhash)
== tal_count(peer->remote.commit->cstate->a.htlcs))
return tal_count(peer->remote.staging_cstate->a.htlcs);
if (funding_find_htlc(peer->remote.commit->cstate, rhash, OURS) == -1)
return -1;
return funding_find_htlc(&peer->remote.staging_cstate->a, rhash);
return funding_find_htlc(peer->remote.staging_cstate, rhash, OURS);
}
struct fulfillhtlc {
@ -2276,11 +2279,11 @@ static void do_fullfill(struct peer *peer,
sha256(&rhash, &fulfillhtlc->r, sizeof(fulfillhtlc->r));
i = find_their_committed_htlc(peer, &rhash);
if (i == tal_count(peer->remote.staging_cstate->a.htlcs)) {
if (i == -1) {
command_fail(fulfillhtlc->jsoncmd, "preimage htlc not found");
return;
}
stage.fulfill.id = peer->remote.staging_cstate->a.htlcs[i].id;
stage.fulfill.id = peer->remote.staging_cstate->side[OURS].htlcs[i].id;
set_htlc_command(peer, fulfillhtlc->jsoncmd,
CMD_SEND_HTLC_FULFILL, &stage);
}
@ -2350,11 +2353,11 @@ static void do_failhtlc(struct peer *peer,
/* Look in peer->remote.staging_cstate->a, as that's where we'll
* immediately remove it from: avoids double-handling. */
i = find_their_committed_htlc(peer, &failhtlc->rhash);
if (i == tal_count(peer->remote.staging_cstate->a.htlcs)) {
if (i == -1) {
command_fail(failhtlc->jsoncmd, "htlc not found");
return;
}
stage.fail.id = peer->remote.staging_cstate->a.htlcs[i].id;
stage.fail.id = peer->remote.staging_cstate->side[OURS].htlcs[i].id;
set_htlc_command(peer, failhtlc->jsoncmd, CMD_SEND_HTLC_FAIL, &stage);
}

167
funding.c

@ -1,5 +1,6 @@
#include "funding.h"
#include <assert.h>
#include <ccan/array_size/array_size.h>
#include <ccan/mem/mem.h>
#include <ccan/structeq/structeq.h>
#include <string.h>
@ -127,15 +128,14 @@ static bool change_funding(uint64_t anchor_satoshis,
}
struct channel_state *initial_funding(const tal_t *ctx,
bool am_funder,
uint64_t anchor_satoshis,
uint32_t fee_rate)
uint32_t fee_rate,
enum channel_side funding)
{
uint64_t fee_msat;
struct channel_state *cstate = talz(ctx, struct channel_state);
struct channel_oneside *funder, *fundee;
cstate->a.htlcs = tal_arr(cstate, struct channel_htlc, 0);
cstate->b.htlcs = tal_arr(cstate, struct channel_htlc, 0);
cstate->fee_rate = fee_rate;
cstate->anchor = anchor_satoshis;
cstate->changes = 0;
@ -148,24 +148,22 @@ struct channel_state *initial_funding(const tal_t *ctx,
if (fee_msat > anchor_satoshis * 1000)
return tal_free(cstate);
/* Initially, all goes back to funder. */
cstate->a.pay_msat = anchor_satoshis * 1000 - fee_msat;
cstate->a.fee_msat = fee_msat;
funder = &cstate->side[funding];
fundee = &cstate->side[!funding];
/* Neither side has HTLCs. */
funder->htlcs = tal_arr(cstate, struct channel_htlc, 0);
fundee->htlcs = tal_arr(cstate, struct channel_htlc, 0);
/* If B (not A) is funder, invert. */
if (!am_funder)
invert_cstate(cstate);
/* Initially, all goes back to funder. */
funder->pay_msat = anchor_satoshis * 1000 - fee_msat;
funder->fee_msat = fee_msat;
/* Make sure it checks out. */
assert(change_funding(anchor_satoshis, fee_rate, 0,
&cstate->a, &cstate->b, 0));
if (am_funder) {
assert(cstate->a.fee_msat == fee_msat);
assert(cstate->b.fee_msat == 0);
} else {
assert(cstate->b.fee_msat == fee_msat);
assert(cstate->a.fee_msat == 0);
}
assert(change_funding(anchor_satoshis, fee_rate, 0, funder, fundee, 0));
assert(funder->fee_msat == fee_msat);
assert(fundee->fee_msat == 0);
return cstate;
}
@ -188,8 +186,8 @@ static size_t count_nondust_htlcs(const struct channel_htlc *htlcs)
static size_t total_nondust_htlcs(const struct channel_state *cstate)
{
return count_nondust_htlcs(cstate->a.htlcs)
+ count_nondust_htlcs(cstate->b.htlcs);
return count_nondust_htlcs(cstate->side[OURS].htlcs)
+ count_nondust_htlcs(cstate->side[THEIRS].htlcs);
}
void adjust_fee(struct channel_state *cstate, uint32_t fee_rate)
@ -198,7 +196,7 @@ void adjust_fee(struct channel_state *cstate, uint32_t fee_rate)
fee_msat = calculate_fee_msat(total_nondust_htlcs(cstate), fee_rate);
recalculate_fees(&cstate->a, &cstate->b, fee_msat);
recalculate_fees(&cstate->side[OURS], &cstate->side[THEIRS], fee_msat);
cstate->changes++;
}
@ -207,33 +205,34 @@ bool force_fee(struct channel_state *cstate, uint64_t fee)
/* Beware overflow! */
if (fee > 0xFFFFFFFFFFFFFFFFULL / 1000)
return false;
recalculate_fees(&cstate->a, &cstate->b, fee * 1000);
recalculate_fees(&cstate->side[OURS], &cstate->side[THEIRS], fee * 1000);
cstate->changes++;
return cstate->a.fee_msat + cstate->b.fee_msat == fee * 1000;
return cstate->side[OURS].fee_msat + cstate->side[THEIRS].fee_msat == fee * 1000;
}
void invert_cstate(struct channel_state *cstate)
{
struct channel_oneside tmp;
tmp = cstate->a;
cstate->a = cstate->b;
cstate->b = tmp;
tmp = cstate->side[OURS];
cstate->side[OURS] = cstate->side[THEIRS];
cstate->side[THEIRS] = tmp;
}
/* Add a HTLC to @creator if it can afford it. */
static struct channel_htlc *add_htlc(struct channel_state *cstate,
struct channel_oneside *creator,
struct channel_oneside *recipient,
u32 msatoshis,
const struct abs_locktime *expiry,
const struct sha256 *rhash, uint64_t id)
struct channel_htlc *funding_add_htlc(struct channel_state *cstate,
u32 msatoshis,
const struct abs_locktime *expiry,
const struct sha256 *rhash, uint64_t id,
enum channel_side side)
{
size_t n, nondust;
struct channel_oneside *creator, *recipient;
assert((creator == &cstate->a && recipient == &cstate->b)
|| (creator == &cstate->b && recipient == &cstate->a));
creator = &cstate->side[side];
recipient = &cstate->side[!side];
/* Remember to count the new one in total txsize if not dust! */
nondust = total_nondust_htlcs(cstate);
if (!is_dust_amount(msatoshis / 1000))
@ -259,108 +258,84 @@ static struct channel_htlc *add_htlc(struct channel_state *cstate,
/* Remove htlc from creator, credit it to beneficiary. */
static void remove_htlc(struct channel_state *cstate,
struct channel_oneside *creator,
struct channel_oneside *beneficiary,
struct channel_oneside *non_beneficiary,
enum channel_side creator,
enum channel_side beneficiary,
size_t i)
{
size_t n = tal_count(creator->htlcs);
size_t n = tal_count(cstate->side[creator].htlcs);
size_t nondust;
assert(i < n);
assert(creator == &cstate->a || creator == &cstate->b);
assert((beneficiary == &cstate->a && non_beneficiary == &cstate->b)
|| (beneficiary == &cstate->b && non_beneficiary == &cstate->a));
/* Remember to remove this one in total txsize if not dust! */
nondust = total_nondust_htlcs(cstate);
if (!is_dust_amount(creator->htlcs[i].msatoshis / 1000)) {
if (!is_dust_amount(cstate->side[creator].htlcs[i].msatoshis / 1000)) {
assert(nondust > 0);
nondust--;
}
/* Can't fail since msatoshis is positive. */
if (!change_funding(cstate->anchor, cstate->fee_rate,
-(int64_t)creator->htlcs[i].msatoshis,
beneficiary, non_beneficiary, nondust))
-(int64_t)cstate->side[creator].htlcs[i].msatoshis,
&cstate->side[beneficiary],
&cstate->side[!beneficiary], nondust))
abort();
/* Actually remove the HTLC. */
memmove(creator->htlcs + i, creator->htlcs + i + 1,
(n - i - 1) * sizeof(*creator->htlcs));
tal_resize(&creator->htlcs, n-1);
memmove(cstate->side[creator].htlcs + i,
cstate->side[creator].htlcs + i + 1,
(n - i - 1) * sizeof(*cstate->side[creator].htlcs));
tal_resize(&cstate->side[creator].htlcs, n-1);
cstate->changes++;
}
struct channel_htlc *funding_a_add_htlc(struct channel_state *cstate,
u32 msatoshis,
const struct abs_locktime *expiry,
const struct sha256 *rhash, uint64_t id)
{
return add_htlc(cstate, &cstate->a, &cstate->b,
msatoshis, expiry, rhash, id);
}
struct channel_htlc *funding_b_add_htlc(struct channel_state *cstate,
u32 msatoshis,
const struct abs_locktime *expiry,
const struct sha256 *rhash, uint64_t id)
void funding_fail_htlc(struct channel_state *cstate, size_t index,
enum channel_side side)
{
return add_htlc(cstate, &cstate->b, &cstate->a,
msatoshis, expiry, rhash, id);
remove_htlc(cstate, side, side, index);
}
void funding_a_fail_htlc(struct channel_state *cstate, size_t index)
void funding_fulfill_htlc(struct channel_state *cstate, size_t index,
enum channel_side side)
{
remove_htlc(cstate, &cstate->a, &cstate->a, &cstate->b, index);
remove_htlc(cstate, side, !side, index);
}
void funding_b_fail_htlc(struct channel_state *cstate, size_t index)
{
remove_htlc(cstate, &cstate->b, &cstate->b, &cstate->a, index);
}
void funding_a_fulfill_htlc(struct channel_state *cstate, size_t index)
{
remove_htlc(cstate, &cstate->a, &cstate->b, &cstate->a, index);
}
void funding_b_fulfill_htlc(struct channel_state *cstate, size_t index)
{
remove_htlc(cstate, &cstate->b, &cstate->a, &cstate->b, index);
}
size_t funding_find_htlc(struct channel_oneside *creator,
const struct sha256 *rhash)
size_t funding_find_htlc(const struct channel_state *cstate,
const struct sha256 *rhash,
enum channel_side side)
{
size_t i;
for (i = 0; i < tal_count(creator->htlcs); i++) {
if (structeq(&creator->htlcs[i].rhash, rhash))
break;
for (i = 0; i < tal_count(cstate->side[side].htlcs); i++) {
if (structeq(&cstate->side[side].htlcs[i].rhash, rhash))
return i;
}
return i;
return -1;
}
size_t funding_htlc_by_id(struct channel_oneside *creator, uint64_t id)
size_t funding_htlc_by_id(const struct channel_state *cstate,
uint64_t id,
enum channel_side side)
{
size_t i;
for (i = 0; i < tal_count(creator->htlcs); i++) {
if (creator->htlcs[i].id == id)
break;
for (i = 0; i < tal_count(cstate->side[side].htlcs); i++) {
if (cstate->side[side].htlcs[i].id == id)
return i;
}
return i;
return -1;
}
struct channel_state *copy_funding(const tal_t *ctx,
const struct channel_state *cstate)
{
struct channel_state *cs = tal_dup(ctx, struct channel_state, cstate);
size_t i;
cs->a.htlcs = tal_dup_arr(cs, struct channel_htlc, cs->a.htlcs,
tal_count(cs->a.htlcs), 0);
cs->b.htlcs = tal_dup_arr(cs, struct channel_htlc, cs->b.htlcs,
tal_count(cs->b.htlcs), 0);
for (i = 0; i < ARRAY_SIZE(cs->side); i++)
cs->side[i].htlcs = tal_dup_arr(cs, struct channel_htlc,
cs->side[i].htlcs,
tal_count(cs->side[i].htlcs), 0);
return cs;
}

89
funding.h

@ -20,6 +20,13 @@ struct channel_oneside {
struct channel_htlc *htlcs;
};
enum channel_side {
/* Output for us, htlcs we offered to them. */
OURS,
/* Output for them, htlcs they offered to us. */
THEIRS
};
struct channel_state {
/* Satoshis paid by anchor. */
uint64_t anchor;
@ -27,22 +34,22 @@ struct channel_state {
uint32_t fee_rate;
/* Generation counter (incremented on every change) */
uint32_t changes;
struct channel_oneside a, b;
struct channel_oneside side[2];
};
/**
* initial_funding: Given A, B, and anchor, what is initial state?
* initial_funding: Given initial fees and funding anchor, what is initial state?
* @ctx: tal context to allocate return value from.
* @am_funder: am I paying for the anchor?
* @anchor_satoshis: The anchor amount.
* @fee_rate: amount to pay in fees per kb (in satoshi).
* @dir: which side paid for the anchor.
*
* Returns state, or NULL if malformed.
*/
struct channel_state *initial_funding(const tal_t *ctx,
bool am_funder,
uint64_t anchor_satoshis,
uint32_t fee_rate);
uint32_t fee_rate,
enum channel_side side);
/**
* copy_funding: Make a deep copy of channel_state
@ -53,49 +60,48 @@ struct channel_state *copy_funding(const tal_t *ctx,
const struct channel_state *cstate);
/**
* funding_a_add_htlc: append an HTLC to A's side of cstate if it can afford it
* funding_add_htlc: append an HTLC to cstate if it can afford it
* @cstate: The channel state
* @msatoshis: Millisatoshi A is putting into a HTLC
* @msatoshis: Millisatoshi going into a HTLC
* @expiry: time it expires
* @rhash: hash of redeem secret
* @id: 64-bit ID for htlc
* @side: OURS or THEIRS
*
* If A can't afford the HTLC (or still owes its half of the fees),
* If that direction can't afford the HTLC (or still owes its half of the fees),
* this will return NULL and leave @cstate unchanged. Otherwise
* cstate->a.htlcs will have the HTLC appended, and pay_msat and
* fee_msat are adjusted accordingly; &cstate->htlcs[<last] is returned.
* cstate->side[dir].htlcs will have the HTLC appended, and pay_msat and
* fee_msat are adjusted accordingly; &cstate->side[dir].htlcs[<last>]
* is returned.
*/
struct channel_htlc *funding_a_add_htlc(struct channel_state *cstate,
u32 msatoshis,
const struct abs_locktime *expiry,
const struct sha256 *rhash, uint64_t id);
struct channel_htlc *funding_b_add_htlc(struct channel_state *cstate,
u32 msatoshis,
const struct abs_locktime *expiry,
const struct sha256 *rhash, uint64_t id);
struct channel_htlc *funding_add_htlc(struct channel_state *cstate,
u32 msatoshis,
const struct abs_locktime *expiry,
const struct sha256 *rhash, uint64_t id,
enum channel_side side);
/**
* funding_a_fail_htlc: remove an HTLC from A's side of cstate, funds to A
* funding_fail_htlc: remove an HTLC, funds to the side which offered it.
* @cstate: The channel state
* @index: the index into cstate->a.htlcs[].
* @index: the index into cstate->side[dir].htlcs[].
* @side: OURS or THEIRS
*
* This will remove the @index'th entry in cstate->a.htlcs[], and credit
* the value of the HTLC (back) to A.
* This will remove the @index'th entry in cstate->side[dir].htlcs[], and credit
* the value of the HTLC (back) to cstate->side[dir].
*/
void funding_a_fail_htlc(struct channel_state *cstate, size_t index);
void funding_b_fail_htlc(struct channel_state *cstate, size_t index);
void funding_fail_htlc(struct channel_state *cstate, size_t index,
enum channel_side side);
/**
* funding_a_fulfill_htlc: remove an HTLC from A's side of cstate, funds to B
* funding_fulfill_htlc: remove an HTLC, funds to side which accepted it.
* @cstate: The channel state
* @index: the index into cstate->a.htlcs[].
* @side: OURS or THEIRS
*
* This will remove the @index'th entry in cstate->a.htlcs[], and credit
* the value of the HTLC to B.
* This will remove the @index'th entry in cstate->side[dir].htlcs[], and credit
* the value of the HTLC to cstate->side[!dir].
*/
void funding_a_fulfill_htlc(struct channel_state *cstate, size_t index);
void funding_b_fulfill_htlc(struct channel_state *cstate, size_t index);
void funding_fulfill_htlc(struct channel_state *cstate, size_t index,
enum channel_side side);
/**
* adjust_fee: Change fee rate.
@ -123,24 +129,27 @@ void invert_cstate(struct channel_state *cstate);
/**
* funding_find_htlc: find an HTLC on this side of the channel.
* @creator: channel_state->a or channel_state->b, whichever originated htlc
* @cstate: The channel state
* @rhash: hash of redeem secret
* @side: OURS or THEIRS
*
* Returns a number < tal_count(creator->htlcs), or == tal_count(creator->htlcs)
* on fail.
* Returns a number < tal_count(cstate->side[dir].htlcs), or -1 on fail.
*/
size_t funding_find_htlc(struct channel_oneside *creator,
const struct sha256 *rhash);
size_t funding_find_htlc(const struct channel_state *cstate,
const struct sha256 *rhash,
enum channel_side side);
/**
* funding_htlc_by_id: find an HTLC on this side of the channel by ID.
* @creator: channel_state->a or channel_state->b, whichever originated htlc
* @cstate: The channel state
* @id: id for HTLC.
* @side: OURS or THEIRS
*
* Returns a number < tal_count(creator->htlcs), or == tal_count(creator->htlcs)
* on fail.
* Returns a number < tal_count(cstate->side[dir].htlcs), or -1 on fail.
*/
size_t funding_htlc_by_id(struct channel_oneside *creator, uint64_t id);
size_t funding_htlc_by_id(const struct channel_state *cstate,
uint64_t id,
enum channel_side side);
/**
* fee_for_feerate: calculate the fee (in satoshi) for a given fee_rate.

Loading…
Cancel
Save