Skip to content

Commit fcebb33

Browse files
committed
lightningd: deprecate decodepay.
It only works on BOLT11, and has long been replaced by the more generic "decode". Removing it will stop the confusion! (Note: documentation claims it was introduced in 23.08, but that was wrong, as it's been in CLN since the beginning). [ Fixup from: niftynei <[email protected]> ] Fixes: #6419 Changelog-Deprecated: JSON-RPC: `decodepay`: use `decode`. Signed-off-by: Rusty Russell <[email protected]>
1 parent 374db23 commit fcebb33

File tree

12 files changed

+115
-80
lines changed

12 files changed

+115
-80
lines changed

contrib/msggen/msggen/schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10523,9 +10523,15 @@
1052310523
"$schema": "../rpc-schema-draft.json",
1052410524
"type": "object",
1052510525
"added": "v23.05",
10526+
"depecated": [
10527+
"v24.11",
10528+
"v25.11"
10529+
],
1052610530
"rpc": "decodepay",
1052710531
"title": "Command for decoding a bolt11 string (low-level)",
1052810532
"description": [
10533+
"WARNING: deprecated: use *decode* which also handles bolt12.",
10534+
"",
1052910535
"The **decodepay** RPC command checks and parses a *bolt11* string as specified by the BOLT 11 specification."
1053010536
],
1053110537
"request": {

contrib/pyln-testing/pyln/testing/utils.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,8 +1212,7 @@ def pay(self, dst, amt, label=None, route=False):
12121212

12131213
# make an invoice
12141214
inv = dst.rpc.invoice(amt, label, label)
1215-
# FIXME: pre 0.10.1 invoice calls didn't have payment_secret field
1216-
psecret = dst.rpc.decodepay(inv['bolt11'])['payment_secret']
1215+
psecret = inv['payment_secret']
12171216
rhash = inv['payment_hash']
12181217
invoices = dst.rpc.listinvoices(label)['invoices']
12191218
assert len(invoices) == 1 and invoices[0]['status'] == 'unpaid'

doc/developers-guide/deprecations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ hidden: false
3333
| experimental-onion-messages | Config | v24.08 | v25.02 | Now the default |
3434
| decode.blinding | Field | v24.11 | v25.05 | Renamed to `first_path_key` in BOLT 4 (available in `decode` from v24.11) |
3535
| onion_message_recv.blinding | Hook Field | v24.11 | v25.05 | Renamed to `first_path_key` in BOLT 4 (available in hook from v24.11) |
36-
36+
| decodepay | Command | v24.11 | v25.11 | Use `decode` which is more powerful (since v23.05) |
3737

3838
Inevitably there are features which need to change: either to be generalized, or removed when they can no longer be supported.
3939

doc/schemas/lightning-decodepay.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@
22
"$schema": "../rpc-schema-draft.json",
33
"type": "object",
44
"added": "v23.05",
5+
"depecated": [
6+
"v24.11",
7+
"v25.11"
8+
],
59
"rpc": "decodepay",
610
"title": "Command for decoding a bolt11 string (low-level)",
711
"description": [
12+
"WARNING: deprecated: use *decode* which also handles bolt12.",
13+
"",
814
"The **decodepay** RPC command checks and parses a *bolt11* string as specified by the BOLT 11 specification."
915
],
1016
"request": {

lightningd/invoice.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1585,6 +1585,8 @@ static struct command_result *json_decodepay(struct command *cmd,
15851585
static const struct json_command decodepay_command = {
15861586
"decodepay",
15871587
json_decodepay,
1588+
.depr_start = "v24.11",
1589+
.depr_end = "v25.11"
15881590
};
15891591
AUTODATA(json_command, &decodepay_command);
15901592

tests/autogenerate-rpc-examples.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,6 @@ def generate_utils_examples(l1, l2, l3, l4, l5, l6, c23, c34, inv_l11, inv_l22,
700700
update_example(node=l2, method='signmessage', params={'message': 'message for you'})
701701
update_example(node=l2, method='checkmessage', params={'message': 'testcase to check new rpc error', 'zbase': 'd66bqz3qsku5fxtqsi37j11pci47ydxa95iusphutggz9ezaxt56neh77kxe5hyr41kwgkncgiu94p9ecxiexgpgsz8daoq4tw8kj8yx', 'pubkey': '03be3b0e9992153b1d5a6e1623670b6c3663f72ce6cf2e0dd39c0a373a7de5a3b7'})
702702
update_example(node=l2, method='checkmessage', params={'message': 'this is a test!', 'zbase': 'd6tqaeuonjhi98mmont9m4wag7gg4krg1f4txonug3h31e9h6p6k6nbwjondnj46dkyausobstnk7fhyy998bhgc1yr98dfmhb4k54d7'})
703-
update_example(node=l2, method='decodepay', params={'bolt11': inv_l11['bolt11']})
704703
update_example(node=l2, method='decode', params=[rune_l21['rune']])
705704
update_example(node=l2, method='decode', params=[inv_l22['bolt11']])
706705

tests/test_cln_rs.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -375,12 +375,6 @@ def test_grpc_decode(node_factory):
375375
label="label",
376376
))
377377

378-
res = l1.grpc.DecodePay(clnpb.DecodepayRequest(
379-
bolt11=inv.bolt11
380-
))
381-
# If we get here we're good, conversions work
382-
print(res)
383-
384378
res = l1.grpc.Decode(clnpb.DecodeRequest(
385379
string=inv.bolt11
386380
))

tests/test_invoices.py

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ def test_invoice(node_factory, chainparams):
2424
l1.daemon.wait_for_log(r': "{}:invoice#[0-9]*/cln:listincoming#[0-9]*"\[OUT\]'.format(myname))
2525

2626
after = int(time.time())
27-
b11 = l1.rpc.decodepay(inv['bolt11'])
27+
b11 = l1.rpc.decode(inv['bolt11'])
28+
assert b11['type'] == 'bolt11 invoice'
2829
assert b11['currency'] == chainparams['bip173_prefix']
2930
assert b11['created_at'] >= before
3031
assert b11['created_at'] <= after
@@ -63,7 +64,7 @@ def test_invoice(node_factory, chainparams):
6364

6465
# Test cltv option.
6566
inv = l1.rpc.invoice(123000, 'label3', 'description', 3700, cltv=99)
66-
b11 = l1.rpc.decodepay(inv['bolt11'])
67+
b11 = l1.rpc.decode(inv['bolt11'])
6768
assert b11['min_final_cltv_expiry'] == 99
6869

6970

@@ -103,7 +104,7 @@ def test_invoice_weirdstring(node_factory):
103104
inv = only_one(l1.rpc.listinvoices()['invoices'])
104105
assert inv['label'] == weird_label
105106

106-
b11 = l1.rpc.decodepay(inv['bolt11'])
107+
b11 = l1.rpc.decode(inv['bolt11'])
107108
assert b11['description'] == weird_desc
108109

109110
# Can delete by weird label.
@@ -123,7 +124,7 @@ def test_invoice_weirdstring(node_factory):
123124
inv = only_one(l1.rpc.listinvoices()['invoices'])
124125
assert inv['label'] == str(weird_label)
125126

126-
b11 = l1.rpc.decodepay(inv['bolt11'])
127+
b11 = l1.rpc.decode(inv['bolt11'])
127128
assert b11['description'] == weird_desc
128129

129130
# Can delete by weird label.
@@ -167,7 +168,7 @@ def test_invoice_routeboost(node_factory, bitcoind):
167168
assert 'warning_deadends' not in inv
168169
assert 'warning_mpp' not in inv
169170
# Route array has single route with single element.
170-
r = only_one(only_one(l2.rpc.decodepay(inv['bolt11'])['routes']))
171+
r = only_one(only_one(l2.rpc.decode(inv['bolt11'])['routes']))
171172
assert r['pubkey'] == l2.info['id']
172173
assert r['short_channel_id'] == l3.rpc.listpeerchannels(l2.info['id'])['channels'][0]['short_channel_id']
173174
assert r['fee_base_msat'] == 1
@@ -241,7 +242,7 @@ def test_invoice_routeboost_private(node_factory, bitcoind):
241242
assert 'warning_deadends' not in inv
242243
assert 'warning_mpp' not in inv
243244
# Route array has single route with single element.
244-
r = only_one(only_one(l1.rpc.decodepay(inv['bolt11'])['routes']))
245+
r = only_one(only_one(l1.rpc.decode(inv['bolt11'])['routes']))
245246
assert r['pubkey'] == l1.info['id']
246247
# It uses our private alias!
247248
assert r['short_channel_id'] != l1.rpc.listchannels()['channels'][0]['short_channel_id']
@@ -257,7 +258,7 @@ def test_invoice_routeboost_private(node_factory, bitcoind):
257258
assert 'warning_offline' not in inv
258259
assert 'warning_deadends' not in inv
259260
assert 'warning_mpp' not in inv
260-
assert 'routes' not in l1.rpc.decodepay(inv['bolt11'])
261+
assert 'routes' not in l1.rpc.decode(inv['bolt11'])
261262

262263
# If we ask for it, we get it.
263264
inv = l2.rpc.invoice(amount_msat=123456, label="inv1a", description="?", exposeprivatechannels=scid)
@@ -267,7 +268,7 @@ def test_invoice_routeboost_private(node_factory, bitcoind):
267268
assert 'warning_deadends' not in inv
268269
assert 'warning_mpp' not in inv
269270
# Route array has single route with single element.
270-
r = only_one(only_one(l1.rpc.decodepay(inv['bolt11'])['routes']))
271+
r = only_one(only_one(l1.rpc.decode(inv['bolt11'])['routes']))
271272
assert r['pubkey'] == l1.info['id']
272273
assert r['short_channel_id'] == alias
273274
assert r['fee_base_msat'] == 1
@@ -282,7 +283,7 @@ def test_invoice_routeboost_private(node_factory, bitcoind):
282283
assert 'warning_deadends' not in inv
283284
assert 'warning_mpp' not in inv
284285
# Route array has single route with single element.
285-
r = only_one(only_one(l1.rpc.decodepay(inv['bolt11'])['routes']))
286+
r = only_one(only_one(l1.rpc.decode(inv['bolt11'])['routes']))
286287
assert r['pubkey'] == l1.info['id']
287288
assert r['short_channel_id'] == alias
288289
assert r['fee_base_msat'] == 1
@@ -314,7 +315,7 @@ def test_invoice_routeboost_private(node_factory, bitcoind):
314315
assert 'warning_deadends' not in inv
315316
assert 'warning_mpp' not in inv
316317
# Route array has single route with single element.
317-
r = only_one(only_one(l1.rpc.decodepay(inv['bolt11'])['routes']))
318+
r = only_one(only_one(l1.rpc.decode(inv['bolt11'])['routes']))
318319
assert r['pubkey'] == l1.info['id']
319320
assert r['short_channel_id'] == alias
320321
assert r['fee_base_msat'] == 1
@@ -328,7 +329,7 @@ def test_invoice_routeboost_private(node_factory, bitcoind):
328329
assert 'warning_deadends' not in inv
329330
assert 'warning_mpp' not in inv
330331
# Route array has single route with single element.
331-
r = only_one(only_one(l1.rpc.decodepay(inv['bolt11'])['routes']))
332+
r = only_one(only_one(l1.rpc.decode(inv['bolt11'])['routes']))
332333
assert r['pubkey'] == l1.info['id']
333334
assert r['short_channel_id'] == alias
334335
assert r['fee_base_msat'] == 1
@@ -351,7 +352,7 @@ def test_invoice_routeboost_private(node_factory, bitcoind):
351352
assert 'warning_deadends' not in inv
352353
assert 'warning_mpp' not in inv
353354
# Route array has single route with single element.
354-
r = only_one(only_one(l1.rpc.decodepay(inv['bolt11'])['routes']))
355+
r = only_one(only_one(l1.rpc.decode(inv['bolt11'])['routes']))
355356
assert r['pubkey'] == l1.info['id']
356357
assert r['short_channel_id'] == alias
357358
assert r['fee_base_msat'] == 1
@@ -371,7 +372,7 @@ def test_invoice_routeboost_private(node_factory, bitcoind):
371372
assert 'warning_deadends' not in inv
372373
assert 'warning_mpp' not in inv
373374
# Route array has single route with single element.
374-
r = only_one(only_one(l1.rpc.decodepay(inv['bolt11'])['routes']))
375+
r = only_one(only_one(l1.rpc.decode(inv['bolt11'])['routes']))
375376
assert r['pubkey'] == l1.info['id']
376377
assert r['short_channel_id'] == alias
377378
assert r['fee_base_msat'] == 1
@@ -535,11 +536,11 @@ def test_signinvoice(node_factory, executor):
535536

536537
# Create an invoice for l1
537538
inv1 = l1.rpc.invoice(1000, 'inv1', 'inv1')['bolt11']
538-
assert l1.rpc.decodepay(inv1)['payee'] == l1.info['id']
539+
assert l1.rpc.decode(inv1)['payee'] == l1.info['id']
539540

540541
# Have l2 re-sign the invoice
541542
inv2 = l2.rpc.signinvoice(inv1)['bolt11']
542-
assert l1.rpc.decodepay(inv2)['payee'] == l2.info['id']
543+
assert l1.rpc.decode(inv2)['payee'] == l2.info['id']
543544

544545

545546
def test_waitanyinvoice_reversed(node_factory, executor):
@@ -570,7 +571,8 @@ def test_waitanyinvoice_reversed(node_factory, executor):
570571
def test_decode_unknown(node_factory):
571572
l1 = node_factory.get_node()
572573

573-
b11 = l1.rpc.decodepay('lntb30m1pw2f2yspp5s59w4a0kjecw3zyexm7zur8l8n4scw674w8sftjhwec33km882gsdpa2pshjmt9de6zqun9w96k2um5ypmkjargypkh2mr5d9cxzun5ypeh2ursdae8gxqruyqvzddp68gup69uhnzwfj9cejuvf3xshrwde68qcrswf0d46kcarfwpshyaplw3skw0tdw4k8g6tsv9e8gu2etcvsym36pdjpz04wm9nn96f9ntc3t3h5r08pe9d62p3js5wt5rkurqnrl7zkj2fjpvl3rmn7wwazt80letwxlm22hngu8n88g7hsp542qpl')
574+
b11 = l1.rpc.decode('lntb30m1pw2f2yspp5s59w4a0kjecw3zyexm7zur8l8n4scw674w8sftjhwec33km882gsdpa2pshjmt9de6zqun9w96k2um5ypmkjargypkh2mr5d9cxzun5ypeh2ursdae8gxqruyqvzddp68gup69uhnzwfj9cejuvf3xshrwde68qcrswf0d46kcarfwpshyaplw3skw0tdw4k8g6tsv9e8gu2etcvsym36pdjpz04wm9nn96f9ntc3t3h5r08pe9d62p3js5wt5rkurqnrl7zkj2fjpvl3rmn7wwazt80letwxlm22hngu8n88g7hsp542qpl')
575+
assert b11['type'] == 'bolt11 invoice'
574576
assert b11['currency'] == 'tb'
575577
assert b11['created_at'] == 1554294928
576578
assert b11['payment_hash'] == '850aeaf5f69670e8889936fc2e0cff3ceb0c3b5eab8f04ae57767118db673a91'
@@ -596,7 +598,7 @@ def test_amountless_invoice(node_factory):
596598
assert(len(i) == 1)
597599
assert('amount_received_msat' not in i[0])
598600
assert(i[0]['status'] == 'unpaid')
599-
details = l1.rpc.decodepay(inv)
601+
details = l1.rpc.decode(inv)
600602
assert('msatoshi' not in details)
601603

602604
l1.rpc.pay(inv, amount_msat=1337)
@@ -781,7 +783,7 @@ def test_invoice_deschash(node_factory, chainparams):
781783
inv = l2.rpc.invoice(42, 'label', 'One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon', deschashonly=True)
782784
assert '8yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqs' in inv['bolt11']
783785

784-
b11 = l2.rpc.decodepay(inv['bolt11'])
786+
b11 = l2.rpc.decode(inv['bolt11'])
785787
assert 'description' not in b11
786788
assert b11['description_hash'] == '3925b6f67e2c340036ed12093dd44e0368df1b6ea26c53dbe4811f58fd5db8c1'
787789

@@ -864,7 +866,7 @@ def test_unified_invoices(node_factory, executor, bitcoind):
864866
l1, l2 = node_factory.line_graph(2, opts={'invoices-onchain-fallback': None})
865867
amount_sat = 1000
866868
inv = l1.rpc.invoice(amount_sat * 1000, "inv1", "test_unified_invoices")
867-
b11 = l1.rpc.decodepay(inv['bolt11'])
869+
b11 = l1.rpc.decode(inv['bolt11'])
868870

869871
assert len(b11['fallbacks']) == 1
870872

tests/test_misc.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3733,21 +3733,21 @@ def test_field_filter(node_factory, chainparams):
37333733
inv = l1.rpc.invoice(123000, 'label', 'description', 3700, [addr1, addr2])
37343734

37353735
# Simple case: single field
3736-
dec = l1.rpc.call('decodepay', {'bolt11': inv['bolt11']}, filter={"currency": True})
3736+
dec = l1.rpc.call('decode', {'string': inv['bolt11']}, filter={"currency": True})
37373737
assert dec == {"currency": chainparams['bip173_prefix']}
37383738

37393739
# Use context manager:
37403740
with l1.rpc.reply_filter({"currency": True}):
3741-
dec = l1.rpc.decodepay(bolt11=inv['bolt11'])
3741+
dec = l1.rpc.decode(string=inv['bolt11'])
37423742
assert dec == {"currency": chainparams['bip173_prefix']}
37433743

37443744
# Two fields
3745-
dec = l1.rpc.call('decodepay', {'bolt11': inv['bolt11']}, filter={"currency": True, "payment_hash": True})
3745+
dec = l1.rpc.call('decode', {'string': inv['bolt11']}, filter={"currency": True, "payment_hash": True})
37463746
assert dec == {"currency": chainparams['bip173_prefix'],
37473747
"payment_hash": inv['payment_hash']}
37483748

37493749
# Nested fields
3750-
dec = l1.rpc.call('decodepay', {'bolt11': inv['bolt11']},
3750+
dec = l1.rpc.call('decode', {'string': inv['bolt11']},
37513751
filter={"currency": True,
37523752
"payment_hash": True,
37533753
"fallbacks": [{"type": True}]})
@@ -3756,12 +3756,12 @@ def test_field_filter(node_factory, chainparams):
37563756
"fallbacks": [{"type": 'P2WPKH'}, {"type": 'P2SH'}]}
37573757

37583758
# Nonexistent fields.
3759-
dec = l1.rpc.call('decodepay', {'bolt11': inv['bolt11']},
3759+
dec = l1.rpc.call('decode', {'string': inv['bolt11']},
37603760
filter={"foobar": True})
37613761
assert dec == {}
37623762

37633763
# Bad filters
3764-
dec = l1.rpc.call('decodepay', {'bolt11': inv['bolt11']},
3764+
dec = l1.rpc.call('decode', {'string': inv['bolt11']},
37653765
filter={"currency": True,
37663766
"payment_hash": True,
37673767
"fallbacks": {'type': True}})

tests/test_opening.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from pyln.testing.utils import FUNDAMOUNT
88

99
from pathlib import Path
10-
from pprint import pprint
1110
import pytest
1211
import re
1312
import unittest
@@ -1665,8 +1664,7 @@ def test_zeroconf_open(bitcoind, node_factory):
16651664
wait_for(lambda: l3.rpc.listchannels() != {'channels': []})
16661665

16671666
inv = l3.rpc.invoice(10**8, 'lbl', 'desc')['bolt11']
1668-
details = l2.rpc.decodepay(inv)
1669-
pprint(details)
1667+
details = l2.rpc.decode(inv)
16701668
assert('routes' in details and len(details['routes']) == 1)
16711669
hop = details['routes'][0][0] # First (and only) hop of hint 0
16721670
l2alias = only_one(l2.rpc.listpeerchannels(l3.info['id'])['channels'])['alias']['local']
@@ -1679,7 +1677,6 @@ def test_zeroconf_open(bitcoind, node_factory):
16791677
l3.daemon.wait_for_log(r'Balance [0-9]+msat -> [0-9]+msat')
16801678

16811679
# Inverse payments should work too
1682-
pprint(l3.rpc.listpeers())
16831680
inv = l2.rpc.invoice(10**5, 'lbl', 'desc')['bolt11']
16841681
l3.rpc.pay(inv)
16851682

0 commit comments

Comments
 (0)