Browse Source

pytest: add dev hack for testing option_upfront_shutdown_script.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
htlc_accepted_hook
Rusty Russell 6 years ago
parent
commit
dddfdc7f10
  1. 1
      CHANGELOG.md
  2. 16
      openingd/openingd.c
  3. 53
      tests/test_closing.py

1
CHANGELOG.md

@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- JSON API: `listforwards` now includes the time an HTLC was received and when it was resolved. Both are expressed as UNIX timestamps to facilitate parsing (Issue [#2491](https://github.com/ElementsProject/lightning/issues/2491), PR [#2528](https://github.com/ElementsProject/lightning/pull/2528))
- JSON API: new plugin `invoice_payment` hook for intercepting invoices before they're paid.
- plugin: the `connected` hook can now send an `error_message` to the rejected peer.
- Protocol: we now enforce `option_upfront_shutdown_script` if a peer negotiates it.
### Changed

16
openingd/openingd.c

@ -110,6 +110,17 @@ struct state {
const struct chainparams *chainparams;
};
static const u8 *dev_upfront_shutdown_script(const tal_t *ctx)
{
#if DEVELOPER
/* This is a hack, for feature testing */
const char *e = getenv("DEV_OPENINGD_UPFRONT_SHUTDOWN_SCRIPT");
if (e)
return tal_hexdata(ctx, e, strlen(e));
#endif
return NULL;
}
/*~ If we can't agree on parameters, we fail to open the channel. If we're
* the funder, we need to tell lightningd, otherwise it never really notices. */
static void negotiation_aborted(struct state *state, bool am_funder,
@ -517,7 +528,8 @@ static u8 *funder_channel(struct state *state,
&state->our_points.delayed_payment,
&state->our_points.htlc,
&state->first_per_commitment_point[LOCAL],
channel_flags, NULL);
channel_flags,
dev_upfront_shutdown_script(tmpctx));
sync_crypto_write(&state->cs, PEER_FD, take(msg));
/* This is usually a very transient state... */
@ -1080,7 +1092,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
&state->our_points.delayed_payment,
&state->our_points.htlc,
&state->first_per_commitment_point[LOCAL],
NULL);
dev_upfront_shutdown_script(tmpctx));
sync_crypto_write(&state->cs, PEER_FD, take(msg));

53
tests/test_closing.py

@ -1491,3 +1491,56 @@ def test_shutdown(node_factory):
raise Exception("Node {} has memory leaks: {}"
.format(l1.daemon.lightning_dir, leaks))
l1.rpc.stop()
@unittest.skipIf(not DEVELOPER, "needs to set upfront_shutdown_script")
def test_option_upfront_shutdown_script(node_factory, bitcoind):
l1 = node_factory.get_node(start=False)
# Insist on upfront script we're not going to match.
l1.daemon.env["DEV_OPENINGD_UPFRONT_SHUTDOWN_SCRIPT"] = "76a91404b61f7dc1ea0dc99424464cc4064dc564d91e8988ac"
l1.start()
l2 = node_factory.get_node()
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.fund_channel(l2, 1000000, False)
l1.rpc.close(l2.info['id'])
# l2 will close unilaterally when it dislikes shutdown script.
l1.daemon.wait_for_log(r'received ERROR.*scriptpubkey .* is not as agreed upfront \(76a91404b61f7dc1ea0dc99424464cc4064dc564d91e8988ac\)')
# Clear channel.
wait_for(lambda: len(bitcoind.rpc.getrawmempool()) != 0)
bitcoind.generate_block(1)
wait_for(lambda: [c['state'] for c in only_one(l1.rpc.listpeers()['peers'])['channels']] == ['ONCHAIN'])
# Works when l2 closes channel, too.
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
l1.fund_channel(l2, 1000000, False)
l2.rpc.close(l1.info['id'])
# l2 will close unilaterally when it dislikes shutdown script.
l1.daemon.wait_for_log(r'received ERROR.*scriptpubkey .* is not as agreed upfront \(76a91404b61f7dc1ea0dc99424464cc4064dc564d91e8988ac\)')
# Clear channel.
wait_for(lambda: len(bitcoind.rpc.getrawmempool()) != 0)
bitcoind.generate_block(1)
wait_for(lambda: [c['state'] for c in only_one(l1.rpc.listpeers()['peers'])['channels']] == ['ONCHAIN', 'ONCHAIN'])
# Figure out what address it will try to use.
keyidx = int(l1.db_query("SELECT val FROM vars WHERE name='bip32_max_index';")[0]['val'])
# Expect 1 for change address, 1 for the channel final address.
addr = l1.rpc.call('dev-listaddrs', [keyidx + 2])['addresses'][-1]
# Now, if we specify upfront and it's OK, all good.
l1.stop()
# We need to prepend the segwit version (0) and push opcode (14).
l1.daemon.env["DEV_OPENINGD_UPFRONT_SHUTDOWN_SCRIPT"] = '0014' + addr['bech32_redeemscript']
l1.start()
l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
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'])

Loading…
Cancel
Save