Skip to content

payalgo: Support bolt11 'r' fields. #1330

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions channeld/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ CHANNELD_COMMON_OBJS := \
common/permute_tx.o \
common/pseudorand.o \
common/read_peer_msg.o \
common/route_info.o \
common/sphinx.o \
common/status.o \
common/status_wire.o \
Expand Down
1 change: 1 addition & 0 deletions closingd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ CLOSINGD_COMMON_OBJS := \
common/permute_tx.o \
common/ping.o \
common/read_peer_msg.o \
common/route_info.o \
common/socket_close.o \
common/status.o \
common/status_wire.o \
Expand Down
2 changes: 2 additions & 0 deletions common/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ COMMON_SRC_NOGEN := \
common/ping.c \
common/pseudorand.c \
common/read_peer_msg.c \
common/route_builder.c \
common/route_info.c \
common/socket_close.c \
common/sphinx.c \
common/status.c \
Expand Down
21 changes: 1 addition & 20 deletions common/bolt11.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <common/bech32.h>
#include <common/bech32_util.h>
#include <common/bolt11.h>
#include <common/route_info.h>
#include <common/utils.h>
#include <errno.h>
#include <hsmd/gen_hsm_client_wire.h>
Expand Down Expand Up @@ -375,26 +376,6 @@ static char *decode_f(struct bolt11 *b11,
return NULL;
}

static bool fromwire_route_info(const u8 **cursor, size_t *max,
struct route_info *route_info)
{
fromwire_pubkey(cursor, max, &route_info->pubkey);
fromwire_short_channel_id(cursor, max, &route_info->short_channel_id);
route_info->fee_base_msat = fromwire_u32(cursor, max);
route_info->fee_proportional_millionths = fromwire_u32(cursor, max);
route_info->cltv_expiry_delta = fromwire_u16(cursor, max);
return *cursor != NULL;
}

static void towire_route_info(u8 **pptr, const struct route_info *route_info)
{
towire_pubkey(pptr, &route_info->pubkey);
towire_short_channel_id(pptr, &route_info->short_channel_id);
towire_u32(pptr, route_info->fee_base_msat);
towire_u32(pptr, route_info->fee_proportional_millionths);
towire_u16(pptr, route_info->cltv_expiry_delta);
}

/* BOLT #11:
*
* `r` (3): `data_length` variable. One or more entries containing
Expand Down
17 changes: 2 additions & 15 deletions common/bolt11.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <common/hash_u5.h>
#include <secp256k1_recovery.h>

struct route_info;

/* We only have 10 bits for the field length, meaning < 640 bytes */
#define BOLT11_FIELD_BYTE_LIMIT ((1 << 10) * 5 / 8)

Expand All @@ -19,21 +21,6 @@ struct bolt11_field {
u5 *data;
};

/* BOLT #11:
* * `pubkey` (264 bits)
* * `short_channel_id` (64 bits)
* * `fee_base_msat` (32 bits, big-endian)
* * `fee_proportional_millionths` (32 bits, big-endian)
* * `cltv_expiry_delta` (16 bits, big-endian)
*/

struct route_info {
struct pubkey pubkey;
struct short_channel_id short_channel_id;
u32 fee_base_msat, fee_proportional_millionths;
u16 cltv_expiry_delta;
};

