mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 06:41:44 +01:00
lightningd: new option for htlc dust limit
To reduce the surface area of amount of a channel balance that can be eaten up as htlc dust, we introduce a new config '--max-dust-htlc-exposure-msat', which sets the max amount that any channel's balance can be added as dust Changelog-Added: config: new option --max-dust-htlc-exposure-msat, which limits the total amount of sats to be allowed as dust on a channel
This commit is contained in:
parent
0f0a77e322
commit
1fe829c546
13 changed files with 62 additions and 5 deletions
|
@ -406,6 +406,8 @@ int main(int argc, const char *argv[])
|
||||||
|
|
||||||
local_config->max_htlc_value_in_flight = AMOUNT_MSAT(-1ULL);
|
local_config->max_htlc_value_in_flight = AMOUNT_MSAT(-1ULL);
|
||||||
remote_config->max_htlc_value_in_flight = AMOUNT_MSAT(-1ULL);
|
remote_config->max_htlc_value_in_flight = AMOUNT_MSAT(-1ULL);
|
||||||
|
local_config->max_dust_htlc_exposure_msat = AMOUNT_MSAT(-1ULL);
|
||||||
|
remote_config->max_dust_htlc_exposure_msat = AMOUNT_MSAT(-1ULL);
|
||||||
local_config->channel_reserve = AMOUNT_SAT(0);
|
local_config->channel_reserve = AMOUNT_SAT(0);
|
||||||
remote_config->channel_reserve = AMOUNT_SAT(0);
|
remote_config->channel_reserve = AMOUNT_SAT(0);
|
||||||
local_config->htlc_minimum = AMOUNT_MSAT(0);
|
local_config->htlc_minimum = AMOUNT_MSAT(0);
|
||||||
|
|
|
@ -9,6 +9,7 @@ void towire_channel_config(u8 **pptr, const struct channel_config *config)
|
||||||
towire_amount_msat(pptr, config->htlc_minimum);
|
towire_amount_msat(pptr, config->htlc_minimum);
|
||||||
towire_u16(pptr, config->to_self_delay);
|
towire_u16(pptr, config->to_self_delay);
|
||||||
towire_u16(pptr, config->max_accepted_htlcs);
|
towire_u16(pptr, config->max_accepted_htlcs);
|
||||||
|
towire_amount_msat(pptr, config->max_dust_htlc_exposure_msat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fromwire_channel_config(const u8 **ptr, size_t *max,
|
void fromwire_channel_config(const u8 **ptr, size_t *max,
|
||||||
|
@ -20,4 +21,5 @@ void fromwire_channel_config(const u8 **ptr, size_t *max,
|
||||||
config->htlc_minimum = fromwire_amount_msat(ptr, max);
|
config->htlc_minimum = fromwire_amount_msat(ptr, max);
|
||||||
config->to_self_delay = fromwire_u16(ptr, max);
|
config->to_self_delay = fromwire_u16(ptr, max);
|
||||||
config->max_accepted_htlcs = fromwire_u16(ptr, max);
|
config->max_accepted_htlcs = fromwire_u16(ptr, max);
|
||||||
|
config->max_dust_htlc_exposure_msat = fromwire_amount_msat(ptr, max);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,12 @@ struct channel_config {
|
||||||
* similarly, `max_accepted_htlcs` limits the number of outstanding
|
* similarly, `max_accepted_htlcs` limits the number of outstanding
|
||||||
* HTLCs the other node can offer. */
|
* HTLCs the other node can offer. */
|
||||||
u16 max_accepted_htlcs;
|
u16 max_accepted_htlcs;
|
||||||
|
|
||||||
|
/* BOLT-TBD #X
|
||||||
|
*
|
||||||
|
* maximum dust exposure allowed for this channel
|
||||||
|
*/
|
||||||
|
struct amount_msat max_dust_htlc_exposure_msat;
|
||||||
};
|
};
|
||||||
|
|
||||||
void towire_channel_config(u8 **pptr, const struct channel_config *config);
|
void towire_channel_config(u8 **pptr, const struct channel_config *config);
|
||||||
|
|
|
@ -149,6 +149,7 @@ static int parse_config(char *argv[],
|
||||||
config->max_htlc_value_in_flight = AMOUNT_MSAT(-1ULL);
|
config->max_htlc_value_in_flight = AMOUNT_MSAT(-1ULL);
|
||||||
config->htlc_minimum = AMOUNT_MSAT(0);
|
config->htlc_minimum = AMOUNT_MSAT(0);
|
||||||
config->max_accepted_htlcs = 483;
|
config->max_accepted_htlcs = 483;
|
||||||
|
config->max_dust_htlc_exposure_msat = AMOUNT_MSAT(-1ULL);
|
||||||
|
|
||||||
config->to_self_delay = atoi(argv[argnum]);
|
config->to_self_delay = atoi(argv[argnum]);
|
||||||
argnum++;
|
argnum++;
|
||||||
|
|
|
@ -71,6 +71,7 @@ On success, an object is returned, containing:
|
||||||
- **rescan** (integer, optional): `rescan` field from config or cmdline, or default
|
- **rescan** (integer, optional): `rescan` field from config or cmdline, or default
|
||||||
- **fee-per-satoshi** (u32, optional): `fee-per-satoshi` field from config or cmdline, or default
|
- **fee-per-satoshi** (u32, optional): `fee-per-satoshi` field from config or cmdline, or default
|
||||||
- **max-concurrent-htlcs** (u32, optional): `max-concurrent-htlcs` field from config or cmdline, or default
|
- **max-concurrent-htlcs** (u32, optional): `max-concurrent-htlcs` field from config or cmdline, or default
|
||||||
|
- **max-dust-htlc-exposure-msat** (msat, optional): `max-dust-htlc-exposure-mast` field from config or cmdline, or default
|
||||||
- **min-capacity-sat** (u64, optional): `min-capacity-sat` field from config or cmdline, or default
|
- **min-capacity-sat** (u64, optional): `min-capacity-sat` field from config or cmdline, or default
|
||||||
- **addr** (string, optional): `addr` field from config or cmdline (can be more than one)
|
- **addr** (string, optional): `addr` field from config or cmdline (can be more than one)
|
||||||
- **announce-addr** (string, optional): `announce-addr` field from config or cmdline (can be more than one)
|
- **announce-addr** (string, optional): `announce-addr` field from config or cmdline (can be more than one)
|
||||||
|
@ -206,4 +207,4 @@ RESOURCES
|
||||||
---------
|
---------
|
||||||
|
|
||||||
Main web site: <https://github.com/ElementsProject/lightning>
|
Main web site: <https://github.com/ElementsProject/lightning>
|
||||||
[comment]: # ( SHA256STAMP:47c067588120e0f9a71206313685cebb2a8c515e9b04b688b202d2772c8f8146)
|
[comment]: # ( SHA256STAMP:71a911b67203f75e7c1f717be611f505713fce4e8113fc4a84c89bc50730d2bf)
|
||||||
|
|
|
@ -183,6 +183,10 @@
|
||||||
"type": "u32",
|
"type": "u32",
|
||||||
"description": "`max-concurrent-htlcs` field from config or cmdline, or default"
|
"description": "`max-concurrent-htlcs` field from config or cmdline, or default"
|
||||||
},
|
},
|
||||||
|
"max-dust-htlc-exposure-msat": {
|
||||||
|
"type": "msat",
|
||||||
|
"description": "`max-dust-htlc-exposure-mast` field from config or cmdline, or default"
|
||||||
|
},
|
||||||
"min-capacity-sat": {
|
"min-capacity-sat": {
|
||||||
"type": "u64",
|
"type": "u64",
|
||||||
"description": "`min-capacity-sat` field from config or cmdline, or default"
|
"description": "`min-capacity-sat` field from config or cmdline, or default"
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <wallet/wallet.h>
|
#include <wallet/wallet.h>
|
||||||
|
|
||||||
|
struct amount_msat;
|
||||||
|
|
||||||
/* Various adjustable things. */
|
/* Various adjustable things. */
|
||||||
struct config {
|
struct config {
|
||||||
/* How long do we want them to lock up their funds? (blocks) */
|
/* How long do we want them to lock up their funds? (blocks) */
|
||||||
|
@ -31,6 +33,9 @@ struct config {
|
||||||
/* htlcs per channel */
|
/* htlcs per channel */
|
||||||
u32 max_concurrent_htlcs;
|
u32 max_concurrent_htlcs;
|
||||||
|
|
||||||
|
/* Max amount of dust allowed per channel */
|
||||||
|
struct amount_msat max_dust_htlc_exposure_msat;
|
||||||
|
|
||||||
/* How long between changing commit and sending COMMIT message. */
|
/* How long between changing commit and sending COMMIT message. */
|
||||||
u32 commit_time_ms;
|
u32 commit_time_ms;
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,9 @@ void channel_config(struct lightningd *ld,
|
||||||
ours->dust_limit = chainparams->dust_limit;
|
ours->dust_limit = chainparams->dust_limit;
|
||||||
ours->max_htlc_value_in_flight = AMOUNT_MSAT(UINT64_MAX);
|
ours->max_htlc_value_in_flight = AMOUNT_MSAT(UINT64_MAX);
|
||||||
|
|
||||||
|
ours->max_dust_htlc_exposure_msat
|
||||||
|
= ld->config.max_dust_htlc_exposure_msat;
|
||||||
|
|
||||||
/* Don't care */
|
/* Don't care */
|
||||||
ours->htlc_minimum = AMOUNT_MSAT(0);
|
ours->htlc_minimum = AMOUNT_MSAT(0);
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <common/features.h>
|
#include <common/features.h>
|
||||||
#include <common/hsm_encryption.h>
|
#include <common/hsm_encryption.h>
|
||||||
#include <common/json_command.h>
|
#include <common/json_command.h>
|
||||||
|
#include <common/json_helpers.h>
|
||||||
#include <common/json_tok.h>
|
#include <common/json_tok.h>
|
||||||
#include <common/param.h>
|
#include <common/param.h>
|
||||||
#include <common/type_to_string.h>
|
#include <common/type_to_string.h>
|
||||||
|
@ -671,6 +672,9 @@ static const struct config testnet_config = {
|
||||||
/* Testnet blockspace is free. */
|
/* Testnet blockspace is free. */
|
||||||
.max_concurrent_htlcs = 483,
|
.max_concurrent_htlcs = 483,
|
||||||
|
|
||||||
|
/* Max amount of dust allowed per channel (50ksat) */
|
||||||
|
.max_dust_htlc_exposure_msat = AMOUNT_MSAT(50000000),
|
||||||
|
|
||||||
/* Be aggressive on testnet. */
|
/* Be aggressive on testnet. */
|
||||||
.cltv_expiry_delta = 6,
|
.cltv_expiry_delta = 6,
|
||||||
.cltv_final = 10,
|
.cltv_final = 10,
|
||||||
|
@ -717,6 +721,9 @@ static const struct config mainnet_config = {
|
||||||
/* While up to 483 htlcs are possible we do 30 by default (as eclair does) to save blockspace */
|
/* While up to 483 htlcs are possible we do 30 by default (as eclair does) to save blockspace */
|
||||||
.max_concurrent_htlcs = 30,
|
.max_concurrent_htlcs = 30,
|
||||||
|
|
||||||
|
/* Max amount of dust allowed per channel (50ksat) */
|
||||||
|
.max_dust_htlc_exposure_msat = AMOUNT_MSAT(50000000),
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
* 1. the `cltv_expiry_delta` for channels, `3R+2G+2S`: if in doubt, a
|
* 1. the `cltv_expiry_delta` for channels, `3R+2G+2S`: if in doubt, a
|
||||||
|
@ -842,6 +849,14 @@ static char *opt_start_daemon(struct lightningd *ld)
|
||||||
errx(1, "Died with signal %u", WTERMSIG(exitcode));
|
errx(1, "Died with signal %u", WTERMSIG(exitcode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *opt_set_msat(const char *arg, struct amount_msat *amt)
|
||||||
|
{
|
||||||
|
if (!parse_amount_msat(amt, arg, strlen(arg)))
|
||||||
|
return tal_fmt(NULL, "Unable to parse millisatoshi '%s'", arg);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static char *opt_set_wumbo(struct lightningd *ld)
|
static char *opt_set_wumbo(struct lightningd *ld)
|
||||||
{
|
{
|
||||||
feature_set_or(ld->our_features,
|
feature_set_or(ld->our_features,
|
||||||
|
@ -1005,6 +1020,9 @@ static void register_opts(struct lightningd *ld)
|
||||||
opt_register_arg("--max-concurrent-htlcs", opt_set_u32, opt_show_u32,
|
opt_register_arg("--max-concurrent-htlcs", opt_set_u32, opt_show_u32,
|
||||||
&ld->config.max_concurrent_htlcs,
|
&ld->config.max_concurrent_htlcs,
|
||||||
"Number of HTLCs one channel can handle concurrently. Should be between 1 and 483");
|
"Number of HTLCs one channel can handle concurrently. Should be between 1 and 483");
|
||||||
|
opt_register_arg("--max-dust-htlc-exposure-msat", opt_set_msat,
|
||||||
|
NULL, &ld->config.max_dust_htlc_exposure_msat,
|
||||||
|
"Max HTLC amount that can be trimmed");
|
||||||
opt_register_arg("--min-capacity-sat", opt_set_u64, opt_show_u64,
|
opt_register_arg("--min-capacity-sat", opt_set_u64, opt_show_u64,
|
||||||
&ld->config.min_capacity_sat,
|
&ld->config.min_capacity_sat,
|
||||||
"Minimum capacity in satoshis for accepting channels");
|
"Minimum capacity in satoshis for accepting channels");
|
||||||
|
@ -1496,6 +1514,8 @@ static void add_config(struct lightningd *ld,
|
||||||
|| opt->cb_arg == (void *)plugin_opt_flag_set) {
|
|| opt->cb_arg == (void *)plugin_opt_flag_set) {
|
||||||
/* FIXME: We actually treat it as if they specified
|
/* FIXME: We actually treat it as if they specified
|
||||||
* --plugin for each one, so ignore these */
|
* --plugin for each one, so ignore these */
|
||||||
|
} else if (opt->cb_arg == (void *)opt_set_msat) {
|
||||||
|
json_add_amount_msat_only(response, name0, ld->config.max_dust_htlc_exposure_msat);
|
||||||
#if EXPERIMENTAL_FEATURES
|
#if EXPERIMENTAL_FEATURES
|
||||||
} else if (opt->cb_arg == (void *)opt_set_accept_extra_tlv_types) {
|
} else if (opt->cb_arg == (void *)opt_set_accept_extra_tlv_types) {
|
||||||
/* TODO Actually print the option */
|
/* TODO Actually print the option */
|
||||||
|
|
|
@ -134,6 +134,9 @@ static struct tx_state *new_tx_state(const tal_t *ctx)
|
||||||
tx_state->lease_chan_max_msat = 0;
|
tx_state->lease_chan_max_msat = 0;
|
||||||
tx_state->lease_chan_max_ppt = 0;
|
tx_state->lease_chan_max_ppt = 0;
|
||||||
|
|
||||||
|
/* no max_htlc_dust_exposure on remoteconf, we exclusively use the local's */
|
||||||
|
tx_state->remoteconf.max_dust_htlc_exposure_msat = AMOUNT_MSAT(0);
|
||||||
|
|
||||||
for (size_t i = 0; i < NUM_TX_MSGS; i++)
|
for (size_t i = 0; i < NUM_TX_MSGS; i++)
|
||||||
tx_state->tx_msg_count[i] = 0;
|
tx_state->tx_msg_count[i] = 0;
|
||||||
|
|
||||||
|
|
|
@ -1429,6 +1429,9 @@ int main(int argc, char *argv[])
|
||||||
memset(&state->channel_id, 0, sizeof(state->channel_id));
|
memset(&state->channel_id, 0, sizeof(state->channel_id));
|
||||||
state->channel = NULL;
|
state->channel = NULL;
|
||||||
|
|
||||||
|
/* Default this to zero, we only ever look at the local */
|
||||||
|
state->remoteconf.max_dust_htlc_exposure_msat = AMOUNT_MSAT(0);
|
||||||
|
|
||||||
/*~ We set these to NULL, meaning no requirements on shutdown */
|
/*~ We set these to NULL, meaning no requirements on shutdown */
|
||||||
state->upfront_shutdown_script[LOCAL]
|
state->upfront_shutdown_script[LOCAL]
|
||||||
= state->upfront_shutdown_script[REMOTE]
|
= state->upfront_shutdown_script[REMOTE]
|
||||||
|
|
|
@ -852,6 +852,9 @@ static struct migration dbmigrations[] = {
|
||||||
" shared_secret=NULL,"
|
" shared_secret=NULL,"
|
||||||
" localfailmsg=NULL"
|
" localfailmsg=NULL"
|
||||||
" WHERE (hstate=9 OR hstate=19);"), NULL},
|
" WHERE (hstate=9 OR hstate=19);"), NULL},
|
||||||
|
/* We default to 50k sats */
|
||||||
|
{SQL("ALTER TABLE channel_configs ADD max_dust_htlc_exposure_msat BIGINT DEFAULT 50000000"), NULL},
|
||||||
|
{SQL("ALTER TABLE channel_htlcs ADD fail_immediate INTEGER DEFAULT 0"), NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Leak tracking. */
|
/* Leak tracking. */
|
||||||
|
|
|
@ -1711,7 +1711,8 @@ static void wallet_channel_config_save(struct wallet *w,
|
||||||
" channel_reserve_satoshis=?,"
|
" channel_reserve_satoshis=?,"
|
||||||
" htlc_minimum_msat=?,"
|
" htlc_minimum_msat=?,"
|
||||||
" to_self_delay=?,"
|
" to_self_delay=?,"
|
||||||
" max_accepted_htlcs=?"
|
" max_accepted_htlcs=?,"
|
||||||
|
" max_dust_htlc_exposure_msat=?"
|
||||||
" WHERE id=?;"));
|
" WHERE id=?;"));
|
||||||
db_bind_amount_sat(stmt, 0, &cc->dust_limit);
|
db_bind_amount_sat(stmt, 0, &cc->dust_limit);
|
||||||
db_bind_amount_msat(stmt, 1, &cc->max_htlc_value_in_flight);
|
db_bind_amount_msat(stmt, 1, &cc->max_htlc_value_in_flight);
|
||||||
|
@ -1719,7 +1720,8 @@ static void wallet_channel_config_save(struct wallet *w,
|
||||||
db_bind_amount_msat(stmt, 3, &cc->htlc_minimum);
|
db_bind_amount_msat(stmt, 3, &cc->htlc_minimum);
|
||||||
db_bind_int(stmt, 4, cc->to_self_delay);
|
db_bind_int(stmt, 4, cc->to_self_delay);
|
||||||
db_bind_int(stmt, 5, cc->max_accepted_htlcs);
|
db_bind_int(stmt, 5, cc->max_accepted_htlcs);
|
||||||
db_bind_u64(stmt, 6, cc->id);
|
db_bind_amount_msat(stmt, 6, &cc->max_dust_htlc_exposure_msat);
|
||||||
|
db_bind_u64(stmt, 7, cc->id);
|
||||||
db_exec_prepared_v2(take(stmt));
|
db_exec_prepared_v2(take(stmt));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1731,7 +1733,8 @@ bool wallet_channel_config_load(struct wallet *w, const u64 id,
|
||||||
const char *query = SQL(
|
const char *query = SQL(
|
||||||
"SELECT id, dust_limit_satoshis, max_htlc_value_in_flight_msat, "
|
"SELECT id, dust_limit_satoshis, max_htlc_value_in_flight_msat, "
|
||||||
"channel_reserve_satoshis, htlc_minimum_msat, to_self_delay, "
|
"channel_reserve_satoshis, htlc_minimum_msat, to_self_delay, "
|
||||||
"max_accepted_htlcs FROM channel_configs WHERE id= ? ;");
|
"max_accepted_htlcs, max_dust_htlc_exposure_msat"
|
||||||
|
" FROM channel_configs WHERE id= ? ;");
|
||||||
struct db_stmt *stmt = db_prepare_v2(w->db, query);
|
struct db_stmt *stmt = db_prepare_v2(w->db, query);
|
||||||
db_bind_u64(stmt, 0, id);
|
db_bind_u64(stmt, 0, id);
|
||||||
db_query_prepared(stmt);
|
db_query_prepared(stmt);
|
||||||
|
@ -1746,7 +1749,8 @@ bool wallet_channel_config_load(struct wallet *w, const u64 id,
|
||||||
db_column_amount_msat(stmt, col++, &cc->htlc_minimum);
|
db_column_amount_msat(stmt, col++, &cc->htlc_minimum);
|
||||||
cc->to_self_delay = db_column_int(stmt, col++);
|
cc->to_self_delay = db_column_int(stmt, col++);
|
||||||
cc->max_accepted_htlcs = db_column_int(stmt, col++);
|
cc->max_accepted_htlcs = db_column_int(stmt, col++);
|
||||||
assert(col == 7);
|
db_column_amount_msat(stmt, col++, &cc->max_dust_htlc_exposure_msat);
|
||||||
|
assert(col == 8);
|
||||||
tal_free(stmt);
|
tal_free(stmt);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue