diff --git a/daemon/packets.c b/daemon/packets.c index 4366cf9fa..a5aceb04b 100644 --- a/daemon/packets.c +++ b/daemon/packets.c @@ -69,24 +69,10 @@ static void queue_pkt(struct peer *peer, Pkt__PktCase type, const void *msg) queue_raw_pkt(peer, make_pkt(peer, type, msg)); } -static struct commit_info *new_commit_info(const tal_t *ctx) -{ - struct commit_info *ci = talz(ctx, struct commit_info); - ci->unacked_changes = tal_arr(ci, union htlc_staging, 0); - ci->acked_changes = tal_arr(ci, union htlc_staging, 0); - return ci; -} - void queue_pkt_open(struct peer *peer, OpenChannel__AnchorOffer anchor) { OpenChannel *o = tal(peer, OpenChannel); - /* Set up out commit info now: rest gets done in setup_first_commit - * once anchor is established. */ - peer->local.commit = new_commit_info(peer); - peer->local.commit->revocation_hash = peer->local.next_revocation_hash; - peer_get_revocation_hash(peer, 1, &peer->local.next_revocation_hash); - open_channel__init(o); o->revocation_hash = sha256_to_proto(o, &peer->local.commit->revocation_hash); o->next_revocation_hash = sha256_to_proto(o, &peer->local.next_revocation_hash); @@ -120,14 +106,6 @@ void queue_pkt_anchor(struct peer *peer) a->output_index = peer->anchor.index; a->amount = peer->anchor.satoshis; - /* This shouldn't happen! */ - if (!setup_first_commit(peer)) { - queue_pkt_err(peer, - pkt_err(peer, - "Own anchor has insufficient funds")); - return; - } - queue_pkt(peer, PKT__PKT_OPEN_ANCHOR, a); } @@ -137,16 +115,6 @@ void queue_pkt_open_commit_sig(struct peer *peer) open_commit_sig__init(s); - log_debug_struct(peer->log, "Creating sig for %s", - struct bitcoin_tx, peer->remote.commit->tx); - log_add_struct(peer->log, " using key %s", - struct pubkey, &peer->local.commitkey); - - peer->remote.commit->sig = tal(peer->remote.commit, - struct bitcoin_signature); - peer->remote.commit->sig->stype = SIGHASH_ALL; - peer_sign_theircommit(peer, peer->remote.commit->tx, - &peer->remote.commit->sig->sig); s->sig = signature_to_proto(s, peer->dstate->secpctx, &peer->remote.commit->sig->sig); @@ -164,7 +132,6 @@ void queue_pkt_open_complete(struct peer *peer) void queue_pkt_htlc_add(struct peer *peer, struct htlc *htlc) { UpdateAddHtlc *u = tal(peer, UpdateAddHtlc); - union htlc_staging stage; update_add_htlc__init(u); @@ -180,49 +147,16 @@ void queue_pkt_htlc_add(struct peer *peer, struct htlc *htlc) 0); u->route->info.len = tal_count(u->route->info.data); - /* BOLT #2: - * - * The sending node MUST add the HTLC addition to the unacked - * changeset for its remote commitment - */ - if (!cstate_add_htlc(peer->remote.staging_cstate, htlc, OURS)) - fatal("Could not add HTLC?"); - - stage.add.add = HTLC_ADD; - stage.add.htlc = htlc; - add_unacked(&peer->remote, &stage); - - remote_changes_pending(peer); - queue_pkt(peer, PKT__PKT_UPDATE_ADD_HTLC, u); } -void queue_pkt_htlc_fulfill(struct peer *peer, struct htlc *htlc, - const struct rval *r) +void queue_pkt_htlc_fulfill(struct peer *peer, struct htlc *htlc) { UpdateFulfillHtlc *f = tal(peer, UpdateFulfillHtlc); - union htlc_staging stage; update_fulfill_htlc__init(f); f->id = htlc->id; - f->r = rval_to_proto(f, r); - - /* BOLT #2: - * - * The sending node MUST add the HTLC fulfill/fail to the - * unacked changeset for its remote commitment - */ - assert(cstate_htlc_by_id(peer->remote.staging_cstate, f->id, THEIRS) - == htlc); - cstate_fulfill_htlc(peer->remote.staging_cstate, htlc, THEIRS); - - stage.fulfill.fulfill = HTLC_FULFILL; - stage.fulfill.htlc = htlc; - stage.fulfill.r = *r; - add_unacked(&peer->remote, &stage); - htlc_changestate(htlc, RCVD_ADD_ACK_REVOCATION, SENT_REMOVE_HTLC); - - remote_changes_pending(peer); + f->r = rval_to_proto(f, htlc->r); queue_pkt(peer, PKT__PKT_UPDATE_FULFILL_HTLC, f); } @@ -230,7 +164,6 @@ void queue_pkt_htlc_fulfill(struct peer *peer, struct htlc *htlc, void queue_pkt_htlc_fail(struct peer *peer, struct htlc *htlc) { UpdateFailHtlc *f = tal(peer, UpdateFailHtlc); - union htlc_staging stage; update_fail_htlc__init(f); f->id = htlc->id; @@ -239,218 +172,39 @@ void queue_pkt_htlc_fail(struct peer *peer, struct htlc *htlc) f->reason = tal(f, FailReason); fail_reason__init(f->reason); - /* BOLT #2: - * - * The sending node MUST add the HTLC fulfill/fail to the - * unacked changeset for its remote commitment - */ - assert(cstate_htlc_by_id(peer->remote.staging_cstate, f->id, THEIRS) - == htlc); - cstate_fail_htlc(peer->remote.staging_cstate, htlc, THEIRS); - - stage.fail.fail = HTLC_FAIL; - stage.fail.htlc = htlc; - add_unacked(&peer->remote, &stage); - htlc_changestate(htlc, RCVD_ADD_ACK_REVOCATION, SENT_REMOVE_HTLC); - - remote_changes_pending(peer); queue_pkt(peer, PKT__PKT_UPDATE_FAIL_HTLC, f); } -struct state_table { - enum htlc_state from, to; -}; - -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; - - 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; -} - /* OK, we're sending a signature for their pending changes. */ void queue_pkt_commit(struct peer *peer) { UpdateCommit *u = tal(peer, UpdateCommit); - struct commit_info *ci = new_commit_info(peer); - static const struct state_table changes[] = { - { SENT_ADD_HTLC, SENT_ADD_COMMIT }, - { SENT_REMOVE_REVOCATION, SENT_REMOVE_ACK_COMMIT }, - { SENT_ADD_REVOCATION, SENT_ADD_ACK_COMMIT}, - { SENT_REMOVE_HTLC, SENT_REMOVE_COMMIT} - }; - - /* BOLT #2: - * - * A node MUST NOT send an `update_commit` message which does - * not include any updates. - */ - if (!htlcs_changestate(peer, changes, ARRAY_SIZE(changes))) - fatal("sent commit with no changes"); - - /* Create new commit info for this commit tx. */ - ci->prev = peer->remote.commit; - ci->commit_num = ci->prev->commit_num + 1; - ci->revocation_hash = peer->remote.next_revocation_hash; - /* BOLT #2: - * - * A sending node MUST apply all remote acked and unacked - * changes except unacked fee changes to the remote commitment - * before generating `sig`. */ - ci->cstate = copy_cstate(ci, peer->remote.staging_cstate); - ci->tx = create_commit_tx(ci, peer, &ci->revocation_hash, - ci->cstate, REMOTE, &ci->map); - bitcoin_txid(ci->tx, &ci->txid); - - log_debug(peer->log, "Signing tx for %u/%u msatoshis, %zu/%zu 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)); - log_add_struct(peer->log, " (txid %s)", struct sha256_double, &ci->txid); - - /* BOLT #2: - * - * A node MUST NOT send an `update_commit` message which does - * not include any updates. - */ - assert(ci->prev->cstate->changes != ci->cstate->changes); - - ci->sig = tal(ci, struct bitcoin_signature); - ci->sig->stype = SIGHASH_ALL; - peer_sign_theircommit(peer, ci->tx, &ci->sig->sig); - - /* Switch to the new commitment. */ - peer->remote.commit = ci; /* Now send message */ update_commit__init(u); - u->sig = signature_to_proto(u, peer->dstate->secpctx, &ci->sig->sig); + u->sig = signature_to_proto(u, peer->dstate->secpctx, + &peer->remote.commit->sig->sig); queue_pkt(peer, PKT__PKT_UPDATE_COMMIT, u); } -/* At revocation time, we apply the changeset to the other side. */ -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; - - for (i = 0; i < num_changes; i++) { - switch (changes[i].type) { - case HTLC_ADD: - htlc = cstate_htlc_by_id(which->staging_cstate, - changes[i].add.htlc->id, side); - if (htlc) - fatal("Can't add duplicate HTLC id %"PRIu64, - changes[i].add.htlc->id); - if (!cstate_add_htlc(which->staging_cstate, - changes[i].add.htlc, - side)) - fatal("Adding HTLC to %s failed", - side == OURS ? "ours" : "theirs"); - continue; - case HTLC_FAIL: - htlc = cstate_htlc_by_id(which->staging_cstate, - changes[i].fail.htlc->id, - !side); - if (!htlc) - fatal("Can't fail non-exisent HTLC id %"PRIu64, - changes[i].fail.htlc->id); - cstate_fail_htlc(which->staging_cstate, htlc, !side); - continue; - case HTLC_FULFILL: - htlc = cstate_htlc_by_id(which->staging_cstate, - changes[i].fulfill.htlc->id, - !side); - if (!htlc) - fatal("Can't fulfill non-exisent HTLC id %"PRIu64, - changes[i].fulfill.htlc->id); - cstate_fulfill_htlc(which->staging_cstate, htlc, !side); - continue; - } - abort(); - } -} /* Send a preimage for the old commit tx. The one we've just committed to is * in peer->local.commit. */ -void queue_pkt_revocation(struct peer *peer) +void queue_pkt_revocation(struct peer *peer, + const struct sha256 *preimage, + const struct sha256 *next_hash) { UpdateRevocation *u = tal(peer, UpdateRevocation); - struct commit_info *ci; - static const struct state_table changes[] = { - { RCVD_ADD_ACK_COMMIT, SENT_ADD_ACK_REVOCATION }, - { RCVD_REMOVE_COMMIT, SENT_REMOVE_REVOCATION }, - { RCVD_ADD_COMMIT, SENT_ADD_REVOCATION }, - { RCVD_REMOVE_ACK_COMMIT, SENT_REMOVE_ACK_REVOCATION } - }; update_revocation__init(u); - assert(peer->local.commit); - ci = peer->local.commit->prev; - assert(ci); - assert(!ci->revocation_preimage); - - /* We have their signature on the current one, right? */ - assert(peer->local.commit->sig); - - if (!htlcs_changestate(peer, changes, ARRAY_SIZE(changes))) - fatal("sent revoke with no changes"); - - ci->revocation_preimage = tal(ci, struct sha256); - peer_get_revocation_preimage(peer, ci->commit_num, - ci->revocation_preimage); - - u->revocation_preimage = sha256_to_proto(u, ci->revocation_preimage); - - u->next_revocation_hash = sha256_to_proto(u, - &peer->local.next_revocation_hash); + u->revocation_preimage + = sha256_to_proto(u, peer->local.commit->prev->revocation_preimage); + u->next_revocation_hash + = sha256_to_proto(u, &peer->local.next_revocation_hash); queue_pkt(peer, PKT__PKT_UPDATE_REVOCATION, u); - - /* BOLT #2: - * - * The node sending `update_revocation` MUST add the local unacked - * changes to the set of remote acked changes. - */ - /* Note: this means the unacked changes as of the commit we're - * revoking */ - add_acked_changes(&peer->remote.commit->acked_changes, ci->unacked_changes); - apply_changeset(peer, &peer->remote, THEIRS, - ci->unacked_changes, tal_count(ci->unacked_changes)); - - if (tal_count(ci->unacked_changes)) - remote_changes_pending(peer); - - /* We should never look at this again. */ - ci->unacked_changes = tal_free(ci->unacked_changes); - - /* That revocation has committed us to changes in the current commitment. - * Any acked changes come from their commitment, so those are now committed - * by both of us. - */ - peer_both_committed_to(peer, ci->acked_changes, OURS); } Pkt *pkt_err(struct peer *peer, const char *msg, ...) diff --git a/daemon/peer.c b/daemon/peer.c index 427a261a5..825b2e06c 100644 --- a/daemon/peer.c +++ b/daemon/peer.c @@ -205,6 +205,53 @@ static bool peer_received_unexpected_pkt(struct peer *peer, const Pkt *pkt) return peer_comms_err(peer, pkt_err_unexpected(peer, 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) +{ + size_t i; + struct htlc *htlc; + + for (i = 0; i < num_changes; i++) { + switch (changes[i].type) { + case HTLC_ADD: + htlc = cstate_htlc_by_id(which->staging_cstate, + changes[i].add.htlc->id, side); + if (htlc) + fatal("Can't add duplicate HTLC id %"PRIu64, + changes[i].add.htlc->id); + if (!cstate_add_htlc(which->staging_cstate, + changes[i].add.htlc, + side)) + fatal("Adding HTLC to %s failed", + side == OURS ? "ours" : "theirs"); + continue; + case HTLC_FAIL: + htlc = cstate_htlc_by_id(which->staging_cstate, + changes[i].fail.htlc->id, + !side); + if (!htlc) + fatal("Can't fail non-exisent HTLC id %"PRIu64, + changes[i].fail.htlc->id); + cstate_fail_htlc(which->staging_cstate, htlc, !side); + continue; + case HTLC_FULFILL: + htlc = cstate_htlc_by_id(which->staging_cstate, + changes[i].fulfill.htlc->id, + !side); + if (!htlc) + fatal("Can't fulfill non-exisent HTLC id %"PRIu64, + changes[i].fulfill.htlc->id); + cstate_fulfill_htlc(which->staging_cstate, htlc, !side); + continue; + } + abort(); + } +} + /* This is the io loop while we're negotiating closing tx. */ static bool closing_pkt_in(struct peer *peer, const Pkt *pkt) { @@ -317,6 +364,65 @@ static bool closing_pkt_in(struct peer *peer, const Pkt *pkt) return true; } +/* We can get update_commit in both normal and clearing states. */ +static Pkt *handle_pkt_commit(struct peer *peer, const Pkt *pkt) +{ + Pkt *err; + struct commit_info *ci; + static const struct state_table changes[] = { + { RCVD_ADD_ACK_COMMIT, SENT_ADD_ACK_REVOCATION }, + { RCVD_REMOVE_COMMIT, SENT_REMOVE_REVOCATION }, + { RCVD_ADD_COMMIT, SENT_ADD_REVOCATION }, + { RCVD_REMOVE_ACK_COMMIT, SENT_REMOVE_ACK_REVOCATION } + }; + + err = accept_pkt_commit(peer, pkt); + if (err) + return err; + + assert(peer->local.commit); + ci = peer->local.commit->prev; + assert(ci); + assert(!ci->revocation_preimage); + + /* We have their signature on the current one, right? */ + assert(peer->local.commit->sig); + + if (!htlcs_changestate(peer, changes, ARRAY_SIZE(changes))) + fatal("sent revoke with no changes"); + + ci->revocation_preimage = tal(ci, struct sha256); + peer_get_revocation_preimage(peer, ci->commit_num, + ci->revocation_preimage); + + /* BOLT #2: + * + * The node sending `update_revocation` MUST add the local unacked + * changes to the set of remote acked changes. + */ + /* Note: this means the unacked changes as of the commit we're + * revoking */ + add_acked_changes(&peer->remote.commit->acked_changes, ci->unacked_changes); + apply_changeset(peer, &peer->remote, THEIRS, + ci->unacked_changes, tal_count(ci->unacked_changes)); + + if (tal_count(ci->unacked_changes)) + remote_changes_pending(peer); + + /* We should never look at this again. */ + ci->unacked_changes = tal_free(ci->unacked_changes); + + /* That revocation has committed us to changes in the current commitment. + * Any acked changes come from their commitment, so those are now committed + * by both of us. + */ + peer_both_committed_to(peer, ci->acked_changes, OURS); + + queue_pkt_revocation(peer, ci->revocation_preimage, + &peer->local.next_revocation_hash); + return NULL; +} + /* This is the io loop while we're clearing. */ static bool clearing_pkt_in(struct peer *peer, const Pkt *pkt) { @@ -366,9 +472,7 @@ static bool clearing_pkt_in(struct peer *peer, const Pkt *pkt) err = accept_pkt_htlc_fail(peer, pkt); break; case PKT__PKT_UPDATE_COMMIT: - err = accept_pkt_commit(peer, pkt); - if (!err) - queue_pkt_revocation(peer); + err = handle_pkt_commit(peer, pkt); break; case PKT__PKT_ERROR: peer_unexpected_pkt(peer, pkt); @@ -450,9 +554,7 @@ static bool normal_pkt_in(struct peer *peer, const Pkt *pkt) break; case PKT_UPDATE_COMMIT: - err = accept_pkt_commit(peer, pkt); - if (!err) - queue_pkt_revocation(peer); + err = handle_pkt_commit(peer, pkt); break; case PKT_CLOSE_CLEARING: @@ -631,10 +733,28 @@ static const struct bitcoin_tx *htlc_fulfill_tx(const struct peer *peer, /* FIXME: Reason! */ static bool command_htlc_fail(struct peer *peer, struct htlc *htlc) { + union htlc_staging stage; + /* If onchain, nothing we can do. */ if (!state_can_remove_htlc(peer->state)) return false; + /* BOLT #2: + * + * The sending node MUST add the HTLC fulfill/fail to the + * unacked changeset for its remote commitment + */ + assert(cstate_htlc_by_id(peer->remote.staging_cstate, htlc->id, THEIRS) + == htlc); + cstate_fail_htlc(peer->remote.staging_cstate, htlc, THEIRS); + + stage.fail.fail = HTLC_FAIL; + stage.fail.htlc = htlc; + add_unacked(&peer->remote, &stage); + htlc_changestate(htlc, RCVD_ADD_ACK_REVOCATION, SENT_REMOVE_HTLC); + + remote_changes_pending(peer); + queue_pkt_htlc_fail(peer, htlc); return true; } @@ -668,6 +788,8 @@ static bool command_htlc_fulfill(struct peer *peer, struct htlc *htlc, const struct rval *r) { + union htlc_staging stage; + assert(!htlc->r); htlc->r = tal_dup(htlc, struct rval, r); @@ -679,7 +801,24 @@ static bool command_htlc_fulfill(struct peer *peer, if (!state_can_remove_htlc(peer->state)) return false; - queue_pkt_htlc_fulfill(peer, htlc, r); + /* BOLT #2: + * + * The sending node MUST add the HTLC fulfill/fail to the + * unacked changeset for its remote commitment + */ + assert(cstate_htlc_by_id(peer->remote.staging_cstate, htlc->id, THEIRS) + == htlc); + cstate_fulfill_htlc(peer->remote.staging_cstate, htlc, THEIRS); + + stage.fulfill.fulfill = HTLC_FULFILL; + stage.fulfill.htlc = htlc; + stage.fulfill.r = *r; + add_unacked(&peer->remote, &stage); + htlc_changestate(htlc, RCVD_ADD_ACK_REVOCATION, SENT_REMOVE_HTLC); + + remote_changes_pending(peer); + + queue_pkt_htlc_fulfill(peer, htlc); return true; } @@ -692,6 +831,7 @@ struct htlc *command_htlc_add(struct peer *peer, u64 msatoshis, struct channel_state *cstate; struct abs_locktime locktime; struct htlc *htlc; + union htlc_staging stage; if (!blocks_to_abs_locktime(expiry, &locktime)) { log_unusual(peer->log, "add_htlc: fail: bad expiry %u", expiry); @@ -755,6 +895,20 @@ struct htlc *command_htlc_add(struct peer *peer, u64 msatoshis, } tal_free(cstate); + /* BOLT #2: + * + * The sending node MUST add the HTLC addition to the unacked + * changeset for its remote commitment + */ + if (!cstate_add_htlc(peer->remote.staging_cstate, htlc, OURS)) + fatal("Could not add HTLC?"); + + stage.add.add = HTLC_ADD; + stage.add.htlc = htlc; + add_unacked(&peer->remote, &stage); + + remote_changes_pending(peer); + queue_pkt_htlc_add(peer, htlc); /* Make sure we never offer the same one twice. */ @@ -861,8 +1015,37 @@ 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; + static const struct state_table changes[] = { + { SENT_ADD_HTLC, SENT_ADD_COMMIT }, + { SENT_REMOVE_REVOCATION, SENT_REMOVE_ACK_COMMIT }, + { SENT_ADD_REVOCATION, SENT_ADD_ACK_COMMIT}, + { SENT_REMOVE_HTLC, SENT_REMOVE_COMMIT} + }; + /* We can have changes we suggested, or changes they suggested. */ if (!peer_uncommitted_changes(peer)) { log_debug(peer->log, "do_commit: no changes to commit"); @@ -877,6 +1060,51 @@ static void do_commit(struct peer *peer, struct command *jsoncmd) assert(!peer->commit_jsoncmd); peer->commit_jsoncmd = jsoncmd; + ci = new_commit_info(peer); + + /* BOLT #2: + * + * A node MUST NOT send an `update_commit` message which does + * not include any updates. + */ + if (!htlcs_changestate(peer, changes, ARRAY_SIZE(changes))) + fatal("sent commit with no changes"); + + /* Create new commit info for this commit tx. */ + ci->prev = peer->remote.commit; + ci->commit_num = ci->prev->commit_num + 1; + ci->revocation_hash = peer->remote.next_revocation_hash; + /* BOLT #2: + * + * A sending node MUST apply all remote acked and unacked + * changes except unacked fee changes to the remote commitment + * before generating `sig`. */ + ci->cstate = copy_cstate(ci, peer->remote.staging_cstate); + ci->tx = create_commit_tx(ci, peer, &ci->revocation_hash, + ci->cstate, REMOTE, &ci->map); + bitcoin_txid(ci->tx, &ci->txid); + + log_debug(peer->log, "Signing tx for %u/%u msatoshis, %zu/%zu 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)); + log_add_struct(peer->log, " (txid %s)", struct sha256_double, &ci->txid); + + /* BOLT #2: + * + * A node MUST NOT send an `update_commit` message which does + * not include any updates. + */ + assert(ci->prev->cstate->changes != ci->cstate->changes); + + ci->sig = tal(ci, struct bitcoin_signature); + ci->sig->stype = SIGHASH_ALL; + peer_sign_theircommit(peer, ci->tx, &ci->sig->sig); + + /* Switch to the new commitment. */ + peer->remote.commit = ci; + queue_pkt_commit(peer); if (peer->state == STATE_CLEARING) { set_peer_state(peer, STATE_CLEARING_COMMITTING, __func__); @@ -915,6 +1143,14 @@ void remote_changes_pending(struct peer *peer) 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); + ci->unacked_changes = tal_arr(ci, union htlc_staging, 0); + ci->acked_changes = tal_arr(ci, union htlc_staging, 0); + return ci; +} + static struct peer *new_peer(struct lightningd_state *dstate, struct io_conn *conn, int addr_type, int addr_protocol, diff --git a/daemon/peer.h b/daemon/peer.h index 7d3a031ee..243e2e6cf 100644 --- a/daemon/peer.h +++ b/daemon/peer.h @@ -239,6 +239,20 @@ void add_acked_changes(union htlc_staging **acked, 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, diff --git a/state.c b/state.c index f99f7d503..e404aeab0 100644 --- a/state.c +++ b/state.c @@ -1,8 +1,7 @@ #include #include -#ifndef TEST_STATE_COVERAGE #include -#endif +#include #include #include @@ -22,6 +21,18 @@ static void queue_tx_broadcast(const struct bitcoin_tx **broadcast, *broadcast = tx; } +static void send_open_pkt(struct peer *peer, + OpenChannel__AnchorOffer anchor) +{ + /* Set up out commit info now: rest gets done in setup_first_commit + * once anchor is established. */ + peer->local.commit = new_commit_info(peer); + peer->local.commit->revocation_hash = peer->local.next_revocation_hash; + peer_get_revocation_hash(peer, 1, &peer->local.next_revocation_hash); + + queue_pkt_open(peer, anchor); +} + enum state state(struct peer *peer, const enum state_input input, const Pkt *pkt, @@ -37,13 +48,13 @@ enum state state(struct peer *peer, */ case STATE_INIT: if (input_is(input, CMD_OPEN_WITH_ANCHOR)) { - queue_pkt_open(peer, - OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR); + send_open_pkt(peer, + OPEN_CHANNEL__ANCHOR_OFFER__WILL_CREATE_ANCHOR); return next_state(peer, input, STATE_OPEN_WAIT_FOR_OPEN_WITHANCHOR); } else if (input_is(input, CMD_OPEN_WITHOUT_ANCHOR)) { - queue_pkt_open(peer, - OPEN_CHANNEL__ANCHOR_OFFER__WONT_CREATE_ANCHOR); + send_open_pkt(peer, + OPEN_CHANNEL__ANCHOR_OFFER__WONT_CREATE_ANCHOR); return next_state(peer, input, STATE_OPEN_WAIT_FOR_OPEN_NOANCHOR); } @@ -78,6 +89,13 @@ enum state state(struct peer *peer, break; case STATE_OPEN_WAIT_FOR_ANCHOR_CREATE: if (input_is(input, BITCOIN_ANCHOR_CREATED)) { + /* This shouldn't happen! */ + if (!setup_first_commit(peer)) { + err = pkt_err(peer, + "Own anchor has insufficient funds"); + peer_open_complete(peer, err->error->problem); + goto err_breakdown; + } queue_pkt_anchor(peer); return next_state(peer, input, STATE_OPEN_WAIT_FOR_COMMIT_SIG); @@ -94,6 +112,18 @@ enum state state(struct peer *peer, peer_open_complete(peer, err->error->problem); goto err_breakdown; } + log_debug_struct(peer->log, "Creating sig for %s", + struct bitcoin_tx, + peer->remote.commit->tx); + log_add_struct(peer->log, " using key %s", + struct pubkey, &peer->local.commitkey); + + peer->remote.commit->sig = tal(peer->remote.commit, + struct bitcoin_signature); + peer->remote.commit->sig->stype = SIGHASH_ALL; + peer_sign_theircommit(peer, peer->remote.commit->tx, + &peer->remote.commit->sig->sig); + queue_pkt_open_commit_sig(peer); peer_watch_anchor(peer, BITCOIN_ANCHOR_DEPTHOK, diff --git a/state.h b/state.h index 031603b32..2810d7fd8 100644 --- a/state.h +++ b/state.h @@ -101,11 +101,12 @@ void queue_pkt_anchor(struct peer *peer); void queue_pkt_open_commit_sig(struct peer *peer); void queue_pkt_open_complete(struct peer *peer); void queue_pkt_htlc_add(struct peer *peer, struct htlc *htlc); -void queue_pkt_htlc_fulfill(struct peer *peer, struct htlc *htlc, - const struct rval *r); +void queue_pkt_htlc_fulfill(struct peer *peer, struct htlc *htlc); void queue_pkt_htlc_fail(struct peer *peer, struct htlc *htlc); void queue_pkt_commit(struct peer *peer); -void queue_pkt_revocation(struct peer *peer); +void queue_pkt_revocation(struct peer *peer, + const struct sha256 *preimage, + const struct sha256 *next_hash); void queue_pkt_close_clearing(struct peer *peer); void queue_pkt_close_signature(struct peer *peer);