From 552e56d002a599c153bdc54b82be6966eff2b1a7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 21 Nov 2017 15:56:59 +1030 Subject: [PATCH] channeld: send update_fee messages. We only send them when we're not awaiting revoke_and_ack: our simplified handling can't deal with multiple in flights. Closes: #244 Signed-off-by: Rusty Russell --- channeld/channel.c | 62 +++++++++++++++++++++++++++++++++++++++ channeld/channel_wire.csv | 5 ++++ lightningd/peer_control.c | 1 + lightningd/peer_control.h | 6 ++++ lightningd/peer_htlcs.c | 26 +++++++++++++++- 5 files changed, 99 insertions(+), 1 deletion(-) diff --git a/channeld/channel.c b/channeld/channel.c index 8cabb200a660..4d59a25feded 100644 --- a/channeld/channel.c +++ b/channeld/channel.c @@ -110,6 +110,9 @@ struct peer { /* Don't accept a pong we didn't ping for. */ size_t num_pings_outstanding; + /* The feerate we want. */ + u32 desired_feerate; + /* Announcement related information */ struct pubkey node_ids[NUM_SIDES]; struct short_channel_id short_channel_ids[NUM_SIDES]; @@ -483,6 +486,7 @@ static struct io_plan *handle_peer_feechange(struct io_conn *conn, "update_fee %u unaffordable", feerate); + status_trace("peer updated fee to %u", feerate); return peer_read_message(conn, &peer->pcs, peer_in); } @@ -697,6 +701,29 @@ static void send_commit(struct peer *peer) return; } + /* If we wanted to update fees, do it now. */ + if (peer->channel->funder == LOCAL + && peer->desired_feerate != channel_feerate(peer->channel, REMOTE)) { + u8 *msg; + u32 feerate, max = approx_max_feerate(peer->channel); + + feerate = peer->desired_feerate; + + /* FIXME: We should avoid adding HTLCs until we can meet this + * feerate! */ + if (feerate > max) + feerate = max; + + if (!channel_update_feerate(peer->channel, feerate)) + status_failed(STATUS_FAIL_INTERNAL_ERROR, + "Could not afford feerate %u" + " (vs max %u)", + feerate, max); + + msg = towire_update_fee(peer, &peer->channel_id, feerate); + msg_enqueue(&peer->peer_out, take(msg)); + } + /* BOLT #2: * * A node MUST NOT send a `commitment_signed` message which does not @@ -1887,6 +1914,34 @@ static void handle_offer_htlc(struct peer *peer, const u8 *inmsg) wire_sync_write(MASTER_FD, take(msg)); } +static void handle_feerates(struct peer *peer, const u8 *inmsg) +{ + u32 feerate, min_feerate, max_feerate; + + if (!fromwire_channel_feerates(inmsg, NULL, &feerate, + &min_feerate, &max_feerate)) + master_badmsg(WIRE_CHANNEL_FEERATES, inmsg); + + /* BOLT #2: + * + * The node which is responsible for paying the bitcoin fee SHOULD + * send `update_fee` to ensure the current fee rate is sufficient for + * timely processing of the commitment transaction by a significant + * margin. */ + if (peer->channel->funder == LOCAL) { + peer->desired_feerate = feerate; + start_commit_timer(peer); + } else { + /* BOLT #2: + * + * The node which is not responsible for paying the bitcoin + * fee MUST NOT send `update_fee`. + */ + /* FIXME: We could drop to chain if fees are too low, but + * that's fraught too. */ + } +} + static void handle_preimage(struct peer *peer, const u8 *inmsg) { u8 *msg; @@ -2034,6 +2089,9 @@ static void req_in(struct peer *peer, const u8 *msg) case WIRE_CHANNEL_OFFER_HTLC: handle_offer_htlc(peer, msg); goto out; + case WIRE_CHANNEL_FEERATES: + handle_feerates(peer, msg); + goto out; case WIRE_CHANNEL_FULFILL_HTLC: handle_preimage(peer, msg); goto out; @@ -2194,6 +2252,10 @@ static void init_channel(struct peer *peer) peer->channel_direction = get_channel_direction( &peer->node_ids[LOCAL], &peer->node_ids[REMOTE]); + /* Default desired feerate is the feerate we set for them last. */ + if (peer->channel->funder == LOCAL) + peer->desired_feerate = feerate_per_kw[REMOTE]; + /* OK, now we can process peer messages. */ if (reconnected) peer_reconnect(peer); diff --git a/channeld/channel_wire.csv b/channeld/channel_wire.csv index 5a9ad95f2808..5f72ae1d48a3 100644 --- a/channeld/channel_wire.csv +++ b/channeld/channel_wire.csv @@ -185,3 +185,8 @@ channel_shutdown_complete,,crypto_state,struct crypto_state # Re-enable commit timer. channel_dev_reenable_commit,1026 channel_dev_reenable_commit_reply,1126 + +channel_feerates,1027 +channel_feerates,,feerate,u32 +channel_feerates,,min_feerate,u32 +channel_feerates,,max_feerate,u32 diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 3b198102212e..9ce3d192ced4 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -2009,6 +2009,7 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds) case WIRE_CHANNEL_SENDING_COMMITSIG_REPLY: case WIRE_CHANNEL_SEND_SHUTDOWN: case WIRE_CHANNEL_DEV_REENABLE_COMMIT: + case WIRE_CHANNEL_FEERATES: /* Replies go to requests. */ case WIRE_CHANNEL_OFFER_HTLC_REPLY: case WIRE_CHANNEL_PING_REPLY: diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h index 58038172e8e7..53c7c8c6d65b 100644 --- a/lightningd/peer_control.h +++ b/lightningd/peer_control.h @@ -106,6 +106,12 @@ static inline bool peer_can_add_htlc(const struct peer *peer) return peer->state == CHANNELD_NORMAL; } +static inline bool peer_fees_can_change(const struct peer *peer) +{ + return peer->state == CHANNELD_NORMAL + || peer->state == CHANNELD_SHUTTING_DOWN; +} + static inline bool peer_can_remove_htlc(const struct peer *peer) { return peer->state == CHANNELD_NORMAL diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 299e0e6be7c5..2350d51835fc 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -1538,5 +1538,29 @@ void notify_new_block(struct lightningd *ld, u32 height) void notify_feerate_change(struct lightningd *ld) { - /* FIXME: Do something! */ + struct peer *peer; + + /* FIXME: We should notify onchaind about NORMAL fee change in case + * it's going to generate more txs. */ + list_for_each(&ld->peers, peer, list) { + u8 *msg; + + if (!peer_fees_can_change(peer)) + continue; + + /* FIXME: We choose not to drop to chain if we can't contact + * peer. We *could* do so, however. */ + if (!peer->owner) + continue; + + msg = towire_channel_feerates(peer, + get_feerate(ld->topology, + FEERATE_IMMEDIATE), + get_feerate(ld->topology, + FEERATE_NORMAL), + get_feerate(ld->topology, + FEERATE_IMMEDIATE) + * 5); + subd_send_msg(peer->owner, take(msg)); + } }