diff --git a/close_tx.h b/close_tx.h index aa26d691e..e52349e83 100644 --- a/close_tx.h +++ b/close_tx.h @@ -6,6 +6,7 @@ #include struct sha256_double; +struct pubkey; /* Create close tx to spend the anchor tx output; doesn't fill in * input scriptsig. */ diff --git a/daemon/packets.c b/daemon/packets.c index 537a71a60..e8eb03771 100644 --- a/daemon/packets.c +++ b/daemon/packets.c @@ -219,7 +219,23 @@ Pkt *pkt_err(const tal_t *ctx, const char *msg, ...) Pkt *pkt_close(const tal_t *ctx, const struct peer *peer) { - FIXME_STUB(peer); + CloseChannel *c = tal(ctx, CloseChannel); + struct signature sig; + + close_channel__init(c); + + /* FIXME: If we're not connected, we don't create close tx. */ + if (!peer->close_tx) { + c->close_fee = 0; + memset(&sig, 0, sizeof(sig)); + c->sig = signature_to_proto(c, &sig); + } else { + c->close_fee = peer->close_tx->fee; + peer_sign_mutual_close(peer, peer->close_tx, &sig); + c->sig = signature_to_proto(c, &sig); + } + + return make_pkt(ctx, PKT__PKT_CLOSE, c); } Pkt *pkt_close_complete(const tal_t *ctx, const struct peer *peer) diff --git a/daemon/peer.c b/daemon/peer.c index b0b5c66e3..4552b6ada 100644 --- a/daemon/peer.c +++ b/daemon/peer.c @@ -1,4 +1,5 @@ #include "bitcoind.h" +#include "close_tx.h" #include "commit_tx.h" #include "cryptopkt.h" #include "dns.h" @@ -10,6 +11,7 @@ #include "peer.h" #include "secrets.h" #include "state.h" +#include "timeout.h" #include #include #include @@ -251,6 +253,7 @@ static struct peer *new_peer(struct lightningd_state *dstate, peer->cmd = INPUT_NONE; peer->current_htlc = NULL; peer->num_htlcs = 0; + peer->close_tx = NULL; /* If we free peer, conn should be closed, but can't be freed * immediately so don't make peer a parent. */ @@ -569,9 +572,25 @@ void peer_watch_tx(struct peer *peer, { FIXME_STUB(peer); } + +static void send_close_timeout(struct peer *peer) +{ + update_state(peer, INPUT_CLOSE_COMPLETE_TIMEOUT, NULL); +} + void peer_watch_close(struct peer *peer, enum state_input done, enum state_input timedout) { + /* We save some work by assuming this. */ + assert(timedout == INPUT_CLOSE_COMPLETE_TIMEOUT); + + /* FIXME: We didn't send CLOSE, so timeout immediately */ + if (!peer->conn) { + (void)send_close_timeout; + /* FIXME: oneshot_timeout(peer->dstate, peer, 0, send_close_timeout, peer); */ + return; + } + FIXME_STUB(peer); } void peer_unwatch_close_timeout(struct peer *peer, enum state_input timedout) diff --git a/daemon/peer.h b/daemon/peer.h index 78b982e59..cc520074a 100644 --- a/daemon/peer.h +++ b/daemon/peer.h @@ -94,6 +94,9 @@ struct peer { struct htlc_progress *current_htlc; /* Number of HTLC updates (== number of previous commit txs) */ u64 num_htlcs; + + /* Closing tx, once we've generated it */ + struct bitcoin_tx *close_tx; /* Current ongoing packetflow */ struct io_data *io_data; diff --git a/daemon/secrets.c b/daemon/secrets.c index 1bee2af24..17118b200 100644 --- a/daemon/secrets.c +++ b/daemon/secrets.c @@ -55,6 +55,19 @@ void peer_sign_theircommit(const struct peer *peer, sig); } +void peer_sign_mutual_close(const struct peer *peer, + struct bitcoin_tx *close, + struct signature *sig) +{ + sign_tx_input(peer->dstate->secpctx, + close, 0, + peer->anchor.redeemscript, + tal_count(peer->anchor.redeemscript), + &peer->secrets->commit, + &peer->us.commitkey, + sig); +} + static void new_keypair(struct lightningd_state *dstate, struct privkey *privkey, struct pubkey *pubkey) { diff --git a/daemon/secrets.h b/daemon/secrets.h index 1125550ce..48ebba57f 100644 --- a/daemon/secrets.h +++ b/daemon/secrets.h @@ -16,6 +16,10 @@ void peer_sign_theircommit(const struct peer *peer, struct bitcoin_tx *commit, struct signature *sig); +void peer_sign_mutual_close(const struct peer *peer, + struct bitcoin_tx *close, + struct signature *sig); + void peer_secrets_init(struct peer *peer); void peer_get_revocation_hash(const struct peer *peer, u64 index,