diff --git a/openingd/Makefile b/openingd/Makefile index 0bb195566..f1dc699fe 100644 --- a/openingd/Makefile +++ b/openingd/Makefile @@ -75,6 +75,7 @@ OPENINGD_COMMON_OBJS := \ common/pseudorand.o \ common/read_peer_msg.o \ common/setup.o \ + common/shutdown_scriptpubkey.o \ common/status.o \ common/status_wire.o \ common/subdaemon.o \ diff --git a/openingd/openingd.c b/openingd/openingd.c index 6ef88dd62..421493f27 100644 --- a/openingd/openingd.c +++ b/openingd/openingd.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -321,6 +322,20 @@ static bool setup_channel_funder(struct state *state) return true; } +static void set_remote_upfront_shutdown(struct state *state, + u8 *shutdown_scriptpubkey STEALS) +{ + state->upfront_shutdown_script[REMOTE] + = tal_steal(state, shutdown_scriptpubkey); + + if (shutdown_scriptpubkey + && !valid_shutdown_scriptpubkey(shutdown_scriptpubkey)) + peer_failed_err(state->pps, + &state->channel_id, + "Unacceptable upfront_shutdown_script %s", + tal_hex(tmpctx, shutdown_scriptpubkey)); +} + /* We start the 'open a channel' negotation with the supplied peer, but * stop when we get to the part where we need the funding txid */ static u8 *funder_channel_start(struct state *state, u8 channel_flags) @@ -404,8 +419,7 @@ static u8 *funder_channel_start(struct state *state, u8 channel_flags) &state->channel_id, "Parsing accept_channel %s", tal_hex(msg, msg)); } - state->upfront_shutdown_script[REMOTE] - = tal_steal(state, accept_tlvs->upfront_shutdown_script); + set_remote_upfront_shutdown(state, accept_tlvs->upfront_shutdown_script); /* BOLT #2: * @@ -764,8 +778,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) peer_failed_err(state->pps, &state->channel_id, "Parsing open_channel %s", tal_hex(tmpctx, open_channel_msg)); - state->upfront_shutdown_script[REMOTE] - = tal_steal(state, open_tlvs->upfront_shutdown_script); + set_remote_upfront_shutdown(state, open_tlvs->upfront_shutdown_script); /* BOLT #2: * diff --git a/tests/test_closing.py b/tests/test_closing.py index 7dc472756..2a2a74a26 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -2594,3 +2594,18 @@ def test_option_upfront_shutdown_script(node_factory, bitcoind, executor): l1.rpc.fundchannel(l2.info['id'], 1000000) l1.rpc.close(l2.info['id']) wait_for(lambda: sorted([c['state'] for c in only_one(l1.rpc.listpeers()['peers'])['channels']]) == ['CLOSINGD_COMPLETE', 'ONCHAIN', 'ONCHAIN']) + + +@unittest.skipIf(not DEVELOPER, "needs to set upfront_shutdown_script") +def test_invalid_upfront_shutdown_script(node_factory, bitcoind, executor): + l1, l2 = node_factory.line_graph(2, fundchannel=False) + + l1 = node_factory.get_node(start=False, allow_warning=True) + # Insist on upfront script we're not going to match. + l1.daemon.env["DEV_OPENINGD_UPFRONT_SHUTDOWN_SCRIPT"] = "76a91404b61f7dc1ea0dc99424464cc4064dc564d91e8988ac00" + l1.start() + + l2 = node_factory.get_node() + l1.rpc.connect(l2.info['id'], 'localhost', l2.port) + with pytest.raises(RpcError, match=r'Unacceptable upfront_shutdown_script'): + l1.fundchannel(l2, 1000000, False)