From 08f7ade80feca29bf2c6f3df176fdc405f644851 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 18 Aug 2016 14:23:45 +0930 Subject: [PATCH] peer.c, packets.c: make more functions static. This also has to re-order functions, so it looks worse than it is. Signed-off-by: Rusty Russell --- daemon/packets.h | 3 - daemon/peer.c | 1111 +++++++++++++++++++++++----------------------- daemon/peer.h | 35 +- state.h | 21 +- 4 files changed, 563 insertions(+), 607 deletions(-) diff --git a/daemon/packets.h b/daemon/packets.h index 14c22802c..140325839 100644 --- a/daemon/packets.h +++ b/daemon/packets.h @@ -9,9 +9,6 @@ struct sha256; struct bitcoin_signature; struct commit_info; -/* Inform peer have an unexpected packet. */ -void peer_unexpected_pkt(struct peer *peer, const Pkt *pkt); - /* Send various kinds of packets */ void queue_pkt_open(struct peer *peer, OpenChannel__AnchorOffer anchor); void queue_pkt_anchor(struct peer *peer); diff --git a/daemon/peer.c b/daemon/peer.c index 551f9ca68..7fe4c625f 100644 --- a/daemon/peer.c +++ b/daemon/peer.c @@ -52,6 +52,126 @@ struct json_connecting { struct anchor_input *input; }; +static bool command_htlc_fail(struct peer *peer, struct htlc *htlc); +static bool command_htlc_fulfill(struct peer *peer, struct htlc *htlc); +static void try_commit(struct peer *peer); + +/* Create a bitcoin close tx, using last signature they sent. */ +static const struct bitcoin_tx *bitcoin_close(struct peer *peer) +{ + struct bitcoin_tx *close_tx; + struct bitcoin_signature our_close_sig; + + close_tx = peer_create_close_tx(peer, peer->closing.their_fee); + + our_close_sig.stype = SIGHASH_ALL; + peer_sign_mutual_close(peer, close_tx, &our_close_sig.sig); + + close_tx->input[0].witness + = bitcoin_witness_2of2(close_tx->input, + peer->dstate->secpctx, + peer->closing.their_sig, + &our_close_sig, + &peer->remote.commitkey, + &peer->local.commitkey); + + return close_tx; +} + +/* Create a bitcoin spend tx (to spend our commit's outputs) */ +static const struct bitcoin_tx *bitcoin_spend_ours(struct peer *peer) +{ + u8 *witnessscript; + const struct bitcoin_tx *commit = peer->local.commit->tx; + struct bitcoin_signature sig; + struct bitcoin_tx *tx; + unsigned int p2wsh_out; + uint64_t fee; + + /* The redeemscript for a commit tx is fairly complex. */ + witnessscript = bitcoin_redeem_secret_or_delay(peer, + peer->dstate->secpctx, + &peer->local.finalkey, + &peer->remote.locktime, + &peer->remote.finalkey, + &peer->local.commit->revocation_hash); + + /* Now, create transaction to spend it. */ + tx = bitcoin_tx(peer, 1, 1); + tx->input[0].txid = peer->local.commit->txid; + p2wsh_out = find_p2wsh_out(commit, witnessscript); + tx->input[0].index = p2wsh_out; + tx->input[0].sequence_number = bitcoin_nsequence(&peer->remote.locktime); + tx->input[0].amount = tal_dup(tx->input, u64, + &commit->output[p2wsh_out].amount); + + tx->output[0].script = scriptpubkey_p2sh(tx, + bitcoin_redeem_single(tx, + peer->dstate->secpctx, + &peer->local.finalkey)); + tx->output[0].script_length = tal_count(tx->output[0].script); + + /* Witness length can vary, due to DER encoding of sigs, but we + * use 176 from an example run. */ + assert(measure_tx_cost(tx) == 83 * 4); + + /* FIXME: Dynamic fees! */ + fee = fee_by_feerate(83 + 176 / 4, + peer->dstate->config.closing_fee_rate); + + /* FIXME: Fail gracefully in these cases (not worth collecting) */ + if (fee > commit->output[p2wsh_out].amount + || is_dust_amount(commit->output[p2wsh_out].amount - fee)) + fatal("Amount of %"PRIu64" won't cover fee %"PRIu64, + commit->output[p2wsh_out].amount, fee); + + tx->output[0].amount = commit->output[p2wsh_out].amount - fee; + + sig.stype = SIGHASH_ALL; + peer_sign_spend(peer, tx, witnessscript, &sig.sig); + + tx->input[0].witness = bitcoin_witness_secret(tx, + peer->dstate->secpctx, + NULL, 0, &sig, + witnessscript); + + return tx; +} + +/* Sign and return our commit tx */ +static const struct bitcoin_tx *bitcoin_commit(struct peer *peer) +{ + struct bitcoin_signature sig; + + /* Can't be signed already, and can't have scriptsig! */ + assert(peer->local.commit->tx->input[0].script_length == 0); + assert(!peer->local.commit->tx->input[0].witness); + + sig.stype = SIGHASH_ALL; + peer_sign_ourcommit(peer, peer->local.commit->tx, &sig.sig); + + peer->local.commit->tx->input[0].witness + = bitcoin_witness_2of2(peer->local.commit->tx->input, + peer->dstate->secpctx, + peer->local.commit->sig, + &sig, + &peer->remote.commitkey, + &peer->local.commitkey); + + return peer->local.commit->tx; +} + +static u64 commit_tx_fee(const struct bitcoin_tx *commit, u64 anchor_satoshis) +{ + uint64_t i, total = 0; + + for (i = 0; i < commit->output_count; i++) + total += commit->output[i].amount; + + assert(anchor_satoshis >= total); + return anchor_satoshis - total; +} + struct peer *find_peer(struct lightningd_state *dstate, const struct pubkey *id) { struct peer *peer; @@ -90,7 +210,20 @@ static bool peer_uncommitted_changes(const struct peer *peer) != peer->remote.commit->cstate->changes; } -void peer_update_complete(struct peer *peer) +static void remote_changes_pending(struct peer *peer) +{ + log_debug(peer->log, "remote_changes_pending: changes=%u", + peer->remote.staging_cstate->changes); + if (!peer->commit_timer) { + log_debug(peer->log, "remote_changes_pending: adding timer"); + peer->commit_timer = new_reltimer(peer->dstate, peer, + peer->dstate->config.commit_time, + try_commit, peer); + } else + log_debug(peer->log, "remote_changes_pending: timer already exists"); +} + +static void peer_update_complete(struct peer *peer) { log_debug(peer->log, "peer_update_complete"); if (peer->commit_jsoncmd) { @@ -199,6 +332,30 @@ static bool peer_comms_err(struct peer *peer, Pkt *err) return false; } +void peer_unexpected_pkt(struct peer *peer, const Pkt *pkt) +{ + const char *p; + + log_unusual(peer->log, "Received unexpected pkt %u (%s)", + pkt->pkt_case, pkt_name(pkt->pkt_case)); + + if (pkt->pkt_case != PKT__PKT_ERROR) + return; + + /* Check packet for weird chars. */ + for (p = pkt->error->problem; *p; p++) { + if (cisprint(*p)) + continue; + + p = tal_hexstr(peer, pkt->error->problem, + strlen(pkt->error->problem)); + log_unusual(peer->log, "Error pkt (hex) %s", p); + tal_free(p); + return; + } + log_unusual(peer->log, "Error pkt '%s'", pkt->error->problem); +} + /* Unexpected packet received: stop listening, start breakdown procedure. */ static bool peer_received_unexpected_pkt(struct peer *peer, const Pkt *pkt) { @@ -207,11 +364,11 @@ static bool peer_received_unexpected_pkt(struct peer *peer, const Pkt *pkt) } /* At revocation time, we apply the changeset to the other side. */ -void apply_changeset(struct peer *peer, - struct peer_visible_state *which, - enum channel_side side, - const union htlc_staging *changes, - size_t num_changes) +static void apply_changeset(struct peer *peer, + struct peer_visible_state *which, + enum channel_side side, + const union htlc_staging *changes, + size_t num_changes) { size_t i; struct htlc *htlc; @@ -253,70 +410,350 @@ void apply_changeset(struct peer *peer, } } -/* This is the io loop while we're negotiating closing tx. */ -static bool closing_pkt_in(struct peer *peer, const Pkt *pkt) -{ - const CloseSignature *c = pkt->close_signature; - struct bitcoin_tx *close_tx; - struct bitcoin_signature theirsig; +struct state_table { + enum htlc_state from, to; +}; - assert(peer->state == STATE_MUTUAL_CLOSING); +static bool htlcs_changestate(struct peer *peer, + const struct state_table *table, size_t n) +{ + struct htlc_map_iter it; + struct htlc *h; + bool changed = false; - if (pkt->pkt_case != PKT__PKT_CLOSE_SIGNATURE) - return peer_received_unexpected_pkt(peer, pkt); + for (h = htlc_map_first(&peer->htlcs, &it); + h; + h = htlc_map_next(&peer->htlcs, &it)) { + size_t i; + for (i = 0; i < n; i++) { + if (h->state == table[i].from) { + htlc_changestate(h, table[i].from, table[i].to); + changed = true; + } + } + } + return changed; +} - log_info(peer->log, "closing_pkt_in: they offered close fee %"PRIu64, - c->close_fee); +static void route_htlc_onwards(struct peer *peer, + struct htlc *htlc, + u64 msatoshis, + const BitcoinPubkey *pb_id, + const u8 *rest_of_route) +{ + struct pubkey id; + struct peer *next; - /* BOLT #2: - * - * The sender MUST set `close_fee` lower than or equal to the fee of the - * final commitment transaction, and MUST set `close_fee` to an even - * number of satoshis. - */ - if ((c->close_fee & 1) - || c->close_fee > commit_tx_fee(peer->remote.commit->tx, - peer->anchor.satoshis)) { - return peer_comms_err(peer, pkt_err(peer, "Invalid close fee")); + log_debug_struct(peer->log, "Forwarding HTLC %s", struct sha256, &htlc->rhash); + log_add(peer->log, " (id %"PRIu64")", htlc->id); + + if (!proto_to_pubkey(peer->dstate->secpctx, pb_id, &id)) { + log_unusual(peer->log, + "Malformed pubkey for HTLC %"PRIu64, htlc->id); + command_htlc_fail(peer, htlc); + return; } - /* FIXME: Don't accept tiny fee at all? */ + next = find_peer(peer->dstate, &id); + if (!next || !next->nc) { + log_unusual(peer->log, "Can't route HTLC %"PRIu64": no %speer ", + htlc->id, next ? "ready " : ""); + log_add_struct(peer->log, "%s", struct pubkey, &id); + if (!peer->dstate->dev_never_routefail) + command_htlc_fail(peer, htlc); + return; + } - /* BOLT #2: - ... otherwise it SHOULD propose a - value strictly between the received `close_fee` and its - previously-sent `close_fee`. - */ - if (peer->closing.their_sig) { - /* We want more, they should give more. */ - if (peer->closing.our_fee > peer->closing.their_fee) { - if (c->close_fee <= peer->closing.their_fee) - return peer_comms_err(peer, - pkt_err(peer, "Didn't increase close fee")); - } else { - if (c->close_fee >= peer->closing.their_fee) - return peer_comms_err(peer, - pkt_err(peer, "Didn't decrease close fee")); - } + /* Offered fee must be sufficient. */ + if (htlc->msatoshis - msatoshis < connection_fee(next->nc, msatoshis)) { + log_unusual(peer->log, + "Insufficient fee for HTLC %"PRIu64 + ": %"PRIi64" on %"PRIu64, + htlc->id, htlc->msatoshis - msatoshis, + msatoshis); + command_htlc_fail(peer, htlc); + return; } - /* BOLT #2: - * - * The receiver MUST check `sig` is valid for the close - * transaction with the given `close_fee`, and MUST fail the - * connection if it is not. */ - theirsig.stype = SIGHASH_ALL; - if (!proto_to_signature(peer->dstate->secpctx, c->sig, &theirsig.sig)) - return peer_comms_err(peer, - pkt_err(peer, "Invalid signature format")); + log_debug_struct(peer->log, "HTLC forward to %s", + struct pubkey, next->id); - close_tx = peer_create_close_tx(peer, c->close_fee); - if (!check_tx_sig(peer->dstate->secpctx, close_tx, 0, - NULL, 0, - peer->anchor.witnessscript, - &peer->remote.commitkey, &theirsig)) - return peer_comms_err(peer, - pkt_err(peer, "Invalid signature")); + /* This checks the HTLC itself is possible. */ + if (!command_htlc_add(next, msatoshis, + abs_locktime_to_blocks(&htlc->expiry) + - next->nc->delay, + &htlc->rhash, htlc, rest_of_route)) { + command_htlc_fail(peer, htlc); + return; + } +} + +static const char *owner_name(enum channel_side side) +{ + return side == OURS ? "our" : "their"; +} + +static void their_htlc_added(struct peer *peer, struct htlc *htlc) +{ + RouteStep *step; + const u8 *rest_of_route; + struct payment *payment; + + if (abs_locktime_is_seconds(&htlc->expiry)) { + log_unusual(peer->log, "HTLC %"PRIu64" is in seconds", htlc->id); + command_htlc_fail(peer, htlc); + return; + } + + if (abs_locktime_to_blocks(&htlc->expiry) <= + get_block_height(peer->dstate) + peer->dstate->config.min_htlc_expiry) { + log_unusual(peer->log, "HTLC %"PRIu64" expires too soon:" + " block %u", + htlc->id, abs_locktime_to_blocks(&htlc->expiry)); + command_htlc_fail(peer, htlc); + return; + } + + if (abs_locktime_to_blocks(&htlc->expiry) > + get_block_height(peer->dstate) + peer->dstate->config.max_htlc_expiry) { + log_unusual(peer->log, "HTLC %"PRIu64" expires too far:" + " block %u", + htlc->id, abs_locktime_to_blocks(&htlc->expiry)); + command_htlc_fail(peer, htlc); + return; + } + + step = onion_unwrap(peer, htlc->routing, tal_count(htlc->routing), + &rest_of_route); + if (!step) { + log_unusual(peer->log, "Bad onion, failing HTLC %"PRIu64, + htlc->id); + command_htlc_fail(peer, htlc); + return; + } + + switch (step->next_case) { + case ROUTE_STEP__NEXT_END: + payment = find_payment(peer->dstate, &htlc->rhash); + if (!payment) { + log_unusual(peer->log, "No payment for HTLC %"PRIu64, + htlc->id); + log_add_struct(peer->log, " rhash=%s", + struct sha256, &htlc->rhash); + if (unlikely(!peer->dstate->dev_never_routefail)) + command_htlc_fail(peer, htlc); + goto free_rest; + } + + if (htlc->msatoshis != payment->msatoshis) { + log_unusual(peer->log, "Short payment for HTLC %"PRIu64 + ": %"PRIu64" not %"PRIu64 " satoshi!", + htlc->id, + htlc->msatoshis, + payment->msatoshis); + command_htlc_fail(peer, htlc); + return; + } + + log_info(peer->log, "Immediately resolving HTLC %"PRIu64, + htlc->id); + + assert(!htlc->r); + htlc->r = tal_dup(htlc, struct rval, &payment->r); + command_htlc_fulfill(peer, htlc); + goto free_rest; + + case ROUTE_STEP__NEXT_BITCOIN: + route_htlc_onwards(peer, htlc, step->amount, step->bitcoin, + rest_of_route); + goto free_rest; + default: + log_info(peer->log, "Unknown step type %u", step->next_case); + command_htlc_fail(peer, htlc); + goto free_rest; + } + +free_rest: + tal_free(rest_of_route); +} + +static void our_htlc_failed(struct peer *peer, struct htlc *htlc) +{ + if (htlc->src) + command_htlc_fail(htlc->src->peer, htlc->src); + else + complete_pay_command(peer, htlc); +} + +static void our_htlc_fulfilled(struct peer *peer, struct htlc *htlc, + const struct rval *preimage) +{ + if (htlc->src) { + assert(!htlc->src->r); + htlc->src->r = tal_dup(htlc->src, struct rval, htlc->r); + command_htlc_fulfill(htlc->src->peer, htlc->src); + } else { + complete_pay_command(peer, htlc); + } +} + +/* When changes are committed to. */ +static void peer_both_committed_to(struct peer *peer, + const union htlc_staging *changes, + enum channel_side side) +{ + size_t i, n = tal_count(changes); + + /* All this, simply for debugging. */ + for (i = 0; i < n; i++) { + u64 htlc_id; + const char *type, *owner; + + switch (changes[i].type) { + case HTLC_ADD: + type = "ADD"; + htlc_id = changes[i].add.htlc->id; + owner = owner_name(side); + assert(cstate_htlc_by_id(peer->remote.commit->cstate, htlc_id, + side)); + assert(cstate_htlc_by_id(peer->local.commit->cstate, htlc_id, + side)); + goto print; + case HTLC_FAIL: + type = "FAIL"; + htlc_id = changes[i].fail.htlc->id; + owner = owner_name(!side); + assert(!cstate_htlc_by_id(peer->remote.commit->cstate, htlc_id, + !side)); + assert(!cstate_htlc_by_id(peer->local.commit->cstate, htlc_id, + !side)); + assert(cstate_htlc_by_id(peer->remote.commit->prev->cstate, + htlc_id, !side) + || cstate_htlc_by_id(peer->local.commit->prev->cstate, + htlc_id, !side)); + goto print; + case HTLC_FULFILL: + type = "FULFILL"; + htlc_id = changes[i].fulfill.htlc->id; + owner = owner_name(!side); + assert(!cstate_htlc_by_id(peer->remote.commit->cstate, htlc_id, + !side)); + assert(!cstate_htlc_by_id(peer->local.commit->cstate, htlc_id, + !side)); + assert(cstate_htlc_by_id(peer->remote.commit->prev->cstate, + htlc_id, !side) + || cstate_htlc_by_id(peer->local.commit->prev->cstate, + htlc_id, !side)); + goto print; + } + abort(); + print: + log_debug(peer->log, "Both committed to %s of %s HTLC %"PRIu64, + type, owner, htlc_id); + } + + /* We actually only respond to changes they made. */ + if (side == OURS) + return; + + for (i = 0; i < n; i++) { + switch (changes[i].type) { + case HTLC_ADD: + their_htlc_added(peer, changes[i].add.htlc); + break; + case HTLC_FULFILL: + /* We handled this as soon as we got it. */ + break; + case HTLC_FAIL: + our_htlc_failed(peer, changes[i].fail.htlc); + break; + } + } +} + +static void add_unacked(struct peer_visible_state *which, + const union htlc_staging *stage) +{ + size_t n = tal_count(which->commit->unacked_changes); + tal_resize(&which->commit->unacked_changes, n+1); + which->commit->unacked_changes[n] = *stage; +} + +static void add_acked_changes(union htlc_staging **acked, + const union htlc_staging *changes) +{ + size_t n_acked, n_changes; + + n_acked = tal_count(*acked); + n_changes = tal_count(changes); + tal_resize(acked, n_acked + n_changes); + memcpy(*acked + n_acked, changes, n_changes * sizeof(*changes)); +} + +/* This is the io loop while we're negotiating closing tx. */ +static bool closing_pkt_in(struct peer *peer, const Pkt *pkt) +{ + const CloseSignature *c = pkt->close_signature; + struct bitcoin_tx *close_tx; + struct bitcoin_signature theirsig; + + assert(peer->state == STATE_MUTUAL_CLOSING); + + if (pkt->pkt_case != PKT__PKT_CLOSE_SIGNATURE) + return peer_received_unexpected_pkt(peer, pkt); + + log_info(peer->log, "closing_pkt_in: they offered close fee %"PRIu64, + c->close_fee); + + /* BOLT #2: + * + * The sender MUST set `close_fee` lower than or equal to the fee of the + * final commitment transaction, and MUST set `close_fee` to an even + * number of satoshis. + */ + if ((c->close_fee & 1) + || c->close_fee > commit_tx_fee(peer->remote.commit->tx, + peer->anchor.satoshis)) { + return peer_comms_err(peer, pkt_err(peer, "Invalid close fee")); + } + + /* FIXME: Don't accept tiny fee at all? */ + + /* BOLT #2: + ... otherwise it SHOULD propose a + value strictly between the received `close_fee` and its + previously-sent `close_fee`. + */ + if (peer->closing.their_sig) { + /* We want more, they should give more. */ + if (peer->closing.our_fee > peer->closing.their_fee) { + if (c->close_fee <= peer->closing.their_fee) + return peer_comms_err(peer, + pkt_err(peer, "Didn't increase close fee")); + } else { + if (c->close_fee >= peer->closing.their_fee) + return peer_comms_err(peer, + pkt_err(peer, "Didn't decrease close fee")); + } + } + + /* BOLT #2: + * + * The receiver MUST check `sig` is valid for the close + * transaction with the given `close_fee`, and MUST fail the + * connection if it is not. */ + theirsig.stype = SIGHASH_ALL; + if (!proto_to_signature(peer->dstate->secpctx, c->sig, &theirsig.sig)) + return peer_comms_err(peer, + pkt_err(peer, "Invalid signature format")); + + close_tx = peer_create_close_tx(peer, c->close_fee); + if (!check_tx_sig(peer->dstate->secpctx, close_tx, 0, + NULL, 0, + peer->anchor.witnessscript, + &peer->remote.commitkey, &theirsig)) + return peer_comms_err(peer, + pkt_err(peer, "Invalid signature")); tal_free(peer->closing.their_sig); peer->closing.their_sig = tal_dup(peer, @@ -596,15 +1033,49 @@ static Pkt *handle_pkt_revocation(struct peer *peer, const Pkt *pkt) if (!htlcs_changestate(peer, changes, ARRAY_SIZE(changes))) fatal("Revocation received but we made empty commitment?"); - /* Should never examine these again. */ - ci->unacked_changes = tal_free(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; +} + +static void peer_calculate_close_fee(struct peer *peer) +{ + /* Use actual worst-case length of close tx: based on BOLT#02's + * commitment tx numbers, but only 1 byte for output count */ + const uint64_t txsize = 41 + 221 + 10 + 32 + 32; + uint64_t maxfee; + + /* FIXME: Dynamic fee */ + peer->closing.our_fee + = fee_by_feerate(txsize, peer->dstate->config.closing_fee_rate); + + /* BOLT #2: + * The sender MUST set `close_fee` lower than or equal to the + * fee of the final commitment transaction, and MUST set + * `close_fee` to an even number of satoshis. + */ + maxfee = commit_tx_fee(peer->local.commit->tx, peer->anchor.satoshis); + if (peer->closing.our_fee > maxfee) { + /* This shouldn't happen: we never accept a commit fee + * less than the min_rate, which is greater than the + * closing_fee_rate. Also, our txsize estimate for + * the closing tx is 2 bytes smaller than the commitment tx. */ + log_unusual(peer->log, + "Closing fee %"PRIu64" exceeded commit fee %"PRIu64", reducing.", + peer->closing.our_fee, maxfee); + peer->closing.our_fee = maxfee; - /* 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; -} + /* This can happen if actual commit txfee is odd. */ + if (peer->closing.our_fee & 1) + peer->closing.our_fee--; + } + assert(!(peer->closing.our_fee & 1)); +} /* This is the io loop while we're clearing. */ static bool clearing_pkt_in(struct peer *peer, const Pkt *pkt) @@ -967,8 +1438,7 @@ static bool fulfill_onchain(struct peer *peer, struct htlc *htlc) fatal("Unknown HTLC to fulfill onchain"); } -static bool command_htlc_fulfill(struct peer *peer, - struct htlc *htlc) +static bool command_htlc_fulfill(struct peer *peer, struct htlc *htlc) { union htlc_staging stage; @@ -1194,27 +1664,6 @@ static void peer_disconnect(struct io_conn *conn, struct peer *peer) } } -bool htlcs_changestate(struct peer *peer, - const struct state_table *table, size_t n) -{ - struct htlc_map_iter it; - struct htlc *h; - bool changed = false; - - for (h = htlc_map_first(&peer->htlcs, &it); - h; - h = htlc_map_next(&peer->htlcs, &it)) { - size_t i; - for (i = 0; i < n; i++) { - if (h->state == table[i].from) { - htlc_changestate(h, table[i].from, table[i].to); - changed = true; - } - } - } - return changed; -} - static void do_commit(struct peer *peer, struct command *jsoncmd) { struct commit_info *ci; @@ -1309,19 +1758,6 @@ static void try_commit(struct peer *peer) } } -void remote_changes_pending(struct peer *peer) -{ - log_debug(peer->log, "remote_changes_pending: changes=%u", - peer->remote.staging_cstate->changes); - if (!peer->commit_timer) { - log_debug(peer->log, "remote_changes_pending: adding timer"); - peer->commit_timer = new_reltimer(peer->dstate, peer, - peer->dstate->config.commit_time, - try_commit, peer); - } else - log_debug(peer->log, "remote_changes_pending: timer already exists"); -} - struct commit_info *new_commit_info(const tal_t *ctx) { struct commit_info *ci = talz(ctx, struct commit_info); @@ -2094,14 +2530,6 @@ static enum watch_result our_htlc_spent(struct peer *peer, return DELETE_WATCH; } -static void our_htlc_failed(struct peer *peer, struct htlc *htlc) -{ - if (htlc->src) - command_htlc_fail(htlc->src->peer, htlc->src); - else - complete_pay_command(peer, htlc); -} - /* We've spent an HTLC output to get our funds back. There's still a * chance that they could also spend the HTLC output (using the preimage), * so we need to wait for some confirms. @@ -2227,18 +2655,6 @@ static void resolve_our_htlcs(struct peer *peer, } } -void our_htlc_fulfilled(struct peer *peer, struct htlc *htlc, - const struct rval *preimage) -{ - if (htlc->src) { - assert(!htlc->src->r); - htlc->src->r = tal_dup(htlc->src, struct rval, htlc->r); - command_htlc_fulfill(htlc->src->peer, htlc->src); - } else { - complete_pay_command(peer, htlc); - } -} - static enum watch_result their_htlc_depth(struct peer *peer, unsigned int depth, const struct sha256_double *txid, @@ -2689,17 +3105,6 @@ void peer_unwatch_anchor_depth(struct peer *peer, peer->anchor.watches->depthok = INPUT_NONE; } -uint64_t commit_tx_fee(const struct bitcoin_tx *commit, uint64_t anchor_satoshis) -{ - uint64_t i, total = 0; - - for (i = 0; i < commit->output_count; i++) - total += commit->output[i].amount; - - assert(anchor_satoshis >= total); - return anchor_satoshis - total; -} - struct bitcoin_tx *peer_create_close_tx(struct peer *peer, u64 fee) { struct channel_state cstate; @@ -2708,190 +3113,27 @@ struct bitcoin_tx *peer_create_close_tx(struct peer *peer, u64 fee) cstate = *peer->local.staging_cstate; if (!force_fee(&cstate, fee)) { log_unusual(peer->log, - "peer_create_close_tx: can't afford fee %"PRIu64, - fee); - return NULL; - } - - log_debug(peer->log, - "creating close-tx with fee %"PRIu64" amounts %u/%u to ", - fee, - cstate.side[OURS].pay_msat / 1000, - cstate.side[THEIRS].pay_msat / 1000); - log_add_struct(peer->log, "%s", struct pubkey, &peer->local.finalkey); - log_add_struct(peer->log, "/%s", struct pubkey, &peer->remote.finalkey); - - return create_close_tx(peer->dstate->secpctx, peer, - peer->closing.our_script, - peer->closing.their_script, - &peer->anchor.txid, - peer->anchor.index, - peer->anchor.satoshis, - cstate.side[OURS].pay_msat / 1000, - cstate.side[THEIRS].pay_msat / 1000); -} - -void peer_calculate_close_fee(struct peer *peer) -{ - /* Use actual worst-case length of close tx: based on BOLT#02's - * commitment tx numbers, but only 1 byte for output count */ - const uint64_t txsize = 41 + 221 + 10 + 32 + 32; - uint64_t maxfee; - - /* FIXME: Dynamic fee */ - peer->closing.our_fee - = fee_by_feerate(txsize, peer->dstate->config.closing_fee_rate); - - /* BOLT #2: - * The sender MUST set `close_fee` lower than or equal to the - * fee of the final commitment transaction, and MUST set - * `close_fee` to an even number of satoshis. - */ - maxfee = commit_tx_fee(peer->local.commit->tx, peer->anchor.satoshis); - if (peer->closing.our_fee > maxfee) { - /* This shouldn't happen: we never accept a commit fee - * less than the min_rate, which is greater than the - * closing_fee_rate. Also, our txsize estimate for - * the closing tx is 2 bytes smaller than the commitment tx. */ - log_unusual(peer->log, - "Closing fee %"PRIu64" exceeded commit fee %"PRIu64", reducing.", - peer->closing.our_fee, maxfee); - peer->closing.our_fee = maxfee; - - /* This can happen if actual commit txfee is odd. */ - if (peer->closing.our_fee & 1) - peer->closing.our_fee--; - } - assert(!(peer->closing.our_fee & 1)); -} - -void peer_unexpected_pkt(struct peer *peer, const Pkt *pkt) -{ - const char *p; - - log_unusual(peer->log, "Received unexpected pkt %u (%s)", - pkt->pkt_case, pkt_name(pkt->pkt_case)); - - if (pkt->pkt_case != PKT__PKT_ERROR) - return; - - /* Check packet for weird chars. */ - for (p = pkt->error->problem; *p; p++) { - if (cisprint(*p)) - continue; - - p = tal_hexstr(peer, pkt->error->problem, - strlen(pkt->error->problem)); - log_add(peer->log, "hex: %s", p); - tal_free(p); - return; - } - log_add(peer->log, "'%s'", pkt->error->problem); -} - -/* Create a bitcoin close tx, using last signature they sent. */ -const struct bitcoin_tx *bitcoin_close(struct peer *peer) -{ - struct bitcoin_tx *close_tx; - struct bitcoin_signature our_close_sig; - - close_tx = peer_create_close_tx(peer, peer->closing.their_fee); - - our_close_sig.stype = SIGHASH_ALL; - peer_sign_mutual_close(peer, close_tx, &our_close_sig.sig); - - close_tx->input[0].witness - = bitcoin_witness_2of2(close_tx->input, - peer->dstate->secpctx, - peer->closing.their_sig, - &our_close_sig, - &peer->remote.commitkey, - &peer->local.commitkey); - - return close_tx; -} - -/* Create a bitcoin spend tx (to spend our commit's outputs) */ -const struct bitcoin_tx *bitcoin_spend_ours(struct peer *peer) -{ - u8 *witnessscript; - const struct bitcoin_tx *commit = peer->local.commit->tx; - struct bitcoin_signature sig; - struct bitcoin_tx *tx; - unsigned int p2wsh_out; - uint64_t fee; - - /* The redeemscript for a commit tx is fairly complex. */ - witnessscript = bitcoin_redeem_secret_or_delay(peer, - peer->dstate->secpctx, - &peer->local.finalkey, - &peer->remote.locktime, - &peer->remote.finalkey, - &peer->local.commit->revocation_hash); - - /* Now, create transaction to spend it. */ - tx = bitcoin_tx(peer, 1, 1); - tx->input[0].txid = peer->local.commit->txid; - p2wsh_out = find_p2wsh_out(commit, witnessscript); - tx->input[0].index = p2wsh_out; - tx->input[0].sequence_number = bitcoin_nsequence(&peer->remote.locktime); - tx->input[0].amount = tal_dup(tx->input, u64, - &commit->output[p2wsh_out].amount); - - tx->output[0].script = scriptpubkey_p2sh(tx, - bitcoin_redeem_single(tx, - peer->dstate->secpctx, - &peer->local.finalkey)); - tx->output[0].script_length = tal_count(tx->output[0].script); - - /* Witness length can vary, due to DER encoding of sigs, but we - * use 176 from an example run. */ - assert(measure_tx_cost(tx) == 83 * 4); - - /* FIXME: Dynamic fees! */ - fee = fee_by_feerate(83 + 176 / 4, - peer->dstate->config.closing_fee_rate); - - /* FIXME: Fail gracefully in these cases (not worth collecting) */ - if (fee > commit->output[p2wsh_out].amount - || is_dust_amount(commit->output[p2wsh_out].amount - fee)) - fatal("Amount of %"PRIu64" won't cover fee %"PRIu64, - commit->output[p2wsh_out].amount, fee); - - tx->output[0].amount = commit->output[p2wsh_out].amount - fee; - - sig.stype = SIGHASH_ALL; - peer_sign_spend(peer, tx, witnessscript, &sig.sig); - - tx->input[0].witness = bitcoin_witness_secret(tx, - peer->dstate->secpctx, - NULL, 0, &sig, - witnessscript); - - return tx; -} - -/* Sign and return our commit tx */ -const struct bitcoin_tx *bitcoin_commit(struct peer *peer) -{ - struct bitcoin_signature sig; - - /* Can't be signed already, and can't have scriptsig! */ - assert(peer->local.commit->tx->input[0].script_length == 0); - assert(!peer->local.commit->tx->input[0].witness); - - sig.stype = SIGHASH_ALL; - peer_sign_ourcommit(peer, peer->local.commit->tx, &sig.sig); + "peer_create_close_tx: can't afford fee %"PRIu64, + fee); + return NULL; + } - peer->local.commit->tx->input[0].witness - = bitcoin_witness_2of2(peer->local.commit->tx->input, - peer->dstate->secpctx, - peer->local.commit->sig, - &sig, - &peer->remote.commitkey, - &peer->local.commitkey); + log_debug(peer->log, + "creating close-tx with fee %"PRIu64" amounts %u/%u to ", + fee, + cstate.side[OURS].pay_msat / 1000, + cstate.side[THEIRS].pay_msat / 1000); + log_add_struct(peer->log, "%s", struct pubkey, &peer->local.finalkey); + log_add_struct(peer->log, "/%s", struct pubkey, &peer->remote.finalkey); - return peer->local.commit->tx; + return create_close_tx(peer->dstate->secpctx, peer, + peer->closing.our_script, + peer->closing.their_script, + &peer->anchor.txid, + peer->anchor.index, + peer->anchor.satoshis, + cstate.side[OURS].pay_msat / 1000, + cstate.side[THEIRS].pay_msat / 1000); } /* Now we can create anchor tx. */ @@ -2959,241 +3201,6 @@ const struct bitcoin_tx *bitcoin_anchor(struct peer *peer) return peer->anchor.tx; } -void add_unacked(struct peer_visible_state *which, - const union htlc_staging *stage) -{ - size_t n = tal_count(which->commit->unacked_changes); - tal_resize(&which->commit->unacked_changes, n+1); - which->commit->unacked_changes[n] = *stage; -} - -void add_acked_changes(union htlc_staging **acked, - const union htlc_staging *changes) -{ - size_t n_acked, n_changes; - - n_acked = tal_count(*acked); - n_changes = tal_count(changes); - tal_resize(acked, n_acked + n_changes); - memcpy(*acked + n_acked, changes, n_changes * sizeof(*changes)); -} - -static const char *owner_name(enum channel_side side) -{ - return side == OURS ? "our" : "their"; -} - -static void route_htlc_onwards(struct peer *peer, - struct htlc *htlc, - u64 msatoshis, - const BitcoinPubkey *pb_id, - const u8 *rest_of_route) -{ - struct pubkey id; - struct peer *next; - - log_debug_struct(peer->log, "Forwarding HTLC %s", struct sha256, &htlc->rhash); - log_add(peer->log, " (id %"PRIu64")", htlc->id); - - if (!proto_to_pubkey(peer->dstate->secpctx, pb_id, &id)) { - log_unusual(peer->log, - "Malformed pubkey for HTLC %"PRIu64, htlc->id); - command_htlc_fail(peer, htlc); - return; - } - - next = find_peer(peer->dstate, &id); - if (!next || !next->nc) { - log_unusual(peer->log, "Can't route HTLC %"PRIu64": no %speer ", - htlc->id, next ? "ready " : ""); - log_add_struct(peer->log, "%s", struct pubkey, &id); - if (!peer->dstate->dev_never_routefail) - command_htlc_fail(peer, htlc); - return; - } - - /* Offered fee must be sufficient. */ - if (htlc->msatoshis - msatoshis < connection_fee(next->nc, msatoshis)) { - log_unusual(peer->log, - "Insufficient fee for HTLC %"PRIu64 - ": %"PRIi64" on %"PRIu64, - htlc->id, htlc->msatoshis - msatoshis, - msatoshis); - command_htlc_fail(peer, htlc); - return; - } - - log_debug_struct(peer->log, "HTLC forward to %s", - struct pubkey, next->id); - - /* This checks the HTLC itself is possible. */ - if (!command_htlc_add(next, msatoshis, - abs_locktime_to_blocks(&htlc->expiry) - - next->nc->delay, - &htlc->rhash, htlc, rest_of_route)) { - command_htlc_fail(peer, htlc); - return; - } -} - -static void their_htlc_added(struct peer *peer, struct htlc *htlc) -{ - RouteStep *step; - const u8 *rest_of_route; - struct payment *payment; - - if (abs_locktime_is_seconds(&htlc->expiry)) { - log_unusual(peer->log, "HTLC %"PRIu64" is in seconds", htlc->id); - command_htlc_fail(peer, htlc); - return; - } - - if (abs_locktime_to_blocks(&htlc->expiry) <= - get_block_height(peer->dstate) + peer->dstate->config.min_htlc_expiry) { - log_unusual(peer->log, "HTLC %"PRIu64" expires too soon:" - " block %u", - htlc->id, abs_locktime_to_blocks(&htlc->expiry)); - command_htlc_fail(peer, htlc); - return; - } - - if (abs_locktime_to_blocks(&htlc->expiry) > - get_block_height(peer->dstate) + peer->dstate->config.max_htlc_expiry) { - log_unusual(peer->log, "HTLC %"PRIu64" expires too far:" - " block %u", - htlc->id, abs_locktime_to_blocks(&htlc->expiry)); - command_htlc_fail(peer, htlc); - return; - } - - step = onion_unwrap(peer, htlc->routing, tal_count(htlc->routing), - &rest_of_route); - if (!step) { - log_unusual(peer->log, "Bad onion, failing HTLC %"PRIu64, - htlc->id); - command_htlc_fail(peer, htlc); - return; - } - - switch (step->next_case) { - case ROUTE_STEP__NEXT_END: - payment = find_payment(peer->dstate, &htlc->rhash); - if (!payment) { - log_unusual(peer->log, "No payment for HTLC %"PRIu64, - htlc->id); - log_add_struct(peer->log, " rhash=%s", - struct sha256, &htlc->rhash); - if (unlikely(!peer->dstate->dev_never_routefail)) - command_htlc_fail(peer, htlc); - goto free_rest; - } - - if (htlc->msatoshis != payment->msatoshis) { - log_unusual(peer->log, "Short payment for HTLC %"PRIu64 - ": %"PRIu64" not %"PRIu64 " satoshi!", - htlc->id, - htlc->msatoshis, - payment->msatoshis); - command_htlc_fail(peer, htlc); - return; - } - - log_info(peer->log, "Immediately resolving HTLC %"PRIu64, - htlc->id); - - assert(!htlc->r); - htlc->r = tal_dup(htlc, struct rval, &payment->r); - command_htlc_fulfill(peer, htlc); - goto free_rest; - - case ROUTE_STEP__NEXT_BITCOIN: - route_htlc_onwards(peer, htlc, step->amount, step->bitcoin, - rest_of_route); - goto free_rest; - default: - log_info(peer->log, "Unknown step type %u", step->next_case); - command_htlc_fail(peer, htlc); - goto free_rest; - } - -free_rest: - tal_free(rest_of_route); -} - -/* When changes are committed to. */ -void peer_both_committed_to(struct peer *peer, - const union htlc_staging *changes, - enum channel_side side) -{ - size_t i, n = tal_count(changes); - - /* All this, simply for debugging. */ - for (i = 0; i < n; i++) { - u64 htlc_id; - const char *type, *owner; - - switch (changes[i].type) { - case HTLC_ADD: - type = "ADD"; - htlc_id = changes[i].add.htlc->id; - owner = owner_name(side); - assert(cstate_htlc_by_id(peer->remote.commit->cstate, htlc_id, - side)); - assert(cstate_htlc_by_id(peer->local.commit->cstate, htlc_id, - side)); - goto print; - case HTLC_FAIL: - type = "FAIL"; - htlc_id = changes[i].fail.htlc->id; - owner = owner_name(!side); - assert(!cstate_htlc_by_id(peer->remote.commit->cstate, htlc_id, - !side)); - assert(!cstate_htlc_by_id(peer->local.commit->cstate, htlc_id, - !side)); - assert(cstate_htlc_by_id(peer->remote.commit->prev->cstate, - htlc_id, !side) - || cstate_htlc_by_id(peer->local.commit->prev->cstate, - htlc_id, !side)); - goto print; - case HTLC_FULFILL: - type = "FULFILL"; - htlc_id = changes[i].fulfill.htlc->id; - owner = owner_name(!side); - assert(!cstate_htlc_by_id(peer->remote.commit->cstate, htlc_id, - !side)); - assert(!cstate_htlc_by_id(peer->local.commit->cstate, htlc_id, - !side)); - assert(cstate_htlc_by_id(peer->remote.commit->prev->cstate, - htlc_id, !side) - || cstate_htlc_by_id(peer->local.commit->prev->cstate, - htlc_id, !side)); - goto print; - } - abort(); - print: - log_debug(peer->log, "Both committed to %s of %s HTLC %"PRIu64, - type, owner, htlc_id); - } - - /* We actually only respond to changes they made. */ - if (side == OURS) - return; - - for (i = 0; i < n; i++) { - switch (changes[i].type) { - case HTLC_ADD: - their_htlc_added(peer, changes[i].add.htlc); - break; - case HTLC_FULFILL: - /* We handled this as soon as we got it. */ - break; - case HTLC_FAIL: - our_htlc_failed(peer, changes[i].fail.htlc); - break; - } - } -} - /* Sets up the initial cstate and commit tx for both nodes: false if * insufficient funds. */ bool setup_first_commit(struct peer *peer) diff --git a/daemon/peer.h b/daemon/peer.h index 243e2e6cf..24e79268f 100644 --- a/daemon/peer.h +++ b/daemon/peer.h @@ -224,35 +224,9 @@ struct peer *find_peer(struct lightningd_state *dstate, const struct pubkey *id) /* Populates very first peer->{local,remote}.commit->{tx,cstate} */ bool setup_first_commit(struct peer *peer); -/* Set up timer: we have something we can commit. */ -void remote_changes_pending(struct peer *peer); - -/* Add this unacked change */ -void add_unacked(struct peer_visible_state *which, - const union htlc_staging *stage); - -/* These unacked changes are now acked; add them to acked set. */ -void add_acked_changes(union htlc_staging **acked, - const union htlc_staging *changes); - -/* Both sides are committed to these changes they proposed. */ -void peer_both_committed_to(struct peer *peer, - const union htlc_staging *changes, enum channel_side side); - /* Allocate a new commit_info struct. */ struct commit_info *new_commit_info(const tal_t *ctx); -struct state_table { - enum htlc_state from, to; -}; -bool htlcs_changestate(struct peer *peer, - const struct state_table *table, size_t n); -void apply_changeset(struct peer *peer, - struct peer_visible_state *which, - enum channel_side side, - const union htlc_staging *changes, - size_t num_changes); - /* Freeing removes from map, too */ struct htlc *peer_new_htlc(struct peer *peer, u64 id, @@ -270,19 +244,12 @@ struct htlc *command_htlc_add(struct peer *peer, u64 msatoshis, struct htlc *src, const u8 *route); -/* Peer has recieved revocation. */ -void peer_update_complete(struct peer *peer); +void peer_unexpected_pkt(struct peer *peer, const Pkt *pkt); /* Peer has completed open, or problem (if non-NULL). */ void peer_open_complete(struct peer *peer, const char *problem); struct bitcoin_tx *peer_create_close_tx(struct peer *peer, u64 fee); -uint64_t commit_tx_fee(const struct bitcoin_tx *commit, - uint64_t anchor_satoshis); - -void our_htlc_fulfilled(struct peer *peer, struct htlc *htlc, - const struct rval *preimage); - void cleanup_peers(struct lightningd_state *dstate); #endif /* LIGHTNING_DAEMON_PEER_H */ diff --git a/state.h b/state.h index d6f5a2436..495bca072 100644 --- a/state.h +++ b/state.h @@ -115,29 +115,14 @@ void peer_unwatch_anchor_depth(struct peer *peer, enum state_input depthok, enum state_input timeout); -/** - * peer_calculate_close_fee: figure out what the fee for closing is. - * @peer: the state data for this peer. - */ -void peer_calculate_close_fee(struct peer *peer); - /* Start creation of the bitcoin anchor tx. */ void bitcoin_create_anchor(struct peer *peer, enum state_input done); -/* We didn't end up broadcasting the anchor: release the utxos. - * If done != INPUT_NONE, remove existing create_anchor too. */ -void bitcoin_release_anchor(struct peer *peer, enum state_input done); - /* Get the bitcoin anchor tx. */ const struct bitcoin_tx *bitcoin_anchor(struct peer *peer); -/* Create a bitcoin close tx. */ -const struct bitcoin_tx *bitcoin_close(struct peer *peer); - -/* Create a bitcoin spend tx (to spend our commit's outputs) */ -const struct bitcoin_tx *bitcoin_spend_ours(struct peer *peer); - -/* Create our commit tx */ -const struct bitcoin_tx *bitcoin_commit(struct peer *peer); +/* We didn't end up broadcasting the anchor: release the utxos. + * If done != INPUT_NONE, remove existing create_anchor too. */ +void bitcoin_release_anchor(struct peer *peer, enum state_input done); #endif /* LIGHTNING_STATE_H */