From 61906ea415a7c1a9f975f44b7c34d2a01e808086 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 20 Jun 2017 15:21:03 +0930 Subject: [PATCH] channeld: don't keep shachain. The master daemon is the one which stores it, have it do the check. Signed-off-by: Rusty Russell --- lightningd/channel/channel.c | 31 ++++--------------------- lightningd/peer_control.c | 1 + lightningd/peer_control.h | 4 ++++ lightningd/peer_htlcs.c | 45 ++++++++++++++++++++++++++++++++++-- 4 files changed, 52 insertions(+), 29 deletions(-) diff --git a/lightningd/channel/channel.c b/lightningd/channel/channel.c index 0d05162f5..df629cb86 100644 --- a/lightningd/channel/channel.c +++ b/lightningd/channel/channel.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -65,9 +64,6 @@ struct peer { /* Our shaseed for generating per-commitment-secrets. */ struct sha256 shaseed; - /* Their shachain. */ - struct shachain their_shachain; - /* BOLT #2: * * A sending node MUST set `id` to 0 for the first HTLC it offers, and @@ -893,23 +889,6 @@ static struct io_plan *handle_peer_revoke_and_ack(struct io_conn *conn, &peer->old_per_commit[REMOTE])); } - /* BOLT #2: - * - * A receiving node MAY fail if the `per_commitment_secret` was not - * generated by the protocol in [BOLT #3] - */ - if (!shachain_add_hash(&peer->their_shachain, - shachain_index(peer->commit_index[REMOTE]), - &old_commit_secret)) { - peer_failed(io_conn_fd(peer->peer_conn), - &peer->pcs.cs, - &peer->channel_id, - WIRE_CHANNEL_PEER_BAD_MESSAGE, - "Bad shachain for privkey %"PRIu64" %s ", - peer->commit_index[REMOTE], - type_to_string(msg, struct privkey, &privkey)); - } - /* We start timer even if this returns false: we might have delayed * commit because we were waiting for this! */ if (channel_rcvd_revoke_and_ack(peer->channel, &changed_htlcs)) @@ -917,10 +896,6 @@ static struct io_plan *handle_peer_revoke_and_ack(struct io_conn *conn, else status_trace("No commits outstanding after recv revoke_and_ack"); - peer->commit_index[REMOTE]++; - peer->old_per_commit[REMOTE] = peer->current_per_commit[REMOTE]; - peer->current_per_commit[REMOTE] = next_per_commit; - /* Tell master about things this locks in, wait for response */ msg = got_revoke_msg(msg, peer->commit_index[REMOTE], &old_commit_secret, changed_htlcs); @@ -928,6 +903,10 @@ static struct io_plan *handle_peer_revoke_and_ack(struct io_conn *conn, WIRE_CHANNEL_GOT_REVOKE_REPLY, handle_reply_wake_peer); + peer->commit_index[REMOTE]++; + peer->old_per_commit[REMOTE] = peer->current_per_commit[REMOTE]; + peer->current_per_commit[REMOTE] = next_per_commit; + /* And peer waits for reply. */ return io_wait(conn, peer, accepted_revocation, peer); } @@ -1648,8 +1627,6 @@ int main(int argc, char *argv[]) sizeof(peer->announcement_bitcoin_sigs[i])); } - shachain_init(&peer->their_shachain); - status_setup_async(&peer->master); msg_queue_init(&peer->peer_out, peer); diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 49e6977f7..60f12a889 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -305,6 +305,7 @@ void add_peer(struct lightningd *ld, u64 unique_id, peer->balance = NULL; peer->state = UNINITIALIZED; peer->channel_info = NULL; + shachain_init(&peer->their_shachain); idname = type_to_string(peer, struct pubkey, id); diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h index 83886db9b..56c9f3704 100644 --- a/lightningd/peer_control.h +++ b/lightningd/peer_control.h @@ -2,6 +2,7 @@ #define LIGHTNING_LIGHTNINGD_PEER_CONTROL_H #include "config.h" #include +#include #include #include #include @@ -23,6 +24,9 @@ struct peer { /* ID of peer */ struct pubkey id; + /* Their shachain. */ + struct shachain their_shachain; + /* What's happening. */ enum peer_state state; diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index e0cd014c6..97f502471 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -908,9 +909,18 @@ int peer_got_commitsig(struct peer *peer, const u8 *msg) return 0; } +/* 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; + u64 revokenum, shachainidx; struct sha256 per_commitment_secret; u64 *added_ids; struct secret *shared_secret; @@ -947,7 +957,38 @@ int peer_got_revoke(struct peer *peer, const u8 *msg) } } - /* FIXME: Save per-commit-secret! */ + if (revokenum >= (1ULL << 48)) { + log_broken(peer->log, "got_revoke: too many txs %"PRIu64, + revokenum); + 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)); + return -1; + } + + /* BOLT #2: + * + * A receiving node MAY fail if the `per_commitment_secret` was not + * generated by the protocol in [BOLT #3] + */ + if (!shachain_add_hash(&peer->their_shachain, + shachainidx, &per_commitment_secret)) { + peer_fail(peer, "Bad per_commitment_secret %s for %"PRIu64, + type_to_string(msg, struct sha256, + &per_commitment_secret), + revokenum); + return -1; + } + + /* FIXME: Commit shachain to db */ /* Tell it we've committed, and to go ahead with revoke. */ msg = towire_channel_got_revoke_reply(msg);