struct bolt11 {
const struct chainparams *chain;
u64 timestamp;
Expand Down
52 changes: 52 additions & 0 deletions common/route_builder.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "route_builder.h"
#include <assert.h>

void
route_builder_init(struct route_builder *builder,
struct route_hop *hops,
size_t n_hops,
const struct pubkey *destination,
u64 msatoshi,
u32 min_final_cltv_expiry)
{
builder->begin = hops;
builder->end = hops + n_hops;
builder->amount = msatoshi;
builder->delay = min_final_cltv_expiry;
builder->next = *destination;
}

void
route_builder_step(struct route_builder *builder,
const struct pubkey *source,
const struct short_channel_id *channel,
u32 fixed,
u32 prop,
u32 delay)
{
struct route_hop *hop = --builder->end;

/* Mostly load from current state. */
hop->channel_id = *channel;
hop->nodeid = builder->next;
hop->amount = builder->amount;
hop->delay = builder->delay;

/* Update these afterwards. */
add_fees(&builder->amount, fixed, prop);
builder->delay += delay;
builder->next = *source;
}

void
route_builder_complete(struct route_builder *builder)
{
assert(builder->begin == builder->end);
}

void
add_fees(u64 *amount, u32 fixed, u32 prop)
{
*amount += *amount * prop / 1000000;
*amount += fixed;
}
55 changes: 55 additions & 0 deletions common/route_builder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#ifndef LIGHTNING_COMMON_ROUTE_BUILDER_H
#define LIGHTNING_COMMON_ROUTE_BUILDER_H
#include "config.h"
#include <bitcoin/pubkey.h>
#include <bitcoin/short_channel_id.h>
#include <ccan/short_types/short_types.h>
#include <stddef.h>

/* Standard route hop understood by send_payment. */
struct route_hop {
struct short_channel_id channel_id;
struct pubkey nodeid;
u64 amount;
u32 delay;
};

/* Fields are not intended to be accessed and are
* subject to change without notice.
* Only put it here so compiler can optimize storage. */
struct route_builder {
struct route_hop *begin;
struct route_hop *end;
u64 amount;
u32 delay;
struct pubkey next;
};
/* Routes are built backwards. This function starts the
* building of a route array. */
void route_builder_init(struct route_builder *builder,
struct route_hop *hops,
size_t n_hops,
const struct pubkey *destination,
u64 msatoshi,
u32 min_final_cltv_expiry);
/* Must be called starting with the last hop, as routes
* must be built backwards. */
void route_builder_step(struct route_builder *builder,
/* Who will pay to the next pubkey. */
const struct pubkey *source,
/* What channel the source will use to pay the
* next pubkey. */
const struct short_channel_id *channel,
/* Fees of the channel. */
u32 fee_base_msat,
u32 fee_proportional_millionths,
/* Delay added by the channel. */
u32 cltv_expiry_delta);
/* Call when the entire route has been loaded. */
void route_builder_complete(struct route_builder *builder);

/* Modify the given amount according to a channel fee. */
void add_fees(u64 *amount,
u32 fee_base_msat, u32 fee_proportional_millionths);

#endif /* LIGHTNING_COMMON_ROUTE_BUILDER_H */
23 changes: 23 additions & 0 deletions common/route_info.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include <common/route_info.h>
#include <wire/wire.h>

bool fromwire_route_info(const u8 **cursor, size_t *max,
struct route_info *route_info)
{
fromwire_pubkey(cursor, max, &route_info->pubkey);
fromwire_short_channel_id(cursor, max, &route_info->short_channel_id);
route_info->fee_base_msat = fromwire_u32(cursor, max);
route_info->fee_proportional_millionths = fromwire_u32(cursor, max);
route_info->cltv_expiry_delta = fromwire_u16(cursor, max);
return *cursor != NULL;
}

void towire_route_info(u8 **pptr, const struct route_info *route_info)
{
towire_pubkey(pptr, &route_info->pubkey);
towire_short_channel_id(pptr, &route_info->short_channel_id);
towire_u32(pptr, route_info->fee_base_msat);
towire_u32(pptr, route_info->fee_proportional_millionths);
towire_u16(pptr, route_info->cltv_expiry_delta);
}

29 changes: 29 additions & 0 deletions common/route_info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef LIGHTNING_COMMON_ROUTE_INFO_H
#define LIGHTNING_COMMON_ROUTE_INFO_H
#include "config.h"

#include <bitcoin/pubkey.h>
#include <bitcoin/short_channel_id.h>
#include <ccan/short_types/short_types.h>

/* BOLT #11:
* * `pubkey` (264 bits)
* * `short_channel_id` (64 bits)
* * `fee_base_msat` (32 bits, big-endian)
* * `fee_proportional_millionths` (32 bits, big-endian)
* * `cltv_expiry_delta` (16 bits, big-endian)
*/

struct route_info {
struct pubkey pubkey;
struct short_channel_id short_channel_id;
u32 fee_base_msat, fee_proportional_millionths;
u16 cltv_expiry_delta;
};

/* Serialization of route_info. */
bool fromwire_route_info(const u8 **cursor, size_t *max,
struct route_info *route_info);
void towire_route_info(u8 **pptr, const struct route_info *route_info);

#endif /* LIGHTNING_COMMON_ROUTE_INFO_H */
1 change: 1 addition & 0 deletions common/test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ COMMON_TEST_OBJS := $(COMMON_TEST_SRC:.c=.o)
COMMON_TEST_PROGRAMS := $(COMMON_TEST_OBJS:.o=)

COMMON_TEST_COMMON_OBJS := \
common/route_info.o \
common/utils.o

$(COMMON_TEST_PROGRAMS): $(COMMON_TEST_COMMON_OBJS) $(BITCOIN_OBJS)
Expand Down
26 changes: 26 additions & 0 deletions common/test/run-features.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,32 @@
#include <wally_core.h>

/* AUTOGENERATED MOCKS START */
/* Generated stub for fromwire_pubkey */
void fromwire_pubkey(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct pubkey *pubkey UNNEEDED)
{ fprintf(stderr, "fromwire_pubkey called!\n"); abort(); }
/* Generated stub for fromwire_short_channel_id */
void fromwire_short_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
struct short_channel_id *short_channel_id UNNEEDED)
{ fprintf(stderr, "fromwire_short_channel_id called!\n"); abort(); }
/* Generated stub for fromwire_u16 */
u16 fromwire_u16(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
{ fprintf(stderr, "fromwire_u16 called!\n"); abort(); }
/* Generated stub for fromwire_u32 */
u32 fromwire_u32(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
{ fprintf(stderr, "fromwire_u32 called!\n"); abort(); }
/* Generated stub for towire_pubkey */
void towire_pubkey(u8 **pptr UNNEEDED, const struct pubkey *pubkey UNNEEDED)
{ fprintf(stderr, "towire_pubkey called!\n"); abort(); }
/* Generated stub for towire_short_channel_id */
void towire_short_channel_id(u8 **pptr UNNEEDED,
const struct short_channel_id *short_channel_id UNNEEDED)
{ fprintf(stderr, "towire_short_channel_id called!\n"); abort(); }
/* Generated stub for towire_u16 */
void towire_u16(u8 **pptr UNNEEDED, u16 v UNNEEDED)
{ fprintf(stderr, "towire_u16 called!\n"); abort(); }
/* Generated stub for towire_u32 */
void towire_u32(u8 **pptr UNNEEDED, u32 v UNNEEDED)
{ fprintf(stderr, "towire_u32 called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */

int main(void)
Expand Down
20 changes: 20 additions & 0 deletions common/test/run-ip_port_parsing.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,19 @@ const u8 *fromwire(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, void *copy
/* Generated stub for fromwire_fail */
const void *fromwire_fail(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
{ fprintf(stderr, "fromwire_fail called!\n"); abort(); }
/* Generated stub for fromwire_pubkey */
void fromwire_pubkey(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct pubkey *pubkey UNNEEDED)
{ fprintf(stderr, "fromwire_pubkey called!\n"); abort(); }
/* Generated stub for fromwire_short_channel_id */
void fromwire_short_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
struct short_channel_id *short_channel_id UNNEEDED)
{ fprintf(stderr, "fromwire_short_channel_id called!\n"); abort(); }
/* Generated stub for fromwire_u16 */
u16 fromwire_u16(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
{ fprintf(stderr, "fromwire_u16 called!\n"); abort(); }
/* Generated stub for fromwire_u32 */
u32 fromwire_u32(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
{ fprintf(stderr, "fromwire_u32 called!\n"); abort(); }
/* Generated stub for fromwire_u8 */
u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
{ fprintf(stderr, "fromwire_u8 called!\n"); abort(); }
Expand All @@ -24,9 +34,19 @@ void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr
/* Generated stub for towire */
void towire(u8 **pptr UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED)
{ fprintf(stderr, "towire called!\n"); abort(); }
/* Generated stub for towire_pubkey */
void towire_pubkey(u8 **pptr UNNEEDED, const struct pubkey *pubkey UNNEEDED)
{ fprintf(stderr, "towire_pubkey called!\n"); abort(); }
/* Generated stub for towire_short_channel_id */
void towire_short_channel_id(u8 **pptr UNNEEDED,
const struct short_channel_id *short_channel_id UNNEEDED)
{ fprintf(stderr, "towire_short_channel_id called!\n"); abort(); }
/* Generated stub for towire_u16 */
void towire_u16(u8 **pptr UNNEEDED, u16 v UNNEEDED)
{ fprintf(stderr, "towire_u16 called!\n"); abort(); }
/* Generated stub for towire_u32 */
void towire_u32(u8 **pptr UNNEEDED, u32 v UNNEEDED)
{ fprintf(stderr, "towire_u32 called!\n"); abort(); }
/* Generated stub for towire_u8 */
void towire_u8(u8 **pptr UNNEEDED, u8 v UNNEEDED)
{ fprintf(stderr, "towire_u8 called!\n"); abort(); }
Expand Down
27 changes: 27 additions & 0 deletions common/test/run-json.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,35 @@
#include "../json_escaped.c"
#include <common/utils.h>
#include <stdio.h>
#include <wire/wire.h>

/* AUTOGENERATED MOCKS START */
/* Generated stub for fromwire_pubkey */
void fromwire_pubkey(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct pubkey *pubkey UNNEEDED)
{ fprintf(stderr, "fromwire_pubkey called!\n"); abort(); }
/* Generated stub for fromwire_short_channel_id */
void fromwire_short_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
struct short_channel_id *short_channel_id UNNEEDED)
{ fprintf(stderr, "fromwire_short_channel_id called!\n"); abort(); }
/* Generated stub for fromwire_u16 */
u16 fromwire_u16(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
{ fprintf(stderr, "fromwire_u16 called!\n"); abort(); }
/* Generated stub for fromwire_u32 */
u32 fromwire_u32(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
{ fprintf(stderr, "fromwire_u32 called!\n"); abort(); }
/* Generated stub for towire_pubkey */
void towire_pubkey(u8 **pptr UNNEEDED, const struct pubkey *pubkey UNNEEDED)
{ fprintf(stderr, "towire_pubkey called!\n"); abort(); }
/* Generated stub for towire_short_channel_id */
void towire_short_channel_id(u8 **pptr UNNEEDED,
const struct short_channel_id *short_channel_id UNNEEDED)
{ fprintf(stderr, "towire_short_channel_id called!\n"); abort(); }
/* Generated stub for towire_u16 */
void towire_u16(u8 **pptr UNNEEDED, u16 v UNNEEDED)
{ fprintf(stderr, "towire_u16 called!\n"); abort(); }
/* Generated stub for towire_u32 */
void towire_u32(u8 **pptr UNNEEDED, u32 v UNNEEDED)
{ fprintf(stderr, "towire_u32 called!\n"); abort(); }
/* AUTOGENERATED MOCKS END */


Expand Down
6 changes: 6 additions & 0 deletions common/test/run-sphinx.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ const u8 *fromwire(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, void *copy
/* Generated stub for fromwire_pad */
void fromwire_pad(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, size_t num UNNEEDED)
{ fprintf(stderr, "fromwire_pad called!\n"); abort(); }
/* Generated stub for fromwire_pubkey */
void fromwire_pubkey(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct pubkey *pubkey UNNEEDED)
{ fprintf(stderr, "fromwire_pubkey called!\n"); abort(); }
/* Generated stub for fromwire_short_channel_id */
void fromwire_short_channel_id(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
struct short_channel_id *short_channel_id UNNEEDED)
Expand All @@ -40,6 +43,9 @@ void towire(u8 **pptr UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED)
/* Generated stub for towire_pad */
void towire_pad(u8 **pptr UNNEEDED, size_t num UNNEEDED)
{ fprintf(stderr, "towire_pad called!\n"); abort(); }
/* Generated stub for towire_pubkey */
void towire_pubkey(u8 **pptr UNNEEDED, const struct pubkey *pubkey UNNEEDED)
{ fprintf(stderr, "towire_pubkey called!\n"); abort(); }
/* Generated stub for towire_short_channel_id */
void towire_short_channel_id(u8 **pptr UNNEEDED,
const struct short_channel_id *short_channel_id UNNEEDED)
Expand Down
Loading