Skip to content

Commit

Permalink
pytest: test that the preapprove hooks get called by check.
Browse files Browse the repository at this point in the history
We add a dev flag so we can decline them.

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Feb 27, 2024
1 parent 1fb80a3 commit 76aff02
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 0 deletions.
7 changes: 7 additions & 0 deletions lightningd/invoice.c
Original file line number Diff line number Diff line change
Expand Up @@ -1954,6 +1954,10 @@ static struct command_result *json_preapproveinvoice(struct command *cmd,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"HSM gave bad preapprove_invoice_reply %s", tal_hex(msg, msg));

/* FIXME: hand this to hsm_init so it can do this, for deeper testing! */
if (cmd->ld->dev_never_preapprove)
approved = false;

if (!approved)
return command_fail(cmd, PAY_INVOICE_PREAPPROVAL_DECLINED, "invoice was declined");

Expand Down Expand Up @@ -1995,6 +1999,9 @@ static struct command_result *json_preapprovekeysend(struct command *cmd,
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"HSM gave bad preapprove_keysend_reply %s", tal_hex(msg, msg));

if (cmd->ld->dev_never_preapprove)
approved = false;

if (!approved)
return command_fail(cmd, PAY_KEYSEND_PREAPPROVAL_DECLINED, "keysend was declined");

Expand Down
1 change: 1 addition & 0 deletions lightningd/lightningd.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
ld->dev_force_tmp_channel_id = NULL;
ld->dev_no_htlc_timeout = false;
ld->dev_no_version_checks = false;
ld->dev_never_preapprove = false;
ld->dev_max_funding_unconfirmed = 2016;
ld->dev_ignore_modern_onion = false;
ld->dev_disable_commit = -1;
Expand Down
1 change: 1 addition & 0 deletions lightningd/lightningd.h
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ struct lightningd {
bool dev_no_htlc_timeout;

bool dev_no_version_checks;
bool dev_never_preapprove;

/* Number of blocks we wait for a channel to get funded
* if we are the fundee. */
Expand Down
4 changes: 4 additions & 0 deletions lightningd/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,10 @@ static void dev_register_opts(struct lightningd *ld)
opt_set_bool,
&ld->dev_allow_shutdown_destination_change,
"Allow destination override on close, even if risky");
clnopt_noarg("--dev-never-preapprove", OPT_DEV,
opt_set_bool,
&ld->dev_never_preapprove,
"Disallow preapproveinvoice and preapprovekeysend (for testing)");
}

static const struct config testnet_config = {
Expand Down
23 changes: 23 additions & 0 deletions tests/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -3995,3 +3995,26 @@ def test_set_feerate_offset(node_factory, bitcoind):

l1.daemon.wait_for_log(' to CLOSINGD_COMPLETE')
l2.daemon.wait_for_log(' to CLOSINGD_COMPLETE')


def test_preapprove(node_factory, bitcoind):
l1, l2 = node_factory.line_graph(2, opts=[{}, {'dev-never-preapprove': None}])

# Create some balance, make sure it's entirely settled.
l1.pay(l2, 200000000)
wait_for(lambda: only_one(l2.rpc.listpeerchannels()['channels'])['htlcs'] == [])

# This will fail at the preapprove step.
inv = l1.rpc.invoice(123000, 'label', 'description', 3700)['bolt11']
with pytest.raises(RpcError, match='invoice was declined'):
l2.rpc.pay(inv)

# This will fail the same way
with pytest.raises(RpcError, match='invoice was declined'):
l2.rpc.check('pay', bolt11=inv)

# Now keysend.
with pytest.raises(RpcError, match='keysend was declined'):
l2.rpc.keysend(l1.info['id'], 1000)
with pytest.raises(RpcError, match='keysend was declined'):
l2.rpc.check('keysend', destination=l1.info['id'], amount_msat=1000)

0 comments on commit 76aff02

Please sign in to comment.