Browse Source

channeld: handle incoming feerate changes.

We allow from the 100-confirm economical rate to 5x the immediate rate.

Closes: #243
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
062f18127d
  1. 85
      channeld/channel.c
  2. 4
      channeld/channel_wire.csv
  3. 2
      lightningd/peer_control.c
  4. 17
      lightningd/peer_htlcs.c

85
channeld/channel.c

@ -64,6 +64,9 @@ struct peer {
bool funding_locked[NUM_SIDES];
u64 next_index[NUM_SIDES];
/* Tolerable amounts for feerate (only relevant for fundee). */
u32 feerate_min, feerate_max;
/* Remote's current per-commit point. */
struct pubkey remote_per_commit;
@ -430,6 +433,59 @@ static struct io_plan *handle_peer_add_htlc(struct io_conn *conn,
return peer_read_message(conn, &peer->pcs, peer_in);
}
static struct io_plan *handle_peer_feechange(struct io_conn *conn,
struct peer *peer, const u8 *msg)
{
struct channel_id channel_id;
u32 feerate;
if (!fromwire_update_fee(msg, NULL, &channel_id, &feerate)) {
peer_failed(io_conn_fd(peer->peer_conn),
&peer->pcs.cs,
&peer->channel_id,
"Bad update_fee %s", tal_hex(msg, msg));
}
/* BOLT #2:
*
* A receiving node MUST fail the channel if the sender is not
* responsible for paying the bitcoin fee.
*/
if (peer->channel->funder != REMOTE)
peer_failed(io_conn_fd(peer->peer_conn),
&peer->pcs.cs,
&peer->channel_id,
"update_fee from non-funder?");
/* BOLT #2:
*
* A receiving node SHOULD fail the channel if the `update_fee` is too
* low for timely processing, or unreasonably large.
*/
if (feerate < peer->feerate_min || feerate > peer->feerate_max)
peer_failed(io_conn_fd(peer->peer_conn),
&peer->pcs.cs,
&peer->channel_id,
"update_fee %u outside range %u-%u",
feerate, peer->feerate_min, peer->feerate_max);
/* BOLT #2:
*
* A receiving node SHOULD fail the channel if the sender cannot
* afford the new fee rate on the receiving node's current commitment
* transaction, but it MAY delay this check until the `update_fee` is
* committed.
*/
if (!channel_update_feerate(peer->channel, feerate))
peer_failed(io_conn_fd(peer->peer_conn),
&peer->pcs.cs,
&peer->channel_id,
"update_fee %u unaffordable",
feerate);
return peer_read_message(conn, &peer->pcs, peer_in);
}
static struct changed_htlc *changed_htlc_arr(const tal_t *ctx,
const struct htlc **changed_htlcs)
{
@ -446,6 +502,7 @@ static struct changed_htlc *changed_htlc_arr(const tal_t *ctx,
static u8 *sending_commitsig_msg(const tal_t *ctx,
u64 remote_commit_index,
u32 remote_feerate,
const struct htlc **changed_htlcs,
const secp256k1_ecdsa_signature *commit_sig,
const secp256k1_ecdsa_signature *htlc_sigs)
@ -458,6 +515,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,
remote_feerate,
changed, commit_sig, htlc_sigs);
tal_free(tmpctx);
return msg;
@ -665,6 +723,7 @@ static void send_commit(struct 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->next_index[REMOTE],
channel_feerate(peer->channel, REMOTE),
changed_htlcs,
&peer->next_commit_sigs->commit_sig,
peer->next_commit_sigs->htlc_sigs);
@ -798,6 +857,7 @@ static void get_shared_secret(const struct htlc *htlc,
static u8 *got_commitsig_msg(const tal_t *ctx,
u64 local_commit_index,
u32 local_feerate,
const secp256k1_ecdsa_signature *commit_sig,
const secp256k1_ecdsa_signature *htlc_sigs,
const struct htlc **changed_htlcs,
@ -856,6 +916,7 @@ static u8 *got_commitsig_msg(const tal_t *ctx,
}
msg = towire_channel_got_commitsig(ctx, local_commit_index,
local_feerate,
commit_sig,
htlc_sigs,
added,
@ -984,8 +1045,9 @@ static struct io_plan *handle_peer_commit_sig(struct io_conn *conn,
tal_count(htlc_sigs));
/* Tell master daemon, then wait for ack. */
msg = got_commitsig_msg(tmpctx, peer->next_index[LOCAL], &commit_sig,
htlc_sigs, changed_htlcs, txs[0]);
msg = got_commitsig_msg(tmpctx, peer->next_index[LOCAL],
channel_feerate(peer->channel, LOCAL),
&commit_sig, htlc_sigs, changed_htlcs, txs[0]);
master_wait_sync_reply(tmpctx, peer, take(msg),
WIRE_CHANNEL_GOT_COMMITSIG_REPLY);
@ -1369,6 +1431,8 @@ static struct io_plan *peer_in(struct io_conn *conn, struct peer *peer, u8 *msg)
return handle_peer_add_htlc(conn, peer, msg);
case WIRE_COMMITMENT_SIGNED:
return handle_peer_commit_sig(conn, peer, msg);
case WIRE_UPDATE_FEE:
return handle_peer_feechange(conn, peer, msg);
case WIRE_REVOKE_AND_ACK:
return handle_peer_revoke_and_ack(conn, peer, msg);
case WIRE_UPDATE_FULFILL_HTLC:
@ -1391,15 +1455,8 @@ static struct io_plan *peer_in(struct io_conn *conn, struct peer *peer, u8 *msg)
case WIRE_FUNDING_CREATED:
case WIRE_FUNDING_SIGNED:
case WIRE_CHANNEL_REESTABLISH:
goto badmessage;
case WIRE_CLOSING_SIGNED:
case WIRE_UPDATE_FEE:
peer_failed(io_conn_fd(peer->peer_conn),
&peer->pcs.cs,
&peer->channel_id,
"Unimplemented message %u (%s)",
type, wire_type_name(type));
goto badmessage;
}
badmessage:
@ -2036,6 +2093,7 @@ static void init_channel(struct peer *peer)
&funding_satoshi,
&peer->conf[LOCAL], &peer->conf[REMOTE],
feerate_per_kw,
&peer->feerate_min, &peer->feerate_max,
&peer->their_commit_sig,
&peer->pcs.cs,
&funding_pubkey[REMOTE],
@ -2079,14 +2137,17 @@ static void init_channel(struct peer *peer)
status_trace("init %s: remote_per_commit = %s, old_remote_per_commit = %s"
" next_idx_local = %"PRIu64
" next_idx_remote = %"PRIu64
" revocations_received = %"PRIu64,
" revocations_received = %"PRIu64
" feerates %u/%u (range %u-%u)",
side_to_str(funder),
type_to_string(trc, struct pubkey,
&peer->remote_per_commit),
type_to_string(trc, struct pubkey,
&peer->old_remote_per_commit),
peer->next_index[LOCAL], peer->next_index[REMOTE],
peer->revocations_received);
peer->revocations_received,
feerate_per_kw[LOCAL], feerate_per_kw[REMOTE],
peer->feerate_min, peer->feerate_max);
/* First commit is used for opening: if we've sent 0, we're on
* index 1. */

4
channeld/channel_wire.csv

@ -14,6 +14,8 @@ channel_init,,our_config,struct channel_config
channel_init,,their_config,struct channel_config
# FIXME: Fix generate-wire.py to allow NUM_SIDES*u32 here.
channel_init,,feerate_per_kw,2*u32
channel_init,,feerate_min,u32
channel_init,,feerate_max,u32
channel_init,,first_commit_sig,secp256k1_ecdsa_signature
channel_init,,crypto_state,struct crypto_state
channel_init,,remote_fundingkey,struct pubkey
@ -118,6 +120,7 @@ channel_got_funding_locked,,next_per_commit_point,struct pubkey
# When we send a commitment_signed message, tell master.
channel_sending_commitsig,1020
channel_sending_commitsig,,commitnum,u64
channel_sending_commitsig,,feerate,u32
# 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
@ -131,6 +134,7 @@ channel_sending_commitsig_reply,1120
# When we have a commitment_signed message, tell master to remember.
channel_got_commitsig,1021
channel_got_commitsig,,commitnum,u64
channel_got_commitsig,,feerate,u32
channel_got_commitsig,,signature,secp256k1_ecdsa_signature
channel_got_commitsig,,num_htlcs,u16
channel_got_commitsig,,htlc_signature,num_htlcs*secp256k1_ecdsa_signature

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

2
lightningd/peer_control.c

@ -2108,6 +2108,8 @@ static bool peer_start_channeld(struct peer *peer,
&peer->our_config,
&peer->channel_info->their_config,
peer->channel_info->feerate_per_kw,
get_feerate(peer->ld->topology, FEERATE_NORMAL),
get_feerate(peer->ld->topology, FEERATE_IMMEDIATE) * 5,
peer->last_sig,
cs,
&peer->channel_info->remote_fundingkey,

17
lightningd/peer_htlcs.c

@ -990,6 +990,7 @@ static bool peer_save_commitsig_sent(struct peer *peer, u64 commitnum)
void peer_sending_commitsig(struct peer *peer, const u8 *msg)
{
u64 commitnum;
u32 feerate;
struct changed_htlc *changed_htlcs;
size_t i, maxid = 0, num_local_added = 0;
secp256k1_ecdsa_signature commit_sig;
@ -997,6 +998,7 @@ void peer_sending_commitsig(struct peer *peer, const u8 *msg)
if (!fromwire_channel_sending_commitsig(msg, msg, NULL,
&commitnum,
&feerate,
&changed_htlcs,
&commit_sig, &htlc_sigs)) {
peer_internal_error(peer, "bad channel_sending_commitsig %s",
@ -1033,6 +1035,9 @@ void peer_sending_commitsig(struct peer *peer, const u8 *msg)
peer->next_htlc_id += num_local_added;
}
/* Update their feerate. */
peer->channel_info->feerate_per_kw[REMOTE] = feerate;
if (!peer_save_commitsig_sent(peer, commitnum))
return;
@ -1109,6 +1114,7 @@ static bool peer_sending_revocation(struct peer *peer,
void peer_got_commitsig(struct peer *peer, const u8 *msg)
{
u64 commitnum;
u32 feerate;
secp256k1_ecdsa_signature commit_sig;
secp256k1_ecdsa_signature *htlc_sigs;
struct added_htlc *added;
@ -1121,6 +1127,7 @@ void peer_got_commitsig(struct peer *peer, const u8 *msg)
if (!fromwire_channel_got_commitsig(msg, msg, NULL,
&commitnum,
&feerate,
&commit_sig,
&htlc_sigs,
&added,
@ -1137,8 +1144,8 @@ void peer_got_commitsig(struct peer *peer, const u8 *msg)
log_debug(peer->log,
"got commitsig %"PRIu64
": %zu added, %zu fulfilled, %zu failed, %zu changed",
commitnum, tal_count(added), tal_count(fulfilled),
": feerate %u, %zu added, %zu fulfilled, %zu failed, %zu changed",
commitnum, feerate, tal_count(added), tal_count(fulfilled),
tal_count(failed), tal_count(changed));
/* FIXME: store commit & htlc signature information. */
@ -1166,6 +1173,12 @@ void peer_got_commitsig(struct peer *peer, const u8 *msg)
}
}
/* Update both feerates: if we're funder, REMOTE should already be
* that feerate, if we're not, we're about to ACK anyway. */
peer->channel_info->feerate_per_kw[LOCAL]
= peer->channel_info->feerate_per_kw[REMOTE]
= feerate;
/* Since we're about to send revoke, bump state again. */
if (!peer_sending_revocation(peer, added, fulfilled, failed, changed))
return;

Loading…
Cancel
Save