mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
opening: Add dev-allowdustreserve option to opt into dust reserves
Technically this is a non-conformance with the spec, hence the `dev` flag to opt-in, however I'm being told that it is also implemented in other implementations. I'll follow this up with a proposal to the spec to remove the checks we now bypass.
This commit is contained in:
2
Makefile
2
Makefile
@@ -258,8 +258,6 @@ endif
|
|||||||
CPPFLAGS += -DBINTOPKGLIBEXECDIR="\"$(shell sh tools/rel.sh $(bindir) $(pkglibexecdir))\""
|
CPPFLAGS += -DBINTOPKGLIBEXECDIR="\"$(shell sh tools/rel.sh $(bindir) $(pkglibexecdir))\""
|
||||||
CFLAGS = $(CPPFLAGS) $(CWARNFLAGS) $(CDEBUGFLAGS) $(COPTFLAGS) -I $(CCANDIR) $(EXTERNAL_INCLUDE_FLAGS) -I . -I$(CPATH) $(SQLITE3_CFLAGS) $(POSTGRES_INCLUDE) $(FEATURES) $(COVFLAGS) $(DEV_CFLAGS) -DSHACHAIN_BITS=48 -DJSMN_PARENT_LINKS $(PIE_CFLAGS) $(COMPAT_CFLAGS) -DBUILD_ELEMENTS=1
|
CFLAGS = $(CPPFLAGS) $(CWARNFLAGS) $(CDEBUGFLAGS) $(COPTFLAGS) -I $(CCANDIR) $(EXTERNAL_INCLUDE_FLAGS) -I . -I$(CPATH) $(SQLITE3_CFLAGS) $(POSTGRES_INCLUDE) $(FEATURES) $(COVFLAGS) $(DEV_CFLAGS) -DSHACHAIN_BITS=48 -DJSMN_PARENT_LINKS $(PIE_CFLAGS) $(COMPAT_CFLAGS) -DBUILD_ELEMENTS=1
|
||||||
|
|
||||||
CFLAGS += -DZERORESERVE=1
|
|
||||||
|
|
||||||
# If CFLAGS is already set in the environment of make (to whatever value, it
|
# If CFLAGS is already set in the environment of make (to whatever value, it
|
||||||
# does not matter) then it would export it to subprocesses with the above value
|
# does not matter) then it would export it to subprocesses with the above value
|
||||||
# we set, including CWARNFLAGS which by default contains -Wall -Werror. This
|
# we set, including CWARNFLAGS which by default contains -Wall -Werror. This
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ On success, an object is returned, containing:
|
|||||||
- **subdaemon** (string, optional): `subdaemon` fields from config or cmdline if any (can be more than one)
|
- **subdaemon** (string, optional): `subdaemon` fields from config or cmdline if any (can be more than one)
|
||||||
- **fetchinvoice-noconnect** (boolean, optional): `featchinvoice-noconnect` fileds from config or cmdline, or default
|
- **fetchinvoice-noconnect** (boolean, optional): `featchinvoice-noconnect` fileds from config or cmdline, or default
|
||||||
- **tor-service-password** (string, optional): `tor-service-password` field from config or cmdline, if any
|
- **tor-service-password** (string, optional): `tor-service-password` field from config or cmdline, if any
|
||||||
|
- **dev-allowdustreserve** (boolean, optional): Whether we allow setting dust reserves
|
||||||
|
|
||||||
[comment]: # (GENERATE-FROM-SCHEMA-END)
|
[comment]: # (GENERATE-FROM-SCHEMA-END)
|
||||||
|
|
||||||
@@ -216,4 +217,5 @@ RESOURCES
|
|||||||
---------
|
---------
|
||||||
|
|
||||||
Main web site: <https://github.com/ElementsProject/lightning>
|
Main web site: <https://github.com/ElementsProject/lightning>
|
||||||
[comment]: # ( SHA256STAMP:dcab86f29b946fed925de5e05cb79faa03cc4421cefeab3561a596ed5e64962d)
|
|
||||||
|
[comment]: # ( SHA256STAMP:310cc00ef62e7075d5d2588b0492c2dd96f507cc739f67d56ccc6c4f3135bca5)
|
||||||
|
|||||||
@@ -286,6 +286,10 @@
|
|||||||
"tor-service-password": {
|
"tor-service-password": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "`tor-service-password` field from config or cmdline, if any"
|
"description": "`tor-service-password` field from config or cmdline, if any"
|
||||||
|
},
|
||||||
|
"dev-allowdustreserve": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Whether we allow setting dust reserves"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,27 +146,28 @@ static void set_reserve_absolute(struct state * state, const struct amount_sat d
|
|||||||
{
|
{
|
||||||
status_debug("Setting their reserve to %s",
|
status_debug("Setting their reserve to %s",
|
||||||
type_to_string(tmpctx, struct amount_sat, &reserve_sat));
|
type_to_string(tmpctx, struct amount_sat, &reserve_sat));
|
||||||
#ifdef ZERORESERVE
|
if (state->allowdustreserve) {
|
||||||
state->localconf.channel_reserve = reserve_sat;
|
state->localconf.channel_reserve = reserve_sat;
|
||||||
#else
|
} else {
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
* The sending node:
|
* The sending node:
|
||||||
*...
|
*...
|
||||||
* - MUST set `channel_reserve_satoshis` greater than or equal to
|
* - MUST set `channel_reserve_satoshis` greater than or equal
|
||||||
* `dust_limit_satoshis` from the `open_channel` message.
|
*to `dust_limit_satoshis` from the `open_channel` message.
|
||||||
*/
|
*/
|
||||||
if (amount_sat_greater(dust_limit, reserve_sat)) {
|
if (amount_sat_greater(dust_limit, reserve_sat)) {
|
||||||
status_debug(
|
status_debug("Their reserve is too small, bumping to "
|
||||||
"Their reserve is too small, bumping to dust_limit: %s < %s",
|
"dust_limit: %s < %s",
|
||||||
type_to_string(tmpctx, struct amount_sat, &reserve_sat),
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
type_to_string(tmpctx, struct amount_sat, &dust_limit));
|
&reserve_sat),
|
||||||
state->localconf.channel_reserve
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
= dust_limit;
|
&dust_limit));
|
||||||
|
state->localconf.channel_reserve = dust_limit;
|
||||||
} else {
|
} else {
|
||||||
state->localconf.channel_reserve = reserve_sat;
|
state->localconf.channel_reserve = reserve_sat;
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We always set channel_reserve_satoshis to 1%, rounded down. */
|
/* We always set channel_reserve_satoshis to 1%, rounded down. */
|
||||||
@@ -464,8 +465,8 @@ static u8 *funder_channel_start(struct state *state, u8 channel_flags)
|
|||||||
type_to_string(msg, struct channel_id,
|
type_to_string(msg, struct channel_id,
|
||||||
&state->channel_id));
|
&state->channel_id));
|
||||||
|
|
||||||
#ifndef ZERORESERVE
|
if (!state->allowdustreserve &&
|
||||||
if (amount_sat_greater(state->remoteconf.dust_limit,
|
amount_sat_greater(state->remoteconf.dust_limit,
|
||||||
state->localconf.channel_reserve)) {
|
state->localconf.channel_reserve)) {
|
||||||
negotiation_failed(state,
|
negotiation_failed(state,
|
||||||
"dust limit %s"
|
"dust limit %s"
|
||||||
@@ -476,7 +477,6 @@ static u8 *funder_channel_start(struct state *state, u8 channel_flags)
|
|||||||
&state->localconf.channel_reserve));
|
&state->localconf.channel_reserve));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!check_config_bounds(tmpctx, state->funding_sats,
|
if (!check_config_bounds(tmpctx, state->funding_sats,
|
||||||
state->feerate_per_kw,
|
state->feerate_per_kw,
|
||||||
@@ -972,7 +972,8 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
|
|||||||
* - MUST set `dust_limit_satoshis` less than or equal to
|
* - MUST set `dust_limit_satoshis` less than or equal to
|
||||||
* `channel_reserve_satoshis` from the `open_channel` message.
|
* `channel_reserve_satoshis` from the `open_channel` message.
|
||||||
*/
|
*/
|
||||||
if (amount_sat_greater(state->remoteconf.dust_limit,
|
if (!state->allowdustreserve &&
|
||||||
|
amount_sat_greater(state->remoteconf.dust_limit,
|
||||||
state->localconf.channel_reserve)) {
|
state->localconf.channel_reserve)) {
|
||||||
negotiation_failed(state,
|
negotiation_failed(state,
|
||||||
"Our channel reserve %s"
|
"Our channel reserve %s"
|
||||||
|
|||||||
@@ -1740,17 +1740,20 @@ def test_zeroreserve(node_factory, bitcoind):
|
|||||||
- l2 enforces default reserve
|
- l2 enforces default reserve
|
||||||
- l3 enforces sub-dust reserves
|
- l3 enforces sub-dust reserves
|
||||||
"""
|
"""
|
||||||
ZEROCONF = True
|
|
||||||
plugin_path = Path(__file__).parent / "plugins" / "zeroreserve.py"
|
plugin_path = Path(__file__).parent / "plugins" / "zeroreserve.py"
|
||||||
opts = [
|
opts = [
|
||||||
{
|
{
|
||||||
'plugin': str(plugin_path),
|
'plugin': str(plugin_path),
|
||||||
'reserve': '0sat',
|
'reserve': '0sat',
|
||||||
|
'dev-allowdustreserve': True,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'dev-allowdustreserve': True,
|
||||||
},
|
},
|
||||||
{},
|
|
||||||
{
|
{
|
||||||
'plugin': str(plugin_path),
|
'plugin': str(plugin_path),
|
||||||
'reserve': '123sat'
|
'reserve': '123sat',
|
||||||
|
'dev-allowdustreserve': True,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
l1, l2, l3 = node_factory.get_nodes(3, opts=opts)
|
l1, l2, l3 = node_factory.get_nodes(3, opts=opts)
|
||||||
@@ -1780,16 +1783,16 @@ def test_zeroreserve(node_factory, bitcoind):
|
|||||||
l1c3 = l1.rpc.listpeers(l3.info['id'])['peers'][0]['channels'][0]
|
l1c3 = l1.rpc.listpeers(l3.info['id'])['peers'][0]['channels'][0]
|
||||||
|
|
||||||
# l1 imposed a 0sat reserve on l2, while l2 imposed the default 1% reserve on l1
|
# l1 imposed a 0sat reserve on l2, while l2 imposed the default 1% reserve on l1
|
||||||
assert l1c1['their_channel_reserve_satoshis'] == l2c1['our_channel_reserve_satoshis'] == (0 if ZEROCONF else 546)
|
assert l1c1['their_reserve_msat'] == l2c1['our_reserve_msat'] == Millisatoshi('0sat')
|
||||||
assert l1c1['our_channel_reserve_satoshis'] == l2c1['their_channel_reserve_satoshis'] == 10000
|
assert l1c1['our_reserve_msat'] == l2c1['their_reserve_msat'] == Millisatoshi('10000sat')
|
||||||
|
|
||||||
# l2 imposed the default 1% on l3, while l3 imposed a custom 123sat fee on l2
|
# l2 imposed the default 1% on l3, while l3 imposed a custom 123sat fee on l2
|
||||||
assert l2c2['their_channel_reserve_satoshis'] == l3c2['our_channel_reserve_satoshis'] == 10000
|
assert l2c2['their_reserve_msat'] == l3c2['our_reserve_msat'] == Millisatoshi('10000sat')
|
||||||
assert l2c2['our_channel_reserve_satoshis'] == l3c2['their_channel_reserve_satoshis'] == (123 if ZEROCONF else 546)
|
assert l2c2['our_reserve_msat'] == l3c2['their_reserve_msat'] == Millisatoshi('123sat')
|
||||||
|
|
||||||
# l3 imposed a custom 321sat fee on l1, while l1 imposed a custom 0sat fee on l3
|
# l3 imposed a custom 321sat fee on l1, while l1 imposed a custom 0sat fee on l3
|
||||||
assert l3c3['their_channel_reserve_satoshis'] == l1c3['our_channel_reserve_satoshis'] == (321 if ZEROCONF else 546)
|
assert l3c3['their_reserve_msat'] == l1c3['our_reserve_msat'] == Millisatoshi('321sat')
|
||||||
assert l3c3['our_channel_reserve_satoshis'] == l1c3['their_channel_reserve_satoshis'] == (0 if ZEROCONF else 546)
|
assert l3c3['our_reserve_msat'] == l1c3['their_reserve_msat'] == Millisatoshi('0sat')
|
||||||
|
|
||||||
# Now do some drain tests on c1, as that should be drainable
|
# Now do some drain tests on c1, as that should be drainable
|
||||||
# completely by l2 being the fundee
|
# completely by l2 being the fundee
|
||||||
|
|||||||
Reference in New Issue
Block a user