Skip to content

Commit bb38f83

Browse files
committed
checkrune: make nodeid and method optional.
nodeid is only useful when we know the peer we're talking to (e.g. commando). Signed-off-by: Rusty Russell <[email protected]> No-schema-diff-check: We're simply making optional, not deprecating!
1 parent bbb3459 commit bb38f83

File tree

4 files changed

+60
-13
lines changed

4 files changed

+60
-13
lines changed

doc/lightning-checkrune.7.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ lightning-checkrune -- Command to Validate Rune
44
SYNOPSIS
55
--------
66

7-
**checkrune** *rune* *nodeid* *method* [*params*]
7+
**checkrune** *rune* [*nodeid*] [*method*] [*params*]
88

99
DESCRIPTION
1010
-----------

doc/schemas/checkrune.request.json

+3-5
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
"type": "object",
44
"additionalProperties": false,
55
"required": [
6-
"nodeid",
7-
"rune",
8-
"method"
6+
"rune"
97
],
108
"added": "v23.08",
119
"properties": {
@@ -15,11 +13,11 @@
1513
},
1614
"nodeid": {
1715
"type": "string",
18-
"description": "node id of your node"
16+
"description": "node id of requesting node *(required until v23.11)*"
1917
},
2018
"method": {
2119
"type": "string",
22-
"description": "method for which rune needs to be validated"
20+
"description": "method for which rune needs to be validated *(required until v23.11)*"
2321
},
2422
"params": {
2523
"oneOf": [

lightningd/runes.c

+13-7
Original file line numberDiff line numberDiff line change
@@ -674,11 +674,17 @@ static const char *check_condition(const tal_t *ctx,
674674
if (streq(alt->fieldname, "time")) {
675675
return rune_alt_single_int(ctx, alt, time_now().ts.tv_sec);
676676
} else if (streq(alt->fieldname, "id")) {
677-
const char *id = node_id_to_hexstr(tmpctx, cinfo->peer);
678-
return rune_alt_single_str(ctx, alt, id, strlen(id));
677+
if (cinfo->peer) {
678+
const char *id = node_id_to_hexstr(tmpctx, cinfo->peer);
679+
return rune_alt_single_str(ctx, alt, id, strlen(id));
680+
}
681+
return rune_alt_single_missing(ctx, alt);
679682
} else if (streq(alt->fieldname, "method")) {
680-
return rune_alt_single_str(ctx, alt,
681-
cinfo->method, strlen(cinfo->method));
683+
if (cinfo->method) {
684+
return rune_alt_single_str(ctx, alt,
685+
cinfo->method, strlen(cinfo->method));
686+
}
687+
return rune_alt_single_missing(ctx, alt);
682688
} else if (streq(alt->fieldname, "pnum")) {
683689
return rune_alt_single_int(ctx, alt, (cinfo && cinfo->params) ? cinfo->params->size : 0);
684690
} else if (streq(alt->fieldname, "rate")) {
@@ -748,8 +754,8 @@ static struct command_result *json_checkrune(struct command *cmd,
748754

749755
if (!param(cmd, buffer, params,
750756
p_req("rune", param_rune, &ras),
751-
p_req("nodeid", param_node_id, &nodeid),
752-
p_req("method", param_string, &method),
757+
p_opt("nodeid", param_node_id, &nodeid),
758+
p_opt("method", param_string, &method),
753759
p_opt("params", param_params, &methodparams),
754760
NULL))
755761
return command_param_failed();
@@ -793,6 +799,6 @@ static const struct json_command checkrune_command = {
793799
"checkrune",
794800
"utility",
795801
json_checkrune,
796-
"Checks rune for validity with required {nodeid}, {rune}, {method} and optional {params} and returns {valid: true} or error message"
802+
"Checks rune for validity with required {rune} and optional {nodeid}, {method}, {params} and returns {valid: true} or error message"
797803
};
798804
AUTODATA(json_command, &checkrune_command);

tests/test_runes.py

+43
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,49 @@ def test_commando_blacklist_migration(node_factory):
471471
{'start': 9, 'end': 9}]}
472472

473473

474+
def test_missing_method_or_nodeid(node_factory):
475+
"""For v23.11 we realized that nodeid should not be required for checkrune, which means method (which followed it) could not be require either"""
476+
l1 = node_factory.get_node()
477+
rune1 = l1.rpc.createrune(restrictions=[["method=getinfo"]])['rune']
478+
rune2 = l1.rpc.createrune(restrictions=[["id={}".format(l1.info['id'])]])['rune']
479+
rune3 = l1.rpc.createrune(restrictions=[["method!"]])['rune']
480+
rune4 = l1.rpc.createrune(restrictions=[["id!"]])['rune']
481+
482+
# Simple cases with nodeid and method
483+
assert l1.rpc.checkrune(rune=rune1,
484+
nodeid=l1.info['id'],
485+
method='getinfo')['valid'] is True
486+
assert l1.rpc.checkrune(rune=rune2,
487+
nodeid=l1.info['id'],
488+
method='getinfo')['valid'] is True
489+
# No nodeid works for rune1
490+
assert l1.rpc.checkrune(rune=rune1,
491+
method='getinfo')['valid'] is True
492+
# No method works for rune2
493+
assert l1.rpc.checkrune(rune=rune2,
494+
nodeid=l1.info['id'])['valid'] is True
495+
496+
# No method works for rune3
497+
assert l1.rpc.checkrune(rune=rune3,
498+
nodeid=l1.info['id'])['valid'] is True
499+
# No id works for rune4
500+
assert l1.rpc.checkrune(rune=rune4,
501+
method='getinfo')['valid'] is True
502+
503+
# This fails, as method is missing
504+
with pytest.raises(RpcError, match='Not permitted: method not present'):
505+
l1.rpc.checkrune(rune=rune1)
506+
# This fails, as id is missing
507+
with pytest.raises(RpcError, match='Not permitted: id not present'):
508+
l1.rpc.checkrune(rune=rune2)
509+
# This fails, as method is present
510+
with pytest.raises(RpcError, match='Not permitted: method is present'):
511+
l1.rpc.checkrune(rune=rune3, method='getinfo')
512+
# This fails, as id is present
513+
with pytest.raises(RpcError, match='Not permitted: id is present'):
514+
l1.rpc.checkrune(rune=rune4, nodeid=l1.info['id'])
515+
516+
474517
def test_showrune_id(node_factory):
475518
l1 = node_factory.get_node()
476519

0 commit comments

Comments
 (0)