From ca28c30eff782c3e06fdb2d5028a8ca04890494a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Aug 2019 20:18:20 +0930 Subject: [PATCH] funding: don't allow funding new channels until we're synced. This is probably worth preventing. 1. Our depth estimate would be inaccurate possibly leading to us timing out too early. 2. If we're not up-to-date our onchain funds are unknown. 3. We wouldn't be able to send or receive HTLCs until we're synced anyway. Signed-off-by: Rusty Russell --- CHANGELOG.md | 2 ++ common/jsonrpc_errors.h | 1 + doc/lightning-fundchannel.7 | 15 +++++++++++++-- doc/lightning-fundchannel.7.txt | 1 + lightningd/opening_control.c | 10 ++++++++++ tests/test_misc.py | 19 +++++++++++++++---- 6 files changed, 42 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 820ea7d98..6d89720d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,8 @@ changes. - channeld: ignore, and simply try reconnecting if lnd sends "sync error". - Protocol: we now correctly ignore unknown odd messages. - wallet: We will now backfill blocks below our wallet start height on demand when we require them to verify gossip messages. This fixes an issue where we would not remove channels on spend that were opened below that start height because we weren't tracking the funding output. +- Detect when we're still syncing with bitcoin network: don't send or receive + HTLCs or allow `fundchannel`. ### Security diff --git a/common/jsonrpc_errors.h b/common/jsonrpc_errors.h index 473142e37..8b5fa03c7 100644 --- a/common/jsonrpc_errors.h +++ b/common/jsonrpc_errors.h @@ -40,6 +40,7 @@ #define FUND_CANNOT_AFFORD 301 #define FUND_OUTPUT_IS_DUST 302 #define FUNDING_BROADCAST_FAIL 303 +#define FUNDING_STILL_SYNCING_BITCOIN 304 /* Errors from `invoice` command */ #define INVOICE_LABEL_ALREADY_EXISTS 900 diff --git a/doc/lightning-fundchannel.7 b/doc/lightning-fundchannel.7 index 082c4f852..4b8533b90 100644 --- a/doc/lightning-fundchannel.7 +++ b/doc/lightning-fundchannel.7 @@ -2,12 +2,12 @@ .\" Title: lightning-fundchannel .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.79.1 -.\" Date: 05/24/2019 +.\" Date: 08/07/2019 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "LIGHTNING\-FUNDCHANN" "7" "06/07/2019" "\ \&" "\ \&" +.TH "LIGHTNING\-FUNDCHANN" "7" "08/07/2019" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -110,6 +110,17 @@ The following error codes may occur: 303\&. Broadcasting of the funding transaction failed, the internal call to bitcoin\-cli returned with an error\&. .RE .sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +.sp -1 +.IP \(bu 2.3 +.\} +304\&. We\(cqre still syncing with the bitcoin network\&. Retry later\&. +.RE +.sp Failure may also occur if \fBlightningd\fR and the peer cannot agree on channel parameters (funding limits, channel reserves, fees, etc\&.)\&. .SH "SEE ALSO" .sp diff --git a/doc/lightning-fundchannel.7.txt b/doc/lightning-fundchannel.7.txt index 73f3f98f5..4ddd115fe 100644 --- a/doc/lightning-fundchannel.7.txt +++ b/doc/lightning-fundchannel.7.txt @@ -62,6 +62,7 @@ The following error codes may occur: * 302. The output amount is too small, and would be considered dust. * 303. Broadcasting of the funding transaction failed, the internal call to bitcoin-cli returned with an error. +* 304. We're still syncing with the bitcoin network. Retry later. Failure may also occur if *lightningd* and the peer cannot agree on channel parameters (funding limits, channel reserves, fees, etc.). diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index 17efc3950..ba59b2bac 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -1273,6 +1273,11 @@ static struct command_result *json_fund_channel_start(struct command *cmd, "Feerate below feerate floor"); } + if (!topology_synced(cmd->ld->topology)) { + return command_fail(cmd, FUNDING_STILL_SYNCING_BITCOIN, + "Still syncing with bitcoin network"); + } + peer = peer_by_id(cmd->ld, id); if (!peer) { return command_fail(cmd, LIGHTNINGD, "Unknown peer"); @@ -1365,6 +1370,11 @@ static struct command_result *json_fund_channel(struct command *cmd, "Feerate below feerate floor"); } + if (!topology_synced(cmd->ld->topology)) { + return command_fail(cmd, FUNDING_STILL_SYNCING_BITCOIN, + "Still syncing with bitcoin network"); + } + peer = peer_by_id(cmd->ld, id); if (!peer) { return command_fail(cmd, LIGHTNINGD, "Unknown peer"); diff --git a/tests/test_misc.py b/tests/test_misc.py index 38689253d..2480809d7 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -152,16 +152,22 @@ def test_lightningd_still_loading(node_factory, bitcoind, executor): "id": r['id'] } - # Start it, establish channel. + # Start it, establish channel, get extra funds. l1, l2 = node_factory.line_graph(2, opts={'may_reconnect': True}) - # Balance channel. + # Extra funds, for second channel attempt. + bitcoind.rpc.sendtoaddress(l1.rpc.newaddr()['bech32'], 1.0) + # Balance l1<->l2 channel l1.pay(l2, 10**9 // 2) + l1.stop() + # Start extra node. + l3 = node_factory.get_node() + # Now make sure it's behind. bitcoind.generate_block(2) - # Make sure l2 is synced - sync_blockheight(bitcoind, [l2]) + # Make sure l2/l3 are synced + sync_blockheight(bitcoind, [l2, l3]) # Make it slow grabbing the final block. slow_blockid = bitcoind.rpc.getblockhash(bitcoind.rpc.getblockcount()) @@ -177,6 +183,11 @@ def test_lightningd_still_loading(node_factory, bitcoind, executor): with pytest.raises(RpcError, match=r'TEMPORARY_CHANNEL_FAILURE'): l1.pay(l2, 1000) + # Can't fund a new channel, either. + l1.rpc.connect(l3.info['id'], 'localhost', l3.port) + with pytest.raises(RpcError, match=r'304'): + l1.rpc.fundchannel(l3.info['id'], 'all') + # This will work, but will be delayed until synced. fut = executor.submit(l2.pay, l1, 1000) l1.daemon.wait_for_log("Deferring incoming commit until we sync")