Browse Source

lightningd/channel: tell master about the commit sigs.

There are two ways we can do retransmission on reconnect: re-derive
what we would have sent, or remember it and simply re-send.  The
rederivation is difficult: unwinding state depends on whether we sent
a revoke_and_ack before or after the commitment_signed, and unwinding
a revoke_and_ack would require us to remember HTLCs we would have
normally forgotten at this point.

So we simply tell the master to remember the old signatures for us,
and hand them back in case we need to re-send.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
parent
commit
9497cbe73b
  1. 102
      lightningd/channel/channel.c
  2. 3
      lightningd/channel/channel_wire.csv
  3. 7
      lightningd/peer_htlcs.c

102
lightningd/channel/channel.c

@ -47,6 +47,12 @@
#define GOSSIP_FD 4
#define HSM_FD 5
struct commit_sigs {
struct peer *peer;
secp256k1_ecdsa_signature commit_sig;
secp256k1_ecdsa_signature *htlc_sigs;
};
struct peer {
struct peer_crypto_state pcs;
struct channel_config conf[NUM_SIDES];
@ -106,6 +112,9 @@ struct peer {
u16 cltv_delta;
u32 fee_base;
u32 fee_per_satoshi;
/* We save calculated commit sigs while waiting for master approval */
struct commit_sigs *next_commit_sigs;
};
static u8 *create_channel_announcement(const tal_t *ctx, struct peer *peer);
@ -385,7 +394,9 @@ static struct changed_htlc *changed_htlc_arr(const tal_t *ctx,
static u8 *sending_commitsig_msg(const tal_t *ctx,
u64 remote_commit_index,
const struct htlc **changed_htlcs)
const struct htlc **changed_htlcs,
const secp256k1_ecdsa_signature *commit_sig,
const secp256k1_ecdsa_signature *htlc_sigs)
{
const tal_t *tmpctx = tal_tmpctx(ctx);
struct changed_htlc *changed;
@ -395,7 +406,7 @@ static u8 *sending_commitsig_msg(const tal_t *ctx,
* committed to. */
changed = changed_htlc_arr(tmpctx, changed_htlcs);
msg = towire_channel_sending_commitsig(ctx, remote_commit_index,
changed);
changed, commit_sig, htlc_sigs);
tal_free(tmpctx);
return msg;
}
@ -403,14 +414,46 @@ static u8 *sending_commitsig_msg(const tal_t *ctx,
/* Master has acknowledged that we're sending commitment, so send it. */
static void handle_sending_commitsig_reply(struct peer *peer, const u8 *msg)
{
const tal_t *tmpctx = tal_tmpctx(peer);
secp256k1_ecdsa_signature commit_sig, *htlc_sigs;
status_trace("Sending commit_sig with %zu htlc sigs",
tal_count(peer->next_commit_sigs->htlc_sigs));
msg = towire_commitment_signed(peer, &peer->channel_id,
&peer->next_commit_sigs->commit_sig,
peer->next_commit_sigs->htlc_sigs);
msg_enqueue(&peer->peer_out, take(msg));
peer->next_commit_sigs = tal_free(peer->next_commit_sigs);
/* Timer now considered expired, you can add a new one. */
peer->commit_timer = NULL;
/* FIXME: In case we had outstanding commits, restart timer */
start_commit_timer(peer);
}
/* This blocks other traffic from the master until we get reply. */
static void master_sync_reply(struct peer *peer, const u8 *msg,
enum channel_wire_type replytype,
void (*handle)(struct peer *peer, const u8 *msg))
{
assert(!peer->handle_master_reply);
peer->handle_master_reply = handle;
peer->master_reply_type = replytype;
daemon_conn_send(&peer->master, msg);
}
static struct commit_sigs *calc_commitsigs(const tal_t *ctx,
const struct peer *peer)
{
const tal_t *tmpctx = tal_tmpctx(ctx);
size_t i;
struct bitcoin_tx **txs;
const u8 **wscripts;
const struct htlc **htlc_map;
struct pubkey localkey;
struct privkey local_secretkey;
struct commit_sigs *commit_sigs = tal(ctx, struct commit_sigs);
if (!derive_simple_privkey(&peer->our_secrets.payment_basepoint_secret,
&peer->channel->basepoints[LOCAL].payment,
@ -432,11 +475,11 @@ static void handle_sending_commitsig_reply(struct peer *peer, const u8 *msg)
wscripts[0],
&peer->our_secrets.funding_privkey,
&peer->channel->funding_pubkey[LOCAL],
&commit_sig);
&commit_sigs->commit_sig);
status_trace("Creating commit_sig signature %s for tx %s wscript %s key %s",
type_to_string(trc, secp256k1_ecdsa_signature,
&commit_sig),
&commit_sigs->commit_sig),
type_to_string(trc, struct bitcoin_tx, txs[0]),
tal_hex(trc, wscripts[0]),
type_to_string(trc, struct pubkey,
@ -449,51 +492,27 @@ static void handle_sending_commitsig_reply(struct peer *peer, const u8 *msg)
* corresponding to BIP69 lexicographic ordering of the commitment
* transaction.
*/
htlc_sigs = tal_arr(tmpctx, secp256k1_ecdsa_signature,
tal_count(txs) - 1);
commit_sigs->htlc_sigs = tal_arr(commit_sigs, secp256k1_ecdsa_signature,
tal_count(txs) - 1);
for (i = 0; i < tal_count(htlc_sigs); i++) {
for (i = 0; i < tal_count(commit_sigs->htlc_sigs); i++) {
sign_tx_input(txs[1 + i], 0,
NULL,
wscripts[1 + i],
&local_secretkey, &localkey,
&htlc_sigs[i]);
&commit_sigs->htlc_sigs[i]);
status_trace("Creating HTLC signature %s for tx %s wscript %s key %s",
type_to_string(trc, secp256k1_ecdsa_signature,
&htlc_sigs[i]),
&commit_sigs->htlc_sigs[i]),
type_to_string(trc, struct bitcoin_tx, txs[1+i]),
tal_hex(trc, wscripts[1+i]),
type_to_string(trc, struct pubkey, &localkey));
assert(check_tx_sig(txs[1+i], 0, NULL, wscripts[1+i],
&localkey, &htlc_sigs[i]));
&localkey, &commit_sigs->htlc_sigs[i]));
}
status_trace("Sending commit_sig with %zu htlc sigs",
tal_count(htlc_sigs));
msg = towire_commitment_signed(tmpctx, &peer->channel_id,
&commit_sig, htlc_sigs);
msg_enqueue(&peer->peer_out, take(msg));
/* Timer now considered expired, you can add a new one. */
peer->commit_timer = NULL;
/* FIXME: In case we had outstanding commits, restart timer */
start_commit_timer(peer);
tal_free(tmpctx);
}
/* This blocks other traffic from the master until we get reply. */
static void master_sync_reply(struct peer *peer, const u8 *msg,
enum channel_wire_type replytype,
void (*handle)(struct peer *peer, const u8 *msg))
{
assert(!peer->handle_master_reply);
peer->handle_master_reply = handle;
peer->master_reply_type = replytype;
daemon_conn_send(&peer->master, msg);
return commit_sigs;
}
static void send_commit(struct peer *peer)
@ -529,10 +548,14 @@ static void send_commit(struct peer *peer)
return;
}
peer->next_commit_sigs = calc_commitsigs(peer, peer);
status_trace("Telling master we're about to commit...");
/* Tell master to save this next commit to database, then wait. */
msg = sending_commitsig_msg(tmpctx, peer->commit_index[REMOTE] + 1,
changed_htlcs);
changed_htlcs,
&peer->next_commit_sigs->commit_sig,
peer->next_commit_sigs->htlc_sigs);
master_sync_reply(peer, take(msg),
WIRE_CHANNEL_SENDING_COMMITSIG_REPLY,
handle_sending_commitsig_reply);
@ -1492,6 +1515,8 @@ static void handle_fail(struct peer *peer, const u8 *inmsg)
if (malformed) {
struct htlc *h;
struct sha256 sha256_of_onion;
status_trace("Failing %"PRIu64" with code %u",
id, malformed);
h = channel_get_htlc(peer->channel, REMOTE, id);
sha256(&sha256_of_onion, h->routing,
tal_len(h->routing));
@ -1673,6 +1698,7 @@ int main(int argc, char *argv[])
peer->master_reply_type = 0;
msg_queue_init(&peer->master_deferred, peer);
msg_queue_init(&peer->peer_out, peer);
peer->next_commit_sigs = NULL;
/* We send these to HSM to get real signatures; don't have valgrind
* complain. */

3
lightningd/channel/channel_wire.csv

@ -117,6 +117,9 @@ channel_sending_commitsig,,commitnum,u64
# SENT_ADD_COMMIT, SENT_REMOVE_ACK_COMMIT, SENT_ADD_ACK_COMMIT, SENT_REMOVE_COMMIT
channel_sending_commitsig,,num_changed,u16
channel_sending_commitsig,,changed,num_changed*struct changed_htlc
channel_sending_commitsig,,commit_sig,secp256k1_ecdsa_signature
channel_sending_commitsig,,num_htlc_sigs,u16
channel_sending_commitsig,,htlc_sigs,num_htlc_sigs*secp256k1_ecdsa_signature
# Wait for reply, to make sure it's on disk before we send commit.
channel_sending_commitsig_reply,120

Can't render this file because it has a wrong number of fields in line 2.

7
lightningd/peer_htlcs.c

@ -806,10 +806,13 @@ int peer_sending_commitsig(struct peer *peer, const u8 *msg)
u64 commitnum;
struct changed_htlc *changed_htlcs;
size_t i;
secp256k1_ecdsa_signature commit_sig;
secp256k1_ecdsa_signature *htlc_sigs;
if (!fromwire_channel_sending_commitsig(msg, msg, NULL,
&commitnum,
&changed_htlcs)) {
&changed_htlcs,
&commit_sig, &htlc_sigs)) {
log_broken(peer->log, "bad channel_sending_commitsig %s",
tal_hex(peer, msg));
return -1;
@ -826,6 +829,8 @@ int peer_sending_commitsig(struct peer *peer, const u8 *msg)
if (!peer_save_commitsig_sent(peer, commitnum))
return -1;
/* FIXME: save commit_sig and htlc_sigs */
/* Last was commit. */
peer->last_was_revoke = false;
tal_free(peer->last_sent_commit);

Loading…
Cancel
Save