setchannel: add minhtlc

Suggested by @m-schmook, I realized that if we append it later I'll
never get it right: I expect parameters min and max, not max and min!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: Protocol: you can now alter the `htlc_minimum_msat` and `htlc_maximum_msat` your node advertizes.
This commit is contained in:
Rusty Russell
2022-03-21 11:28:54 +10:30
parent f29890ed66
commit 999c734bb5
20 changed files with 186 additions and 43 deletions

View File

@@ -410,10 +410,11 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
secp256k1_ecdsa_signature *lease_commit_sig STEALS,
u32 lease_chan_max_msat,
u16 lease_chan_max_ppt,
struct amount_msat htlc_minimum_msat,
struct amount_msat htlc_maximum_msat)
{
struct channel *channel = tal(peer->ld, struct channel);
struct amount_msat htlc_max;
struct amount_msat htlc_min, htlc_max;
assert(dbid != 0);
channel->peer = peer;
@@ -509,8 +510,12 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
channel->blockheight_states = dup_height_states(channel, height_states);
channel->channel_update = NULL;
/* DB migration, for example, sets this to bignum; correct
* here */
/* DB migration, for example, sets min to 0, max to large: fixup */
htlc_min = channel->channel_info.their_config.htlc_minimum;
if (amount_msat_greater(htlc_min, htlc_minimum_msat))
channel->htlc_minimum_msat = htlc_min;
else
channel->htlc_minimum_msat = htlc_minimum_msat;
htlc_max = htlc_max_possible_send(channel);
if (amount_msat_less(htlc_max, htlc_maximum_msat))
channel->htlc_maximum_msat = htlc_max;

View File

@@ -196,8 +196,8 @@ struct channel {
* peer via option_data_loss_protect? */
const struct pubkey *future_per_commitment_point;
/* Max htlc amount allowed in channel. */
struct amount_msat htlc_maximum_msat;
/* Min/max htlc amount allowed in channel. */
struct amount_msat htlc_minimum_msat, htlc_maximum_msat;
/* Feerate per channel */
u32 feerate_base, feerate_ppm;
@@ -205,7 +205,7 @@ struct channel {
/* But allow these feerates/htlcs up until this time. */
struct timeabs old_feerate_timeout;
u32 old_feerate_base, old_feerate_ppm;
struct amount_msat old_htlc_maximum_msat;
struct amount_msat old_htlc_minimum_msat, old_htlc_maximum_msat;
/* If they used option_upfront_shutdown_script. */
const u8 *remote_upfront_shutdown_script;
@@ -315,6 +315,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid,
secp256k1_ecdsa_signature *lease_commit_sig STEALS,
u32 lease_chan_max_msat,
u16 lease_chan_max_ppt,
struct amount_msat htlc_minimum_msat,
struct amount_msat htlc_maximum_msat);
/* new_inflight - Create a new channel_inflight for a channel */

View File

@@ -702,6 +702,7 @@ void peer_start_channeld(struct channel *channel,
channel->opener,
channel->feerate_base,
channel->feerate_ppm,
channel->htlc_minimum_msat,
channel->htlc_maximum_msat,
channel->our_msat,
&channel->local_basepoints,

View File

@@ -1110,6 +1110,7 @@ wallet_update_channel(struct lightningd *ld,
channel->msat_to_us_min = our_msat;
channel->msat_to_us_max = our_msat;
channel->lease_expiry = lease_expiry;
channel->htlc_minimum_msat = channel->channel_info.their_config.htlc_minimum;
channel->htlc_maximum_msat = htlc_max_possible_send(channel);
tal_free(channel->lease_commit_sig);
@@ -1253,6 +1254,7 @@ wallet_commit_channel(struct lightningd *ld,
channel->lease_chan_max_msat = lease_chan_max_msat;
channel->lease_chan_max_ppt = lease_chan_max_ppt;
channel->htlc_minimum_msat = channel_info->their_config.htlc_minimum;
channel->htlc_maximum_msat = htlc_max_possible_send(channel);
/* Now we finally put it in the database. */

View File

@@ -210,6 +210,7 @@ wallet_commit_channel(struct lightningd *ld,
take(new_height_states(NULL, uc->fc ? LOCAL : REMOTE,
&lease_start_blockheight)),
0, NULL, 0, 0, /* No leases on v1s */
AMOUNT_MSAT(0), /* No htlc_minimum_msat */
AMOUNT_MSAT(-1ULL)); /* No htlc_maximum_msat */
/* Now we finally put it in the database. */

View File

@@ -861,6 +861,9 @@ static void json_add_channel(struct lightningd *ld,
channel->our_config.htlc_minimum,
"htlc_minimum_msat",
"minimum_htlc_in_msat");
json_add_amount_msat_only(response,
"minimum_htlc_out_msat",
channel->htlc_minimum_msat);
json_add_amount_msat_only(response,
"maximum_htlc_out_msat",
channel->htlc_maximum_msat);
@@ -2010,21 +2013,27 @@ static struct command_result *param_msat_u32(struct command *cmd,
static void set_channel_config(struct command *cmd, struct channel *channel,
u32 *base,
u32 *ppm,
struct amount_msat *htlc_min,
struct amount_msat *htlc_max,
u32 delaysecs,
struct json_stream *response,
bool add_details)
{
bool warn_cannot_set_min = false;
/* We only need to defer values if we *increase* fees (or drop
* max); we always allow users to overpay fees. */
* max, increase min); we always allow users to overpay fees. */
if ((base && *base > channel->feerate_base)
|| (ppm && *ppm > channel->feerate_ppm)
|| (htlc_min
&& amount_msat_greater(*htlc_min, channel->htlc_minimum_msat))
|| (htlc_max
&& amount_msat_less(*htlc_max, channel->htlc_maximum_msat))) {
channel->old_feerate_timeout
= timeabs_add(time_now(), time_from_sec(delaysecs));
channel->old_feerate_base = channel->feerate_base;
channel->old_feerate_ppm = channel->feerate_ppm;
channel->old_htlc_minimum_msat = channel->htlc_minimum_msat;
channel->old_htlc_maximum_msat = channel->htlc_maximum_msat;
}
@@ -2033,6 +2042,17 @@ static void set_channel_config(struct command *cmd, struct channel *channel,
channel->feerate_base = *base;
if (ppm)
channel->feerate_ppm = *ppm;
if (htlc_min) {
struct amount_msat actual_min;
/* We can't send something they'll refuse: check that here. */
actual_min = channel->channel_info.their_config.htlc_minimum;
if (amount_msat_less(*htlc_min, actual_min)) {
warn_cannot_set_min = true;
channel->htlc_minimum_msat = actual_min;
} else
channel->htlc_minimum_msat = *htlc_min;
}
if (htlc_max)
channel->htlc_maximum_msat = *htlc_max;
@@ -2040,7 +2060,7 @@ static void set_channel_config(struct command *cmd, struct channel *channel,
if (channel->owner && streq(channel->owner->name, "channeld"))
subd_send_msg(channel->owner,
take(towire_channeld_config_channel(NULL, base, ppm,
htlc_max)));
htlc_min, htlc_max)));
/* save values to database */
wallet_channel_save(cmd->ld->wallet, channel);
@@ -2059,6 +2079,12 @@ static void set_channel_config(struct command *cmd, struct channel *channel,
amount_msat(channel->feerate_base));
json_add_u32(response, "fee_proportional_millionths",
channel->feerate_ppm);
json_add_amount_msat_only(response,
"minimum_htlc_out_msat",
channel->htlc_minimum_msat);
if (warn_cannot_set_min)
json_add_string(response, "warning_htlcmin_too_low",
"Set minimum_htlc_out_msat to minimum allowed by peer");
json_add_amount_msat_only(response,
"maximum_htlc_out_msat",
channel->htlc_maximum_msat);
@@ -2110,13 +2136,13 @@ static struct command_result *json_setchannelfee(struct command *cmd,
channel->state != CHANNELD_AWAITING_LOCKIN &&
channel->state != DUALOPEND_AWAITING_LOCKIN)
continue;
set_channel_config(cmd, channel, base, ppm, NULL,
set_channel_config(cmd, channel, base, ppm, NULL, NULL,
*delaysecs, response, false);
}
/* single channel should be updated */
} else {
set_channel_config(cmd, channel, base, ppm, NULL,
set_channel_config(cmd, channel, base, ppm, NULL, NULL,
*delaysecs, response, false);
}
@@ -2149,13 +2175,14 @@ static struct command_result *json_setchannel(struct command *cmd,
struct peer *peer;
struct channel *channel;
u32 *base, *ppm, *delaysecs;
struct amount_msat *htlc_max;
struct amount_msat *htlc_min, *htlc_max;
/* Parse the JSON command */
if (!param(cmd, buffer, params,
p_req("id", param_channel_or_all, &channel),
p_opt("feebase", param_msat_u32, &base),
p_opt("feeppm", param_number, &ppm),
p_opt("htlcmin", param_msat, &htlc_min),
p_opt("htlcmax", param_msat, &htlc_max),
p_opt_def("enforcedelay", param_number, &delaysecs, 600),
NULL))
@@ -2182,13 +2209,15 @@ static struct command_result *json_setchannel(struct command *cmd,
channel->state != CHANNELD_AWAITING_LOCKIN &&
channel->state != DUALOPEND_AWAITING_LOCKIN)
continue;
set_channel_config(cmd, channel, base, ppm, htlc_max,
set_channel_config(cmd, channel, base, ppm,
htlc_min, htlc_max,
*delaysecs, response, true);
}
/* single channel should be updated */
} else {
set_channel_config(cmd, channel, base, ppm, htlc_max,
set_channel_config(cmd, channel, base, ppm,
htlc_min, htlc_max,
*delaysecs, response, true);
}

View File

@@ -656,16 +656,18 @@ static void forward_htlc(struct htlc_in *hin,
"Allowing payment using older feerate");
}
if (amount_msat_greater(amt_to_forward, next->htlc_maximum_msat)) {
/* Are we in old-max grace-period? */
if (amount_msat_greater(amt_to_forward, next->htlc_maximum_msat)
|| amount_msat_less(amt_to_forward, next->htlc_minimum_msat)) {
/* Are we in old-range grace-period? */
if (!time_before(time_now(), next->old_feerate_timeout)
|| amount_msat_less(amt_to_forward, next->old_htlc_minimum_msat)
|| amount_msat_greater(amt_to_forward, next->old_htlc_maximum_msat)) {
failmsg = towire_temporary_channel_failure(tmpctx,
get_channel_update(next));
goto fail;
}
log_info(hin->key.channel->log,
"Allowing large htlc using older htlc_maximum_msat");
"Allowing htlc using older htlc_minimum/maximum_msat");
}
if (!check_cltv(hin, cltv_expiry, outgoing_cltv_value,

View File

@@ -114,6 +114,8 @@ routehint_candidates(const tal_t *ctx,
continue;
}
/* FIXME: we don't actually check htlc_minimum_msat! */
/* If they set an htlc_maximum_msat, consider that the
* capacity ceiling. We *could* do multiple HTLCs,
* but presumably that would defeat the spirit of the

View File

@@ -626,7 +626,7 @@ void towire_bigsize(u8 **pptr UNNEEDED, const bigsize_t val UNNEEDED)
void towire_channel_id(u8 **pptr UNNEEDED, const struct channel_id *channel_id UNNEEDED)
{ fprintf(stderr, "towire_channel_id called!\n"); abort(); }
/* Generated stub for towire_channeld_config_channel */
u8 *towire_channeld_config_channel(const tal_t *ctx UNNEEDED, u32 *feerate_base UNNEEDED, u32 *feerate_ppm UNNEEDED, struct amount_msat *htlc_maximum UNNEEDED)
u8 *towire_channeld_config_channel(const tal_t *ctx UNNEEDED, u32 *feerate_base UNNEEDED, u32 *feerate_ppm UNNEEDED, struct amount_msat *htlc_minimum UNNEEDED, struct amount_msat *htlc_maximum UNNEEDED)
{ fprintf(stderr, "towire_channeld_config_channel called!\n"); abort(); }
/* Generated stub for towire_channeld_dev_memleak */
u8 *towire_channeld_dev_memleak(const tal_t *ctx UNNEEDED)