Browse Source

bolt11: allow multiple fallback addresses.

We can have more than one; eg we might offer both bech32 and a p2sh
address, and in future we might offer v1 segwit, etc.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
09c4203767
  1. 35
      common/bolt11.c
  2. 4
      common/bolt11.h
  3. 11
      common/test/run-bolt11.c
  4. 4
      contrib/pylightning/lightning/lightning.py
  5. 12
      devtools/bolt11-cli.c
  6. 6
      doc/lightning-decodepay.7
  7. 2
      doc/lightning-decodepay.7.txt
  8. 8
      doc/lightning-invoice.7
  9. 6
      doc/lightning-invoice.7.txt
  10. 152
      lightningd/invoice.c
  11. 32
      tests/test_lightningd.py

35
common/bolt11.c

@ -313,13 +313,10 @@ static char *decode_n(struct bolt11 *b11,
static char *decode_f(struct bolt11 *b11,
struct hash_u5 *hu5,
u5 **data, size_t *data_len,
size_t data_length, bool *have_f)
size_t data_length)
{
u64 version;
if (*have_f)
return unknown_field(b11, hu5, data, data_len, 'f',
data_length);
u8 *fallback;
if (!pull_uint(hu5, data, data_len, &version, 5))
return tal_fmt(b11, "f: data_length %zu short", data_length);
@ -339,8 +336,7 @@ static char *decode_f(struct bolt11 *b11,
pull_bits_certain(hu5, data, data_len, &pkhash, data_length*5,
false);
b11->fallback = scriptpubkey_p2pkh(b11, &pkhash);
return NULL;
fallback = scriptpubkey_p2pkh(b11, &pkhash);
} else if (version == 18) {
/* Pay to pubkey script hash (P2SH) */
struct ripemd160 shash;
@ -350,7 +346,7 @@ static char *decode_f(struct bolt11 *b11,
pull_bits_certain(hu5, data, data_len, &shash, data_length*5,
false);
b11->fallback = scriptpubkey_p2sh_hash(b11, &shash);
fallback = scriptpubkey_p2sh_hash(b11, &shash);
} else if (version < 17) {
u8 *f = tal_arr(b11, u8, data_length * 5 / 8);
if (version == 0) {
@ -361,14 +357,20 @@ static char *decode_f(struct bolt11 *b11,
}
pull_bits_certain(hu5, data, data_len, f, data_length * 5,
false);
b11->fallback = scriptpubkey_witness_raw(b11, version,
f, tal_len(f));
fallback = scriptpubkey_witness_raw(b11, version,
f, tal_len(f));
tal_free(f);
} else
return unknown_field(b11, hu5, data, data_len, 'f',
data_length);
*have_f = true;
if (b11->fallbacks == NULL)
b11->fallbacks = tal_arr(b11, const u8 *, 1);
else
tal_resize(&b11->fallbacks, tal_count(b11->fallbacks) + 1);
b11->fallbacks[tal_count(b11->fallbacks)-1]
= tal_steal(b11->fallbacks, fallback);
return NULL;
}
@ -441,7 +443,7 @@ struct bolt11 *new_bolt11(const tal_t *ctx, u64 *msatoshi)
list_head_init(&b11->extra_fields);
b11->description = NULL;
b11->description_hash = NULL;
b11->fallback = NULL;
b11->fallbacks = NULL;
b11->routes = NULL;
b11->msatoshi = NULL;
b11->expiry = DEFAULT_X;
@ -465,7 +467,7 @@ struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str,
struct hash_u5 hu5;
struct sha256 hash;
bool have_p = false, have_n = false, have_d = false, have_h = false,
have_x = false, have_f = false, have_c = false;
have_x = false, have_c = false;
b11->routes = tal_arr(b11, struct route_info *, 0);
@ -617,8 +619,7 @@ struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str,
case 'f':
problem = decode_f(b11, &hu5, &data,
&data_len, data_length,
&have_f);
&data_len, data_length);
break;
case 'r':
problem = decode_r(b11, &hu5, &data, &data_len,
@ -948,8 +949,8 @@ char *bolt11_encode_(const tal_t *ctx,
if (b11->min_final_cltv_expiry != DEFAULT_C)
encode_c(&data, b11->min_final_cltv_expiry);
if (b11->fallback)
encode_f(&data, b11->fallback);
for (size_t i = 0; i < tal_count(b11->fallbacks); i++)
encode_f(&data, b11->fallbacks[i]);
for (size_t i = 0; i < tal_count(b11->routes); i++)
encode_r(&data, b11->routes[i]);

4
common/bolt11.h

@ -52,8 +52,8 @@ struct bolt11 {
/* How many blocks final hop requires. */
u32 min_final_cltv_expiry;
/* If non-NULL, indicates a fallback address to pay to. */
const u8 *fallback;
/* If non-NULL, indicates fallback addresses to pay to. */
const u8 **fallbacks;
/* If non-NULL: array of route arrays */
struct route_info **routes;

11
common/test/run-bolt11.c

@ -91,12 +91,11 @@ static void test_b11(const char *b11str,
assert(b11->expiry == expect_b11->expiry);
assert(b11->min_final_cltv_expiry == expect_b11->min_final_cltv_expiry);
if (!b11->fallback)
assert(!expect_b11->fallback);
else
assert(memeq(b11->fallback, tal_len(b11->fallback),
expect_b11->fallback,
tal_len(expect_b11->fallback)));
assert(tal_count(b11->fallbacks) == tal_count(expect_b11->fallbacks));
for (size_t i = 0; i < tal_count(b11->fallbacks); i++)
assert(memeq(b11->fallbacks[i], tal_len(b11->fallbacks[i]),
expect_b11->fallbacks[i],
tal_len(expect_b11->fallbacks[i])));
/* FIXME: compare routes. */
assert(tal_count(b11->routes) == tal_count(expect_b11->routes));

4
contrib/pylightning/lightning/lightning.py

@ -150,7 +150,7 @@ class LightningRpc(UnixDomainSocketRpc):
}
return self.call("listchannels", payload)
def invoice(self, msatoshi, label, description, expiry=None, fallback=None):
def invoice(self, msatoshi, label, description, expiry=None, fallbacks=None):
"""
Create an invoice for {msatoshi} with {label} and {description} with
optional {expiry} seconds (default 1 hour)
@ -160,7 +160,7 @@ class LightningRpc(UnixDomainSocketRpc):
"label": label,
"description": description,
"expiry": expiry,
"fallback": fallback
"fallbacks": fallbacks
}
return self.call("invoice", payload)

12
devtools/bolt11-cli.c

@ -111,27 +111,27 @@ int main(int argc, char *argv[])
tal_hexstr(ctx, b11->description_hash,
sizeof(*b11->description_hash)));
if (tal_len(b11->fallback)) {
for (i = 0; i < tal_count(b11->fallbacks); i++) {
struct bitcoin_address pkh;
struct ripemd160 sh;
struct sha256 wsh;
printf("fallback: %s\n", tal_hex(ctx, b11->fallback));
if (is_p2pkh(b11->fallback, &pkh)) {
printf("fallback: %s\n", tal_hex(ctx, b11->fallbacks[i]));
if (is_p2pkh(b11->fallbacks[i], &pkh)) {
printf("fallback-P2PKH: %s\n",
bitcoin_to_base58(ctx, b11->chain->testnet,
&pkh));
} else if (is_p2sh(b11->fallback, &sh)) {
} else if (is_p2sh(b11->fallbacks[i], &sh)) {
printf("fallback-P2SH: %s\n",
p2sh_to_base58(ctx,
b11->chain->testnet,
&sh));
} else if (is_p2wpkh(b11->fallback, &pkh)) {
} else if (is_p2wpkh(b11->fallbacks[i], &pkh)) {
char out[73 + strlen(b11->chain->bip173_name)];
if (segwit_addr_encode(out, b11->chain->bip173_name, 0,
(const u8 *)&pkh, sizeof(pkh)))
printf("fallback-P2WPKH: %s\n", out);
} else if (is_p2wsh(b11->fallback, &wsh)) {
} else if (is_p2wsh(b11->fallbacks[i], &wsh)) {
char out[73 + strlen(b11->chain->bip173_name)];
if (segwit_addr_encode(out, b11->chain->bip173_name, 0,
(const u8 *)&wsh, sizeof(wsh)))

6
doc/lightning-decodepay.7

@ -2,12 +2,12 @@
.\" Title: lightning-decodepay
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
.\" Date: 01/13/2018
.\" Date: 04/05/2018
.\" Manual: \ \&
.\" Source: \ \&
.\" Language: English
.\"
.TH "LIGHTNING\-DECODEPAY" "7" "01/13/2018" "\ \&" "\ \&"
.TH "LIGHTNING\-DECODEPAY" "7" "04/05/2018" "\ \&" "\ \&"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@ -138,7 +138,7 @@ The following fields are optional:
.sp -1
.IP \(bu 2.3
.\}
\fIfallback\fR: fallback address object containing a
\fIfallbacks\fR: array of fallback address object containing a
\fIhex\fR
string, and both
\fItype\fR

2
doc/lightning-decodepay.7.txt

@ -33,7 +33,7 @@ by BOLT11:
The following fields are optional:
- 'msatoshi': the number of millisatoshi requested (if any).
- 'fallback': fallback address object containing a 'hex' string, and
- 'fallbacks': array of fallback address object containing a 'hex' string, and
both 'type' and 'addr' if it is recognized as one of 'P2PKH', 'P2SH', 'P2WPKH', or 'P2WSH'.
- 'routes': an array of routes. Each route is an arrays of objects, each containing 'pubkey', 'short_channel_id', 'fee_base_msat', 'fee_proportional_millionths' and 'cltv_expiry_delta'.
- 'extra': an array of objects representing unknown fields, each with one-character 'tag' and a 'data' bech32 string.

8
doc/lightning-invoice.7

@ -2,12 +2,12 @@
.\" Title: lightning-invoice
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
.\" Date: 03/28/2018
.\" Date: 04/06/2018
.\" Manual: \ \&
.\" Source: \ \&
.\" Language: English
.\"
.TH "LIGHTNING\-INVOICE" "7" "03/28/2018" "\ \&" "\ \&"
.TH "LIGHTNING\-INVOICE" "7" "04/06/2018" "\ \&" "\ \&"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@ -31,7 +31,7 @@
lightning-invoice \- Protocol for accepting payments\&.
.SH "SYNOPSIS"
.sp
\fBinvoice\fR \fImsatoshi\fR \fIlabel\fR \fIdescription\fR [\fIexpiry\fR]
\fBinvoice\fR \fImsatoshi\fR \fIlabel\fR \fIdescription\fR [\fIexpiry\fR] [\fIfallbacks\fR]
.SH "DESCRIPTION"
.sp
The \fBinvoice\fR RPC command creates the expectation of a payment of a given amount of milli\-satoshi: it returns a unique token which another lightning daemon can use to pay this invoice\&.
@ -43,6 +43,8 @@ The \fIlabel\fR must be a unique string or number (which is treated as a string,
The \fIdescription\fR is a short description of purpose of payment, e\&.g\&. \fI1 cup of coffee\fR\&. This value is encoded into the BOLT11 invoice and is viewable by any node you send this invoice to\&. It must be UTF\-8, and cannot use \fI\eu\fR JSON escape codes\&.
.sp
The \fIexpiry\fR is optionally the number of seconds the invoice is valid for\&. If no value is provided the default of 3600 (1 Hour) is used\&.
.sp
The \fIfallbacks\fR array is one or more fallback addresses to include in the invoice (in order from most\-preferred to least): note that these arrays are not currently tracked to fulfill the invoice\&.
.SH "RETURN VALUE"
.sp
On success, a hash is returned as \fIpayment_hash\fR to be given to the payer, and the \fIexpiry_time\fR as a UNIX timestamp\&. It also returns a BOLT11 invoice as \fIbolt11\fR to be given to the payer\&. On failure, an error is returned and no invoice is created\&. If the lightning process fails before responding, the caller should use lightning\-listinvoice(7) to query whether this invoice was created or not\&.

6
doc/lightning-invoice.7.txt

@ -8,7 +8,7 @@ lightning-invoice - Protocol for accepting payments.
SYNOPSIS
--------
*invoice* 'msatoshi' 'label' 'description' ['expiry']
*invoice* 'msatoshi' 'label' 'description' ['expiry'] ['fallbacks']
DESCRIPTION
-----------
@ -32,6 +32,10 @@ UTF-8, and cannot use '\u' JSON escape codes.
The 'expiry' is optionally the number of seconds the invoice is valid for.
If no value is provided the default of 3600 (1 Hour) is used.
The 'fallbacks' array is one or more fallback addresses to include in
the invoice (in order from most-preferred to least): note that these
arrays are not currently tracked to fulfill the invoice.
RETURN VALUE
------------

152
lightningd/invoice.c

@ -127,21 +127,43 @@ static struct json_escaped *json_tok_label(const tal_t *ctx,
tok->end - tok->start);
}
static bool parse_fallback(struct command *cmd,
const char *buffer, const jsmntok_t *fallback,
const u8 **fallback_script)
{
enum address_parse_result fallback_parse;
fallback_parse
= json_tok_address_scriptpubkey(cmd,
get_chainparams(cmd->ld),
buffer, fallback,
fallback_script);
if (fallback_parse == ADDRESS_PARSE_UNRECOGNIZED) {
command_fail(cmd, "Fallback address not valid");
return false;
} else if (fallback_parse == ADDRESS_PARSE_WRONG_NETWORK) {
command_fail(cmd, "Fallback address does not match our network %s",
get_chainparams(cmd->ld)->network_name);
return false;
}
return true;
}
static void json_invoice(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
struct invoice invoice;
struct invoice_details details;
jsmntok_t *msatoshi, *label, *desctok, *exp, *fallback;
jsmntok_t *msatoshi, *label, *desctok, *exp, *fallback, *fallbacks;
u64 *msatoshi_val;
const struct json_escaped *label_val, *desc;
const char *desc_val;
enum address_parse_result fallback_parse;
struct json_result *response = new_json_result(cmd);
struct wallet *wallet = cmd->ld->wallet;
struct bolt11 *b11;
char *b11enc;
const u8 *fallback_script;
const u8 **fallback_scripts = NULL;
u64 expiry = 3600;
bool result;
@ -151,6 +173,7 @@ static void json_invoice(struct command *cmd,
"description", &desctok,
"?expiry", &exp,
"?fallback", &fallback,
"?fallbacks", &fallbacks,
NULL)) {
return;
}
@ -219,21 +242,40 @@ static void json_invoice(struct command *cmd,
return;
}
/* fallback address */
/* fallback addresses */
if (fallback) {
fallback_parse
= json_tok_address_scriptpubkey(cmd,
get_chainparams(cmd->ld),
buffer, fallback,
&fallback_script);
if (fallback_parse == ADDRESS_PARSE_UNRECOGNIZED) {
command_fail(cmd, "Fallback address not valid");
if (deprecated_apis) {
fallback_scripts = tal_arr(cmd, const u8 *, 1);
if (!parse_fallback(cmd, buffer, fallback,
&fallback_scripts[0]))
return;
} else {
command_fail(cmd, "fallback is deprecated: use fallbacks");
return;
} else if (fallback_parse == ADDRESS_PARSE_WRONG_NETWORK) {
command_fail(cmd, "Fallback address does not match our network %s",
get_chainparams(cmd->ld)->network_name);
}
}
if (fallbacks) {
const jsmntok_t *i, *end = json_next(fallbacks);
size_t n = 0;
if (fallback) {
command_fail(cmd, "Cannot use fallback and fallbacks");
return;
}
if (fallbacks->type != JSMN_ARRAY) {
command_fail(cmd, "fallback must be an array");
return;
}
fallback_scripts = tal_arr(cmd, const u8 *, n);
for (i = fallbacks + 1; i < end; i = json_next(i)) {
tal_resize(&fallback_scripts, n+1);
if (!parse_fallback(cmd, buffer, i,
&fallback_scripts[n]))
return;
n++;
}
}
struct preimage r;
@ -253,8 +295,8 @@ static void json_invoice(struct command *cmd,
b11->expiry = expiry;
b11->description = tal_steal(b11, desc_val);
b11->description_hash = NULL;
if (fallback)
b11->fallback = tal_steal(b11, fallback_script);
if (fallback_scripts)
b11->fallbacks = tal_steal(b11, fallback_scripts);
/* FIXME: add private routes if necessary! */
b11enc = bolt11_encode(cmd, b11, false, hsm_sign_b11, cmd->ld);
@ -623,6 +665,41 @@ static const struct json_command waitinvoice_command = {
};
AUTODATA(json_command, &waitinvoice_command);
static void json_add_fallback(struct json_result *response,
const char *fieldname,
const u8 *fallback,
const struct chainparams *chain)
{
struct bitcoin_address pkh;
struct ripemd160 sh;
struct sha256 wsh;
json_object_start(response, fieldname);
if (is_p2pkh(fallback, &pkh)) {
json_add_string(response, "type", "P2PKH");
json_add_string(response, "addr",
bitcoin_to_base58(tmpctx, chain->testnet, &pkh));
} else if (is_p2sh(fallback, &sh)) {
json_add_string(response, "type", "P2SH");
json_add_string(response, "addr",
p2sh_to_base58(tmpctx, chain->testnet, &sh));
} else if (is_p2wpkh(fallback, &pkh)) {
char out[73 + strlen(chain->bip173_name)];
json_add_string(response, "type", "P2WPKH");
if (segwit_addr_encode(out, chain->bip173_name, 0,
(const u8 *)&pkh, sizeof(pkh)))
json_add_string(response, "addr", out);
} else if (is_p2wsh(fallback, &wsh)) {
char out[73 + strlen(chain->bip173_name)];
json_add_string(response, "type", "P2WSH");
if (segwit_addr_encode(out, chain->bip173_name, 0,
(const u8 *)&wsh, sizeof(wsh)))
json_add_string(response, "addr", out);
}
json_add_hex(response, "hex", fallback, tal_len(fallback));
json_object_end(response);
}
static void json_decodepay(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
@ -675,40 +752,15 @@ static void json_decodepay(struct command *cmd,
sizeof(*b11->description_hash));
json_add_num(response, "min_final_cltv_expiry",
b11->min_final_cltv_expiry);
if (tal_len(b11->fallback)) {
struct bitcoin_address pkh;
struct ripemd160 sh;
struct sha256 wsh;
json_object_start(response, "fallback");
if (is_p2pkh(b11->fallback, &pkh)) {
json_add_string(response, "type", "P2PKH");
json_add_string(response, "addr",
bitcoin_to_base58(cmd,
b11->chain->testnet,
&pkh));
} else if (is_p2sh(b11->fallback, &sh)) {
json_add_string(response, "type", "P2SH");
json_add_string(response, "addr",
p2sh_to_base58(cmd,
b11->chain->testnet,
&sh));
} else if (is_p2wpkh(b11->fallback, &pkh)) {
char out[73 + strlen(b11->chain->bip173_name)];
json_add_string(response, "type", "P2WPKH");
if (segwit_addr_encode(out, b11->chain->bip173_name, 0,
(const u8 *)&pkh, sizeof(pkh)))
json_add_string(response, "addr", out);
} else if (is_p2wsh(b11->fallback, &wsh)) {
char out[73 + strlen(b11->chain->bip173_name)];
json_add_string(response, "type", "P2WSH");
if (segwit_addr_encode(out, b11->chain->bip173_name, 0,
(const u8 *)&wsh, sizeof(wsh)))
json_add_string(response, "addr", out);
}
json_add_hex(response, "hex",
b11->fallback, tal_len(b11->fallback));
json_object_end(response);
if (tal_count(b11->fallbacks)) {
if (deprecated_apis)
json_add_fallback(response, "fallback",
b11->fallbacks[0], b11->chain);
json_array_start(response, "fallbacks");
for (size_t i = 0; i < tal_count(b11->fallbacks); i++)
json_add_fallback(response, NULL,
b11->fallbacks[i], b11->chain);
json_array_end(response);
}
if (tal_count(b11->routes)) {

32
tests/test_lightningd.py

@ -429,9 +429,10 @@ class LightningDTests(BaseLightningDTests):
l1 = self.node_factory.get_node()
l2 = self.node_factory.get_node()
addr = l2.rpc.newaddr('bech32')['address']
addr1 = l2.rpc.newaddr('bech32')['address']
addr2 = l2.rpc.newaddr('p2sh-segwit')['address']
before = int(time.time())
inv = l1.rpc.invoice(123000, 'label', 'description', '3700', addr)
inv = l1.rpc.invoice(123000, 'label', 'description', '3700', [addr1, addr2])
after = int(time.time())
b11 = l1.rpc.decodepay(inv['bolt11'])
assert b11['currency'] == 'bcrt'
@ -441,8 +442,11 @@ class LightningDTests(BaseLightningDTests):
assert b11['description'] == 'description'
assert b11['expiry'] == 3700
assert b11['payee'] == l1.info['id']
assert b11['fallback']['addr'] == addr
assert b11['fallback']['type'] == 'P2WPKH'
assert len(b11['fallbacks']) == 2
assert b11['fallbacks'][0]['addr'] == addr1
assert b11['fallbacks'][0]['type'] == 'P2WPKH'
assert b11['fallbacks'][1]['addr'] == addr2
assert b11['fallbacks'][1]['type'] == 'P2SH'
# Check pay_index is null
outputs = l1.db_query('SELECT pay_index IS NULL AS q FROM invoices WHERE label="label";')
@ -721,8 +725,8 @@ class LightningDTests(BaseLightningDTests):
assert b11['payment_hash'] == '0001020304050607080900010203040506070809000102030405060708090102'
assert b11['expiry'] == 3600
assert b11['payee'] == '03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad'
assert b11['fallback']['type'] == 'P2PKH'
assert b11['fallback']['addr'] == 'mk2QpYatsKicvFVuTAQLBryyccRXMUaGHP'
assert b11['fallbacks'][0]['type'] == 'P2PKH'
assert b11['fallbacks'][0]['addr'] == 'mk2QpYatsKicvFVuTAQLBryyccRXMUaGHP'
# > ### On mainnet, with fallback address 1RustyRX2oai4EYYDpQGWvEL62BBGqN9T with extra routing info to go via nodes 029e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255 then 039e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255
# > lnbc20m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsfpp3qjmp7lwpagxun9pygexvgpjdc4jdj85fr9yq20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqpqqqqq9qqqvpeuqafqxu92d8lr6fvg0r5gv0heeeqgcrqlnm6jhphu9y00rrhy4grqszsvpcgpy9qqqqqqgqqqqq7qqzqj9n4evl6mr5aj9f58zp6fyjzup6ywn3x6sk8akg5v4tgn2q8g4fhx05wf6juaxu9760yp46454gpg5mtzgerlzezqcqvjnhjh8z3g2qqdhhwkj
@ -751,8 +755,8 @@ class LightningDTests(BaseLightningDTests):
assert b11['payment_hash'] == '0001020304050607080900010203040506070809000102030405060708090102'
assert b11['expiry'] == 3600
assert b11['payee'] == '03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad'
assert b11['fallback']['type'] == 'P2PKH'
assert b11['fallback']['addr'] == '1RustyRX2oai4EYYDpQGWvEL62BBGqN9T'
assert b11['fallbacks'][0]['type'] == 'P2PKH'
assert b11['fallbacks'][0]['addr'] == '1RustyRX2oai4EYYDpQGWvEL62BBGqN9T'
assert len(b11['routes']) == 1
assert len(b11['routes'][0]) == 2
assert b11['routes'][0][0]['pubkey'] == '029e03a901b85534ff1e92c43c74431f7ce72046060fcf7a95c37e148f78c77255'
@ -792,8 +796,8 @@ class LightningDTests(BaseLightningDTests):
assert b11['payment_hash'] == '0001020304050607080900010203040506070809000102030405060708090102'
assert b11['expiry'] == 3600
assert b11['payee'] == '03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad'
assert b11['fallback']['type'] == 'P2SH'
assert b11['fallback']['addr'] == '3EktnHQD7RiAE6uzMj2ZifT9YgRrkSgzQX'
assert b11['fallbacks'][0]['type'] == 'P2SH'
assert b11['fallbacks'][0]['addr'] == '3EktnHQD7RiAE6uzMj2ZifT9YgRrkSgzQX'
# > ### On mainnet, with fallback (P2WPKH) address bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4
# > lnbc20m1pvjluezhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfppqw508d6qejxtdg4y5r3zarvary0c5xw7kepvrhrm9s57hejg0p662ur5j5cr03890fa7k2pypgttmh4897d3raaq85a293e9jpuqwl0rnfuwzam7yr8e690nd2ypcq9hlkdwdvycqa0qza8
@ -817,8 +821,8 @@ class LightningDTests(BaseLightningDTests):
assert b11['payment_hash'] == '0001020304050607080900010203040506070809000102030405060708090102'
assert b11['expiry'] == 3600
assert b11['payee'] == '03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad'
assert b11['fallback']['type'] == 'P2WPKH'
assert b11['fallback']['addr'] == 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4'
assert b11['fallbacks'][0]['type'] == 'P2WPKH'
assert b11['fallbacks'][0]['addr'] == 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4'
# > ### On mainnet, with fallback (P2WSH) address bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3
# > lnbc20m1pvjluezhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfp4qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q28j0v3rwgy9pvjnd48ee2pl8xrpxysd5g44td63g6xcjcu003j3qe8878hluqlvl3km8rm92f5stamd3jw763n3hck0ct7p8wwj463cql26ava
@ -842,8 +846,8 @@ class LightningDTests(BaseLightningDTests):
assert b11['payment_hash'] == '0001020304050607080900010203040506070809000102030405060708090102'
assert b11['expiry'] == 3600
assert b11['payee'] == '03e7156ae33b0a208d0744199163177e909e80176e55d97a2f221ede0f934dd9ad'
assert b11['fallback']['type'] == 'P2WSH'
assert b11['fallback']['addr'] == 'bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3'
assert b11['fallbacks'][0]['type'] == 'P2WSH'
assert b11['fallbacks'][0]['addr'] == 'bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3'
self.assertRaises(ValueError, l1.rpc.decodepay, '1111111')

Loading…
Cancel
Save