mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-22 16:44:20 +01:00
bolt11: 'c' support for min_final_cltv_expiry.
Based on latest draft spec, using variable length encoding. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -248,6 +248,33 @@ static char *decode_x(struct bolt11 *b11,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* BOLT #11:
|
||||||
|
*
|
||||||
|
* `c` (24): `data_length` variable. `min_final_cltv_expiry` to use for the
|
||||||
|
* last HTLC in the route. Default is 9 if not specified.
|
||||||
|
*/
|
||||||
|
#define DEFAULT_C 9
|
||||||
|
static char *decode_c(struct bolt11 *b11,
|
||||||
|
struct hash_u5 *hu5,
|
||||||
|
u5 **data, size_t *data_len,
|
||||||
|
size_t data_length, bool *have_c)
|
||||||
|
{
|
||||||
|
u64 c;
|
||||||
|
if (*have_c)
|
||||||
|
return unknown_field(b11, hu5, data, data_len, 'c',
|
||||||
|
data_length);
|
||||||
|
|
||||||
|
/* FIXME: Put upper limit in bolt 11 */
|
||||||
|
if (!pull_uint(hu5, data, data_len, &c, data_length * 5))
|
||||||
|
return tal_fmt(b11, "c: length %zu chars is excessive",
|
||||||
|
*data_len);
|
||||||
|
b11->min_final_cltv_expiry = c;
|
||||||
|
if (b11->min_final_cltv_expiry != c)
|
||||||
|
return tal_fmt(b11, "c: %"PRIu64" is too large", c);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static char *decode_n(struct bolt11 *b11,
|
static char *decode_n(struct bolt11 *b11,
|
||||||
struct hash_u5 *hu5,
|
struct hash_u5 *hu5,
|
||||||
u5 **data, size_t *data_len,
|
u5 **data, size_t *data_len,
|
||||||
@@ -417,6 +444,8 @@ struct bolt11 *new_bolt11(const tal_t *ctx, u64 *msatoshi)
|
|||||||
b11->fallback = NULL;
|
b11->fallback = NULL;
|
||||||
b11->routes = NULL;
|
b11->routes = NULL;
|
||||||
b11->msatoshi = NULL;
|
b11->msatoshi = NULL;
|
||||||
|
b11->expiry = DEFAULT_X;
|
||||||
|
b11->min_final_cltv_expiry = DEFAULT_C;
|
||||||
|
|
||||||
if (msatoshi)
|
if (msatoshi)
|
||||||
b11->msatoshi = tal_dup(b11, u64, msatoshi);
|
b11->msatoshi = tal_dup(b11, u64, msatoshi);
|
||||||
@@ -437,7 +466,7 @@ struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str,
|
|||||||
struct hash_u5 hu5;
|
struct hash_u5 hu5;
|
||||||
struct sha256 hash;
|
struct sha256 hash;
|
||||||
bool have_p = false, have_n = false, have_d = false, have_h = false,
|
bool have_p = false, have_n = false, have_d = false, have_h = false,
|
||||||
have_x = false, have_f = false;
|
have_x = false, have_f = false, have_c = false;
|
||||||
|
|
||||||
b11->routes = tal_arr(b11, struct route_info *, 0);
|
b11->routes = tal_arr(b11, struct route_info *, 0);
|
||||||
|
|
||||||
@@ -528,8 +557,6 @@ struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str,
|
|||||||
if (!pull_uint(&hu5, &data, &data_len, &b11->timestamp, 35))
|
if (!pull_uint(&hu5, &data, &data_len, &b11->timestamp, 35))
|
||||||
return decode_fail(b11, fail, "Can't get 35-bit timestamp");
|
return decode_fail(b11, fail, "Can't get 35-bit timestamp");
|
||||||
|
|
||||||
b11->expiry = DEFAULT_X;
|
|
||||||
|
|
||||||
while (data_len > 520 / 5) {
|
while (data_len > 520 / 5) {
|
||||||
const char *problem = NULL;
|
const char *problem = NULL;
|
||||||
u64 type, data_length;
|
u64 type, data_length;
|
||||||
@@ -580,6 +607,12 @@ struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str,
|
|||||||
&have_x);
|
&have_x);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
problem = decode_c(b11, &hu5, &data,
|
||||||
|
&data_len, data_length,
|
||||||
|
&have_c);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
problem = decode_f(b11, &hu5, &data,
|
problem = decode_f(b11, &hu5, &data,
|
||||||
&data_len, data_length,
|
&data_len, data_length,
|
||||||
@@ -765,6 +798,11 @@ static void encode_x(u5 **data, u64 expiry)
|
|||||||
push_varlen_field(data, 'x', expiry);
|
push_varlen_field(data, 'x', expiry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void encode_c(u5 **data, u16 min_final_cltv_expiry)
|
||||||
|
{
|
||||||
|
push_varlen_field(data, 'c', min_final_cltv_expiry);
|
||||||
|
}
|
||||||
|
|
||||||
static void encode_f(u5 **data, const u8 *fallback)
|
static void encode_f(u5 **data, const u8 *fallback)
|
||||||
{
|
{
|
||||||
struct bitcoin_address pkh;
|
struct bitcoin_address pkh;
|
||||||
@@ -906,6 +944,9 @@ char *bolt11_encode(const tal_t *ctx,
|
|||||||
if (b11->expiry != DEFAULT_X)
|
if (b11->expiry != DEFAULT_X)
|
||||||
encode_x(&data, b11->expiry);
|
encode_x(&data, b11->expiry);
|
||||||
|
|
||||||
|
if (b11->min_final_cltv_expiry != DEFAULT_C)
|
||||||
|
encode_c(&data, b11->min_final_cltv_expiry);
|
||||||
|
|
||||||
if (b11->fallback)
|
if (b11->fallback)
|
||||||
encode_f(&data, b11->fallback);
|
encode_f(&data, b11->fallback);
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ struct bolt11 {
|
|||||||
/* How many seconds to pay from @timestamp above. */
|
/* How many seconds to pay from @timestamp above. */
|
||||||
u64 expiry;
|
u64 expiry;
|
||||||
|
|
||||||
|
/* How many blocks final hop requires. */
|
||||||
|
u32 min_final_cltv_expiry;
|
||||||
|
|
||||||
/* If non-NULL, indicates a fallback address to pay to. */
|
/* If non-NULL, indicates a fallback address to pay to. */
|
||||||
const u8 *fallback;
|
const u8 *fallback;
|
||||||
|
|
||||||
|
|||||||
@@ -181,6 +181,7 @@ static void json_invoice(struct command *cmd,
|
|||||||
b11->timestamp = time_now().ts.tv_sec;
|
b11->timestamp = time_now().ts.tv_sec;
|
||||||
b11->payment_hash = invoice->rhash;
|
b11->payment_hash = invoice->rhash;
|
||||||
b11->receiver_id = cmd->ld->id;
|
b11->receiver_id = cmd->ld->id;
|
||||||
|
b11->min_final_cltv_expiry = cmd->ld->config.cltv_final;
|
||||||
if (desc->end - desc->start >= BOLT11_FIELD_BYTE_LIMIT) {
|
if (desc->end - desc->start >= BOLT11_FIELD_BYTE_LIMIT) {
|
||||||
b11->description_hash = tal(b11, struct sha256);
|
b11->description_hash = tal(b11, struct sha256);
|
||||||
sha256(b11->description_hash, buffer + desc->start,
|
sha256(b11->description_hash, buffer + desc->start,
|
||||||
@@ -188,8 +189,7 @@ static void json_invoice(struct command *cmd,
|
|||||||
} else
|
} else
|
||||||
b11->description = tal_strndup(b11, buffer + desc->start,
|
b11->description = tal_strndup(b11, buffer + desc->start,
|
||||||
desc->end - desc->start);
|
desc->end - desc->start);
|
||||||
/* FIXME: add option to set this */
|
/* FIXME: add option to set expiry */
|
||||||
b11->expiry = 3600;
|
|
||||||
|
|
||||||
/* FIXME: add private routes if necessary! */
|
/* FIXME: add private routes if necessary! */
|
||||||
b11enc = bolt11_encode(cmd, cmd->ld, b11, false);
|
b11enc = bolt11_encode(cmd, cmd->ld, b11, false);
|
||||||
|
|||||||
@@ -393,8 +393,6 @@ static void json_pay(struct command *cmd,
|
|||||||
jsmntok_t *bolt11tok, *msatoshitok, *desctok, *riskfactortok;
|
jsmntok_t *bolt11tok, *msatoshitok, *desctok, *riskfactortok;
|
||||||
double riskfactor = 1.0;
|
double riskfactor = 1.0;
|
||||||
u64 msatoshi;
|
u64 msatoshi;
|
||||||
/* FIXME: add ctlv to bolt11 */
|
|
||||||
u32 cltv = 9;
|
|
||||||
struct pay *pay = tal(cmd, struct pay);
|
struct pay *pay = tal(cmd, struct pay);
|
||||||
struct bolt11 *b11;
|
struct bolt11 *b11;
|
||||||
char *fail, *b11str, *desc;
|
char *fail, *b11str, *desc;
|
||||||
@@ -458,7 +456,8 @@ static void json_pay(struct command *cmd,
|
|||||||
/* FIXME: use b11->routes */
|
/* FIXME: use b11->routes */
|
||||||
req = towire_gossip_getroute_request(cmd, &cmd->ld->id,
|
req = towire_gossip_getroute_request(cmd, &cmd->ld->id,
|
||||||
&b11->receiver_id,
|
&b11->receiver_id,
|
||||||
msatoshi, riskfactor*1000, cltv);
|
msatoshi, riskfactor*1000,
|
||||||
|
b11->min_final_cltv_expiry);
|
||||||
subd_req(pay, cmd->ld->gossip, req, -1, 0, json_pay_getroute_reply, pay);
|
subd_req(pay, cmd->ld->gossip, req, -1, 0, json_pay_getroute_reply, pay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user