lightningd: add large-channels / wumbo option.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-added: `large-channels` option to negotiate opening larger channels.
This commit is contained in:
Rusty Russell 2020-04-03 10:33:58 +10:30
parent 1d90f21833
commit 07a281faf8
4 changed files with 77 additions and 1 deletions

View File

@ -281,6 +281,14 @@ extremely busy node for you to even notice\.
.SH Lightning channel and HTLC options
\fBlarge-channels\fR
Removes capacity limits for channel creation\. Version 1\.0 of the specification
limited channel sizes to 16777216 satoshi\. With this option (which your
node will advertize to peers), your node will accept larger incoming channels
and if the peer supports it, will open larger channels\. Note: this option
is spelled \fBlarge-channels\fR but it's pronounced \fBwumbo\fR\.
\fBwatchtime-blocks\fR=\fIBLOCKS\fR
How long we need to spot an outdated close attempt: on opening a channel
we tell our peer that this is how long theyll have to wait if they

View File

@ -230,6 +230,13 @@ extremely busy node for you to even notice.
### Lightning channel and HTLC options
**large-channels**
Removes capacity limits for channel creation. Version 1.0 of the specification
limited channel sizes to 16777215 satoshi. With this option (which your
node will advertize to peers), your node will accept larger incoming channels
and if the peer supports it, will open larger channels. Note: this option
is spelled **large-channels** but it's pronounced **wumbo**.
**watchtime-blocks**=*BLOCKS*
How long we need to spot an outdated close attempt: on opening a channel
we tell our peer that this is how long theyll have to wait if they

View File

@ -742,6 +742,14 @@ static char *opt_start_daemon(struct lightningd *ld)
errx(1, "Died with signal %u", WTERMSIG(exitcode));
}
static char *opt_set_wumbo(struct lightningd *ld)
{
feature_set_or(ld->feature_set,
take(feature_set_for_feature(NULL,
OPTIONAL_FEATURE(OPT_LARGE_CHANNELS))));
return NULL;
}
static void register_opts(struct lightningd *ld)
{
/* This happens before plugins started */
@ -774,6 +782,11 @@ static void register_opts(struct lightningd *ld)
&ld->wallet_dsn,
"Location of the wallet database.");
/* This affects our features, so set early. */
opt_register_early_noarg("--large-channels|--wumbo",
opt_set_wumbo, ld,
"Allow channels larger than 0.16777215 BTC");
opt_register_noarg("--help|-h", opt_lightningd_usage, ld,
"Print this message.");
opt_register_arg("--rgb", opt_set_rgb, NULL, ld,
@ -1188,6 +1201,10 @@ static void add_config(struct lightningd *ld,
? "false" : "true");
} else if (opt->cb == (void *)opt_set_hsm_password) {
json_add_bool(response, "encrypted-hsm", ld->encrypted_hsm);
} else if (opt->cb == (void *)opt_set_wumbo) {
json_add_bool(response, "wumbo",
feature_offered(ld->feature_set->bits[INIT_FEATURE],
OPT_LARGE_CHANNELS));
} else {
/* Insert more decodes here! */
assert(!"A noarg option was added but was not handled");

View File

@ -3,7 +3,7 @@ from decimal import Decimal
from fixtures import * # noqa: F401,F403
from fixtures import TEST_NETWORK
from flaky import flaky # noqa: F401
from pyln.client import RpcError
from pyln.client import RpcError, Millisatoshi
from utils import (
DEVELOPER, only_one, wait_for, sync_blockheight, VALGRIND, TIMEOUT,
SLOW_MACHINE, expected_features
@ -2220,3 +2220,47 @@ def test_pay_disconnect_stress(node_factory, executor):
pass
fut.result()
def test_wumbo_channels(node_factory, bitcoind):
f = bytes.fromhex(expected_features())
# OPT_LARGE_CHANNELS = 18 (19 for us). 0x080000
f = (f[:-3] + bytes([f[-3] | 0x08]) + f[-2:]).hex()
l1, l2, l3 = node_factory.get_nodes(3,
opts=[{'large-channels': None},
{'large-channels': None},
{}])
conn = l1.rpc.connect(l2.info['id'], 'localhost', port=l2.port)
assert conn['features'] == f
assert only_one(l1.rpc.listpeers(l2.info['id'])['peers'])['features'] == f
# Now, can we open a giant channel?
l1.fundwallet(1 << 26)
l1.rpc.fundchannel(l2.info['id'], 1 << 24)
# Get that mined, and announced.
bitcoind.generate_block(6, wait_for_mempool=1)
# Connect l3, get gossip.
l3.rpc.connect(l1.info['id'], 'localhost', port=l1.port)
wait_for(lambda: len(l3.rpc.listnodes(l1.info['id'])['nodes']) == 1)
wait_for(lambda: 'features' in only_one(l3.rpc.listnodes(l1.info['id'])['nodes']))
# Make sure channel capacity is what we expected.
assert ([c['amount_msat'] for c in l3.rpc.listchannels()['channels']]
== [Millisatoshi(str(1 << 24) + "sat")] * 2)
# Make sure we can't open a wumbo channel if we don't agree.
with pytest.raises(RpcError, match='Amount exceeded'):
l1.rpc.fundchannel(l3.info['id'], 1 << 24)
# But we can open and announce a normal one.
l1.rpc.fundchannel(l3.info['id'], 'all')
bitcoind.generate_block(6, wait_for_mempool=1)
wait_for(lambda: l1.channel_state(l3) == 'CHANNELD_NORMAL')
# Make sure l2 sees correct size.
wait_for(lambda: [c['amount_msat'] for c in l2.rpc.listchannels(l1.get_channel_scid(l3))['channels']]
== [Millisatoshi(str((1 << 24) - 1) + "sat")] * 2)