diff --git a/lightningd/channel/channel.c b/lightningd/channel/channel.c index a11534c52..8c02ef179 100644 --- a/lightningd/channel/channel.c +++ b/lightningd/channel/channel.c @@ -286,6 +286,9 @@ static struct io_plan *handle_peer_funding_locked(struct io_conn *conn, "Funding locked twice"); peer->funding_locked[REMOTE] = true; + daemon_conn_send(&peer->master, + take(towire_channel_got_funding_locked(peer, + &peer->current_per_commit[REMOTE]))); if (peer->funding_locked[LOCAL]) { daemon_conn_send(&peer->master, @@ -807,6 +810,7 @@ static struct io_plan *handle_peer_commit_sig(struct io_conn *conn, static u8 *got_revoke_msg(const tal_t *ctx, u64 revoke_num, const struct sha256 *per_commitment_secret, + const struct pubkey *next_per_commit_point, const struct htlc **changed_htlcs) { tal_t *tmpctx = tal_tmpctx(ctx); @@ -826,7 +830,7 @@ static u8 *got_revoke_msg(const tal_t *ctx, u64 revoke_num, } msg = towire_channel_got_revoke(ctx, revoke_num, per_commitment_secret, - changed); + next_per_commit_point, changed); tal_free(tmpctx); return msg; } @@ -893,7 +897,8 @@ static struct io_plan *handle_peer_revoke_and_ack(struct io_conn *conn, /* Tell master about things this locks in, wait for response */ msg = got_revoke_msg(msg, peer->commit_index[REMOTE], - &old_commit_secret, changed_htlcs); + &old_commit_secret, &next_per_commit, + changed_htlcs); master_sync_reply(peer, take(msg), WIRE_CHANNEL_GOT_REVOKE_REPLY, handle_reply_wake_peer); @@ -1549,6 +1554,7 @@ static struct io_plan *req_in(struct io_conn *conn, struct daemon_conn *master) case WIRE_CHANNEL_SENDING_COMMITSIG_REPLY: case WIRE_CHANNEL_GOT_COMMITSIG_REPLY: case WIRE_CHANNEL_GOT_REVOKE_REPLY: + case WIRE_CHANNEL_GOT_FUNDING_LOCKED: break; } status_failed(WIRE_CHANNEL_BAD_COMMAND, "%u %s", t, diff --git a/lightningd/channel/channel_wire.csv b/lightningd/channel/channel_wire.csv index f6735670c..97a58ae82 100644 --- a/lightningd/channel/channel_wire.csv +++ b/lightningd/channel/channel_wire.csv @@ -17,8 +17,7 @@ channel_normal_operation,1001 #include #include -# Begin! You're still waiting for the tx to be buried though (passes -# gossipd-client fd) +# Begin! (passes gossipd-client fd) channel_init,1 channel_init,,funding_txid,struct sha256_double channel_init,,funding_txout,2 @@ -89,6 +88,10 @@ channel_ping_reply,,totlen,u16 # Channeld tells the master that the channel has been announced channel_announced,12 +# When we receive funding_locked. +channel_got_funding_locked,19 +channel_got_funding_locked,,next_per_commit_point,struct pubkey + # When we send a commitment_signed message, tell master. channel_sending_commitsig,20 channel_sending_commitsig,,commitnum,u64 @@ -126,6 +129,7 @@ channel_got_commitsig_reply,121 channel_got_revoke,22 channel_got_revoke,,revokenum,u64 channel_got_revoke,,per_commitment_secret,struct sha256 +channel_got_revoke,,next_per_commit_point,struct pubkey # RCVD_ADD_ACK_REVOCATION, RCVD_REMOVE_ACK_REVOCATION, RCVD_ADD_REVOCATION, RCVD_REMOVE_REVOCATION channel_got_revoke,,num_changed,u16 channel_got_revoke,,changed,num_changed*struct changed_htlc diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 60f12a889..8f12bd665 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -34,15 +34,6 @@ #include #include -/* FIXME: Define serialization primitive for this? */ -struct channel_info { - secp256k1_ecdsa_signature commit_sig; - struct channel_config their_config; - struct pubkey remote_fundingkey; - struct basepoints theirbase; - struct pubkey their_per_commit_point; -}; - static void destroy_peer(struct peer *peer) { list_del_from(&peer->ld->peers, &peer->list); @@ -305,6 +296,7 @@ void add_peer(struct lightningd *ld, u64 unique_id, peer->balance = NULL; peer->state = UNINITIALIZED; peer->channel_info = NULL; + peer->next_per_commitment_point = NULL; shachain_init(&peer->their_shachain); idname = type_to_string(peer, struct pubkey, id); @@ -849,6 +841,25 @@ static void peer_channel_announced(struct peer *peer, const u8 *msg) tal_free(tmpctx); } +static int peer_got_funding_locked(struct peer *peer, const u8 *msg) +{ + struct pubkey next_per_commitment_point; + + if (!fromwire_channel_got_funding_locked(msg, NULL, + &next_per_commitment_point)) { + log_broken(peer->log, "bad channel_got_funding_locked %s", + tal_hex(peer, msg)); + return -1; + } + + /* In case of re-transmit. */ + peer->next_per_commitment_point + = tal_free(peer->next_per_commitment_point); + peer->next_per_commitment_point + = tal_dup(peer, struct pubkey, &next_per_commitment_point); + return 0; +} + static int channel_msg(struct subd *sd, const u8 *msg, const int *unused) { enum channel_wire_type t = fromwire_peektype(msg); @@ -867,6 +878,8 @@ static int channel_msg(struct subd *sd, const u8 *msg, const int *unused) case WIRE_CHANNEL_ANNOUNCED: peer_channel_announced(sd->peer, msg); break; + case WIRE_CHANNEL_GOT_FUNDING_LOCKED: + return peer_got_funding_locked(sd->peer, msg); /* We never see fatal ones. */ case WIRE_CHANNEL_BAD_COMMAND: diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h index 56c9f3704..1f7ed0c24 100644 --- a/lightningd/peer_control.h +++ b/lightningd/peer_control.h @@ -75,6 +75,9 @@ struct peer { /* Keys for channel. */ struct channel_info *channel_info; + /* Their next per-commit point, if known. */ + struct pubkey *next_per_commitment_point; + /* Secret seed (FIXME: Move to hsm!) */ struct privkey *seed; diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index b695b74c5..da82789d3 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -908,6 +908,17 @@ int peer_got_commitsig(struct peer *peer, const u8 *msg) return 0; } +/* Shuffle them over, forgetting the ancient one. */ +static void update_per_commit_point(struct peer *peer, + const struct pubkey *per_commitment_point) +{ + peer->channel_info->their_per_commit_point + = *peer->next_per_commitment_point; + tal_free(peer->next_per_commitment_point); + peer->next_per_commitment_point = tal_dup(peer, struct pubkey, + per_commitment_point); +} + /* FIXME: add to ccan/shachain */ static shachain_index_t shachain_next_index(const struct shachain *chain) { @@ -921,12 +932,14 @@ int peer_got_revoke(struct peer *peer, const u8 *msg) { u64 revokenum, shachainidx; struct sha256 per_commitment_secret; + struct pubkey next_per_commitment_point; struct changed_htlc *changed; enum onion_type *failcodes; size_t i; if (!fromwire_channel_got_revoke(msg, msg, NULL, &revokenum, &per_commitment_secret, + &next_per_commitment_point, &changed)) { log_broken(peer->log, "bad fromwire_channel_got_revoke %s", tal_hex(peer, msg)); @@ -985,7 +998,10 @@ int peer_got_revoke(struct peer *peer, const u8 *msg) return -1; } - /* FIXME: Commit shachain to db */ + /* FIXME: Check per_commitment_secret -> per_commit_point */ + update_per_commit_point(peer, &next_per_commitment_point); + + /* FIXME: Commit shachain and next_per_commit_point to db */ /* Tell it we've committed, and to go ahead with revoke. */ msg = towire_channel_got_revoke_reply(msg); diff --git a/lightningd/peer_htlcs.h b/lightningd/peer_htlcs.h index ece7c7eea..9e60b2a72 100644 --- a/lightningd/peer_htlcs.h +++ b/lightningd/peer_htlcs.h @@ -4,6 +4,15 @@ #include "config.h" #include +/* FIXME: Define serialization primitive for this? */ +struct channel_info { + secp256k1_ecdsa_signature commit_sig; + struct channel_config their_config; + struct pubkey remote_fundingkey; + struct basepoints theirbase; + struct pubkey their_per_commit_point; +}; + int peer_sending_commitsig(struct peer *peer, const u8 *msg); int peer_got_commitsig(struct peer *peer, const u8 *msg); int peer_got_revoke(struct peer *peer, const u8 *msg);