openingd: check upfront shutdown script.
The spec doesn't say to do this, but it makes sense, otherwise they'll never be able to mutually close the channel. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
66dda32da2
commit
26627bdf7d
|
@ -75,6 +75,7 @@ OPENINGD_COMMON_OBJS := \
|
||||||
common/pseudorand.o \
|
common/pseudorand.o \
|
||||||
common/read_peer_msg.o \
|
common/read_peer_msg.o \
|
||||||
common/setup.o \
|
common/setup.o \
|
||||||
|
common/shutdown_scriptpubkey.o \
|
||||||
common/status.o \
|
common/status.o \
|
||||||
common/status_wire.o \
|
common/status_wire.o \
|
||||||
common/subdaemon.o \
|
common/subdaemon.o \
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include <common/peer_status_wiregen.h>
|
#include <common/peer_status_wiregen.h>
|
||||||
#include <common/penalty_base.h>
|
#include <common/penalty_base.h>
|
||||||
#include <common/read_peer_msg.h>
|
#include <common/read_peer_msg.h>
|
||||||
|
#include <common/shutdown_scriptpubkey.h>
|
||||||
#include <common/status.h>
|
#include <common/status.h>
|
||||||
#include <common/subdaemon.h>
|
#include <common/subdaemon.h>
|
||||||
#include <common/type_to_string.h>
|
#include <common/type_to_string.h>
|
||||||
|
@ -321,6 +322,20 @@ static bool setup_channel_funder(struct state *state)
|
||||||
return true;
|
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
|
/* 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 */
|
* stop when we get to the part where we need the funding txid */
|
||||||
static u8 *funder_channel_start(struct state *state, u8 channel_flags)
|
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,
|
&state->channel_id,
|
||||||
"Parsing accept_channel %s", tal_hex(msg, msg));
|
"Parsing accept_channel %s", tal_hex(msg, msg));
|
||||||
}
|
}
|
||||||
state->upfront_shutdown_script[REMOTE]
|
set_remote_upfront_shutdown(state, accept_tlvs->upfront_shutdown_script);
|
||||||
= tal_steal(state, accept_tlvs->upfront_shutdown_script);
|
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
|
@ -764,8 +778,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
|
||||||
peer_failed_err(state->pps,
|
peer_failed_err(state->pps,
|
||||||
&state->channel_id,
|
&state->channel_id,
|
||||||
"Parsing open_channel %s", tal_hex(tmpctx, open_channel_msg));
|
"Parsing open_channel %s", tal_hex(tmpctx, open_channel_msg));
|
||||||
state->upfront_shutdown_script[REMOTE]
|
set_remote_upfront_shutdown(state, open_tlvs->upfront_shutdown_script);
|
||||||
= tal_steal(state, open_tlvs->upfront_shutdown_script);
|
|
||||||
|
|
||||||
/* BOLT #2:
|
/* BOLT #2:
|
||||||
*
|
*
|
||||||
|
|
|
@ -2594,3 +2594,18 @@ def test_option_upfront_shutdown_script(node_factory, bitcoind, executor):
|
||||||
l1.rpc.fundchannel(l2.info['id'], 1000000)
|
l1.rpc.fundchannel(l2.info['id'], 1000000)
|
||||||
l1.rpc.close(l2.info['id'])
|
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'])
|
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)
|
||||||
|
|
Loading…
Reference in New Issue