diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 33da80fd1..450cf51fd 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -297,6 +297,8 @@ void add_peer(struct lightningd *ld, u64 unique_id, peer->state = UNINITIALIZED; peer->channel_info = NULL; peer->next_per_commitment_point = NULL; + peer->num_commits_sent = peer->num_commits_received + = peer->num_revocations_received = 0; shachain_init(&peer->their_shachain); idname = type_to_string(peer, struct pubkey, id); @@ -1065,6 +1067,11 @@ static bool opening_funder_finished(struct subd *opening, const u8 *resp, return false; } + if (!peer_save_commitsig(fc->peer, 0)) { + peer_fail(fc->peer, "Saving commitsig failed"); + return false; + } + /* Get HSM to sign the funding tx. */ log_debug(fc->peer->log, "Getting HSM to sign funding tx"); @@ -1121,6 +1128,9 @@ static bool opening_fundee_finished(struct subd *opening, return false; } + if (!peer_save_commitsig(peer, 0)) + return false; + log_debug(peer->log, "Watching funding tx %s", type_to_string(reply, struct sha256_double, peer->funding_txid)); diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h index 408bbf8c2..6b805b229 100644 --- a/lightningd/peer_control.h +++ b/lightningd/peer_control.h @@ -64,6 +64,9 @@ struct peer { /* Minimum funding depth (specified by us if they fund). */ u32 minimum_depth; + /* Tracking commitment transaction numbers. */ + u64 num_commits_sent, num_commits_received, num_revocations_received; + /* Funding txid and amounts (once known) */ struct sha256_double *funding_txid; u16 funding_outnum; diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index fd5e67f20..391132d16 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -775,6 +775,14 @@ int peer_sending_commitsig(struct peer *peer, const u8 *msg) return -1; } + if (commitnum != peer->num_commits_sent) { + log_broken(peer->log, + "channel_sending_commitsig: expected commitnum %" + PRIu64" got %"PRIu64, + peer->num_commits_sent, commitnum); + return -1; + } + for (i = 0; i < tal_count(changed_htlcs); i++) { if (!changed_htlc(peer, changed_htlcs + i)) { log_broken(peer->log, @@ -783,6 +791,8 @@ int peer_sending_commitsig(struct peer *peer, const u8 *msg) } } + peer->num_commits_sent++; + /* Tell it we've got it, and to go ahead with commitment_signed. */ subd_send_msg(peer->owner, take(towire_channel_sending_commitsig_reply(msg))); @@ -853,6 +863,23 @@ static bool peer_sending_revocation(struct peer *peer, return true; } +/* Also used for opening's initial commitsig */ +bool peer_save_commitsig(struct peer *peer, u64 commitnum) +{ + if (commitnum != peer->num_commits_received) { + log_broken(peer->log, + "channel_got_commitsig: expected commitnum %"PRIu64 + " got %"PRIu64, + peer->num_commits_received, commitnum); + return false; + } + + peer->num_commits_received++; + + /* FIXME: Save to database, with sig and HTLCs. */ + return true; +} + /* This also implies we're sending revocation */ int peer_got_commitsig(struct peer *peer, const u8 *msg) { @@ -915,6 +942,9 @@ int peer_got_commitsig(struct peer *peer, const u8 *msg) if (!peer_sending_revocation(peer, added, fulfilled, failed, changed)) return -1; + peer->channel_info->commit_sig = commit_sig; + peer_save_commitsig(peer, commitnum); + /* Tell it we've committed, and to go ahead with revoke. */ msg = towire_channel_got_commitsig_reply(msg); subd_send_msg(peer->owner, take(msg)); @@ -932,18 +962,9 @@ static void update_per_commit_point(struct peer *peer, per_commitment_point); } -/* FIXME: add to ccan/shachain */ -static shachain_index_t shachain_next_index(const struct shachain *chain) -{ - if (chain->num_valid == 0) - return (shachain_index_t)(UINT64_MAX >> (64 - SHACHAIN_BITS)); - else - return chain->min_index - 1; -} - int peer_got_revoke(struct peer *peer, const u8 *msg) { - u64 revokenum, shachainidx; + u64 revokenum; struct sha256 per_commitment_secret; struct pubkey next_per_commitment_point; struct changed_htlc *changed; @@ -986,14 +1007,10 @@ int peer_got_revoke(struct peer *peer, const u8 *msg) return -1; } - shachainidx = shachain_index(revokenum); - /* Channeld must feed us these in order. */ - if (shachainidx != shachain_next_index(&peer->their_shachain)) { - log_broken(peer->log, "got_revoke: bad revoke number %"PRIu64 - " != %"PRIu64, - revokenum, - (u64)281474976710655 - - shachain_next_index(&peer->their_shachain)); + if (revokenum != peer->num_revocations_received) { + log_broken(peer->log, "got_revoke: expected %"PRIu64 + " got %"PRIu64, + peer->num_revocations_received, revokenum); return -1; } @@ -1003,7 +1020,8 @@ int peer_got_revoke(struct peer *peer, const u8 *msg) * generated by the protocol in [BOLT #3] */ if (!shachain_add_hash(&peer->their_shachain, - shachainidx, &per_commitment_secret)) { + shachain_index(revokenum), + &per_commitment_secret)) { peer_fail(peer, "Bad per_commitment_secret %s for %"PRIu64, type_to_string(msg, struct sha256, &per_commitment_secret), @@ -1013,6 +1031,7 @@ int peer_got_revoke(struct peer *peer, const u8 *msg) /* FIXME: Check per_commitment_secret -> per_commit_point */ update_per_commit_point(peer, &next_per_commitment_point); + peer->num_revocations_received++; /* FIXME: Commit shachain and next_per_commit_point to db */ diff --git a/lightningd/peer_htlcs.h b/lightningd/peer_htlcs.h index 9e60b2a72..b686c400a 100644 --- a/lightningd/peer_htlcs.h +++ b/lightningd/peer_htlcs.h @@ -13,6 +13,8 @@ struct channel_info { struct pubkey their_per_commit_point; }; +bool peer_save_commitsig(struct peer *peer, u64 commitnum); + 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);