mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-23 00:54:20 +01:00
subdaemons: initialize feature routines with explicit feature_set.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
Christian Decker
parent
afb76392e4
commit
c95e58ad4b
@@ -1,12 +1,14 @@
|
|||||||
#include <common/cryptomsg.h>
|
#include <common/cryptomsg.h>
|
||||||
#include <common/channel_config.h>
|
#include <common/channel_config.h>
|
||||||
#include <common/derive_basepoints.h>
|
#include <common/derive_basepoints.h>
|
||||||
|
#include <common/features.h>
|
||||||
#include <common/fee_states.h>
|
#include <common/fee_states.h>
|
||||||
#include <common/per_peer_state.h>
|
#include <common/per_peer_state.h>
|
||||||
|
|
||||||
# Begin! (passes gossipd-client fd)
|
# Begin! (passes gossipd-client fd)
|
||||||
msgtype,channel_init,1000
|
msgtype,channel_init,1000
|
||||||
msgdata,channel_init,chainparams,chainparams,
|
msgdata,channel_init,chainparams,chainparams,
|
||||||
|
msgdata,channel_init,feature_set,feature_set,
|
||||||
msgdata,channel_init,funding_txid,bitcoin_txid,
|
msgdata,channel_init,funding_txid,bitcoin_txid,
|
||||||
msgdata,channel_init,funding_txout,u16,
|
msgdata,channel_init,funding_txout,u16,
|
||||||
msgdata,channel_init,funding_satoshi,amount_sat,
|
msgdata,channel_init,funding_satoshi,amount_sat,
|
||||||
|
|||||||
|
@@ -2753,6 +2753,7 @@ static void init_channel(struct peer *peer)
|
|||||||
secp256k1_ecdsa_signature *remote_ann_node_sig;
|
secp256k1_ecdsa_signature *remote_ann_node_sig;
|
||||||
secp256k1_ecdsa_signature *remote_ann_bitcoin_sig;
|
secp256k1_ecdsa_signature *remote_ann_bitcoin_sig;
|
||||||
bool option_static_remotekey;
|
bool option_static_remotekey;
|
||||||
|
struct feature_set *feature_set;
|
||||||
#if !DEVELOPER
|
#if !DEVELOPER
|
||||||
bool dev_fail_process_onionpacket; /* Ignored */
|
bool dev_fail_process_onionpacket; /* Ignored */
|
||||||
#endif
|
#endif
|
||||||
@@ -2764,6 +2765,7 @@ static void init_channel(struct peer *peer)
|
|||||||
msg = wire_sync_read(tmpctx, MASTER_FD);
|
msg = wire_sync_read(tmpctx, MASTER_FD);
|
||||||
if (!fromwire_channel_init(peer, msg,
|
if (!fromwire_channel_init(peer, msg,
|
||||||
&chainparams,
|
&chainparams,
|
||||||
|
&feature_set,
|
||||||
&funding_txid, &funding_txout,
|
&funding_txid, &funding_txout,
|
||||||
&funding,
|
&funding,
|
||||||
&minimum_depth,
|
&minimum_depth,
|
||||||
@@ -2818,6 +2820,10 @@ static void init_channel(struct peer *peer)
|
|||||||
&dev_fail_process_onionpacket)) {
|
&dev_fail_process_onionpacket)) {
|
||||||
master_badmsg(WIRE_CHANNEL_INIT, msg);
|
master_badmsg(WIRE_CHANNEL_INIT, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now we know what features to advertize. */
|
||||||
|
features_init(take(feature_set));
|
||||||
|
|
||||||
/* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = HSM */
|
/* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = HSM */
|
||||||
per_peer_state_set_fds(peer->pps, 3, 4, 5);
|
per_peer_state_set_fds(peer->pps, 3, 4, 5);
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ CLOSINGD_COMMON_OBJS := \
|
|||||||
common/daemon_conn.o \
|
common/daemon_conn.o \
|
||||||
common/dev_disconnect.o \
|
common/dev_disconnect.o \
|
||||||
common/derive_basepoints.o \
|
common/derive_basepoints.o \
|
||||||
common/features.o \
|
|
||||||
common/gen_peer_status_wire.o \
|
common/gen_peer_status_wire.o \
|
||||||
common/gen_status_wire.o \
|
common/gen_status_wire.o \
|
||||||
common/gossip_rcvd_filter.o \
|
common/gossip_rcvd_filter.o \
|
||||||
|
|||||||
@@ -9,32 +9,6 @@
|
|||||||
* the init features is a superset of the others. */
|
* the init features is a superset of the others. */
|
||||||
static struct feature_set *our_features;
|
static struct feature_set *our_features;
|
||||||
|
|
||||||
/* FIXME: Remove once all subdaemons call features_init() */
|
|
||||||
static const u8 *our_feature_bits(enum feature_place place)
|
|
||||||
{
|
|
||||||
if (!our_features) {
|
|
||||||
static const u32 our_features[] = {
|
|
||||||
OPTIONAL_FEATURE(OPT_DATA_LOSS_PROTECT),
|
|
||||||
OPTIONAL_FEATURE(OPT_UPFRONT_SHUTDOWN_SCRIPT),
|
|
||||||
OPTIONAL_FEATURE(OPT_GOSSIP_QUERIES),
|
|
||||||
OPTIONAL_FEATURE(OPT_VAR_ONION),
|
|
||||||
OPTIONAL_FEATURE(OPT_PAYMENT_SECRET),
|
|
||||||
OPTIONAL_FEATURE(OPT_BASIC_MPP),
|
|
||||||
OPTIONAL_FEATURE(OPT_GOSSIP_QUERIES_EX),
|
|
||||||
OPTIONAL_FEATURE(OPT_STATIC_REMOTEKEY),
|
|
||||||
};
|
|
||||||
u8 *f = tal_arr(NULL, u8, 0);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < ARRAY_SIZE(our_features); i++)
|
|
||||||
set_feature_bit(&f, our_features[i]);
|
|
||||||
|
|
||||||
features_core_init(take(f));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is currently always a superset of other bits */
|
|
||||||
return our_features->bits[place];
|
|
||||||
}
|
|
||||||
|
|
||||||
enum feature_copy_style {
|
enum feature_copy_style {
|
||||||
/* Feature is not exposed (importantly, being 0, this is the default!). */
|
/* Feature is not exposed (importantly, being 0, this is the default!). */
|
||||||
FEATURE_DONT_REPRESENT,
|
FEATURE_DONT_REPRESENT,
|
||||||
@@ -133,6 +107,20 @@ struct feature_set *features_core_init(const u8 *feature_bits)
|
|||||||
return our_features;
|
return our_features;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void features_init(struct feature_set *fset TAKES)
|
||||||
|
{
|
||||||
|
assert(!our_features);
|
||||||
|
|
||||||
|
if (taken(fset))
|
||||||
|
our_features = notleak(tal_steal(NULL, fset));
|
||||||
|
else {
|
||||||
|
our_features = notleak(tal(NULL, struct feature_set));
|
||||||
|
for (size_t i = 0; i < ARRAY_SIZE(fset->bits); i++)
|
||||||
|
our_features->bits[i] = tal_dup_talarr(our_features, u8,
|
||||||
|
fset->bits[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void features_cleanup(void)
|
void features_cleanup(void)
|
||||||
{
|
{
|
||||||
our_features = tal_free(our_features);
|
our_features = tal_free(our_features);
|
||||||
@@ -164,17 +152,17 @@ static bool test_bit(const u8 *features, size_t byte, unsigned int bit)
|
|||||||
|
|
||||||
u8 *get_offered_nodefeatures(const tal_t *ctx)
|
u8 *get_offered_nodefeatures(const tal_t *ctx)
|
||||||
{
|
{
|
||||||
return tal_dup_talarr(ctx, u8, our_feature_bits(NODE_ANNOUNCE_FEATURE));
|
return tal_dup_talarr(ctx, u8, our_features->bits[NODE_ANNOUNCE_FEATURE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *get_offered_initfeatures(const tal_t *ctx)
|
u8 *get_offered_initfeatures(const tal_t *ctx)
|
||||||
{
|
{
|
||||||
return tal_dup_talarr(ctx, u8, our_feature_bits(INIT_FEATURE));
|
return tal_dup_talarr(ctx, u8, our_features->bits[INIT_FEATURE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *get_offered_globalinitfeatures(const tal_t *ctx)
|
u8 *get_offered_globalinitfeatures(const tal_t *ctx)
|
||||||
{
|
{
|
||||||
return tal_dup_talarr(ctx, u8, our_feature_bits(GLOBAL_INIT_FEATURE));
|
return tal_dup_talarr(ctx, u8, our_features->bits[GLOBAL_INIT_FEATURE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_feature_bit(u8 *features, u32 bit)
|
static void clear_feature_bit(u8 *features, u32 bit)
|
||||||
@@ -195,7 +183,7 @@ static void clear_feature_bit(u8 *features, u32 bit)
|
|||||||
*/
|
*/
|
||||||
u8 *get_agreed_channelfeatures(const tal_t *ctx, const u8 *theirfeatures)
|
u8 *get_agreed_channelfeatures(const tal_t *ctx, const u8 *theirfeatures)
|
||||||
{
|
{
|
||||||
u8 *f = tal_dup_talarr(ctx, u8, our_feature_bits(CHANNEL_FEATURE));
|
u8 *f = tal_dup_talarr(ctx, u8, our_features->bits[CHANNEL_FEATURE]);
|
||||||
size_t max_len = 0;
|
size_t max_len = 0;
|
||||||
|
|
||||||
/* Clear any features which they didn't offer too */
|
/* Clear any features which they didn't offer too */
|
||||||
@@ -217,7 +205,7 @@ u8 *get_agreed_channelfeatures(const tal_t *ctx, const u8 *theirfeatures)
|
|||||||
|
|
||||||
u8 *get_offered_bolt11features(const tal_t *ctx)
|
u8 *get_offered_bolt11features(const tal_t *ctx)
|
||||||
{
|
{
|
||||||
return tal_dup_talarr(ctx, u8, our_feature_bits(BOLT11_FEATURE));
|
return tal_dup_talarr(ctx, u8, our_features->bits[BOLT11_FEATURE]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool feature_is_set(const u8 *features, size_t bit)
|
bool feature_is_set(const u8 *features, size_t bit)
|
||||||
@@ -239,7 +227,7 @@ bool feature_offered(const u8 *features, size_t f)
|
|||||||
bool feature_negotiated(const u8 *lfeatures, size_t f)
|
bool feature_negotiated(const u8 *lfeatures, size_t f)
|
||||||
{
|
{
|
||||||
return feature_offered(lfeatures, f)
|
return feature_offered(lfeatures, f)
|
||||||
&& feature_offered(our_feature_bits(INIT_FEATURE), f);
|
&& feature_offered(our_features->bits[INIT_FEATURE], f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -262,7 +250,7 @@ static int all_supported_features(const u8 *bitmap)
|
|||||||
if (!test_bit(bitmap, bitnum/8, bitnum%8))
|
if (!test_bit(bitmap, bitnum/8, bitnum%8))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (feature_offered(our_feature_bits(INIT_FEATURE), bitnum))
|
if (feature_offered(our_features->bits[INIT_FEATURE], bitnum))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return bitnum;
|
return bitnum;
|
||||||
@@ -307,8 +295,8 @@ const char **list_supported_features(const tal_t *ctx)
|
|||||||
{
|
{
|
||||||
const char **list = tal_arr(ctx, const char *, 0);
|
const char **list = tal_arr(ctx, const char *, 0);
|
||||||
|
|
||||||
for (size_t i = 0; i < tal_bytelen(our_feature_bits(INIT_FEATURE)) * 8; i++) {
|
for (size_t i = 0; i < tal_bytelen(our_features->bits[INIT_FEATURE]) * 8; i++) {
|
||||||
if (test_bit(our_feature_bits(INIT_FEATURE), i / 8, i % 8))
|
if (test_bit(our_features->bits[INIT_FEATURE], i / 8, i % 8))
|
||||||
tal_arr_expand(&list, feature_name(list, i));
|
tal_arr_expand(&list, feature_name(list, i));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,3 +326,24 @@ u8 *featurebits_or(const tal_t *ctx, const u8 *f1 TAKES, const u8 *f2 TAKES)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct feature_set *fromwire_feature_set(const tal_t *ctx,
|
||||||
|
const u8 **cursor, size_t *max)
|
||||||
|
{
|
||||||
|
struct feature_set *fset = tal(ctx, struct feature_set);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < ARRAY_SIZE(fset->bits); i++)
|
||||||
|
fset->bits[i] = fromwire_tal_arrn(fset, cursor, max,
|
||||||
|
fromwire_u16(cursor, max));
|
||||||
|
|
||||||
|
if (!*cursor)
|
||||||
|
return tal_free(fset);
|
||||||
|
return fset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void towire_feature_set(u8 **pptr, const struct feature_set *fset)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < ARRAY_SIZE(fset->bits); i++) {
|
||||||
|
towire_u16(pptr, tal_bytelen(fset->bits[i]));
|
||||||
|
towire_u8_array(pptr, fset->bits[i], tal_bytelen(fset->bits[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,9 +21,16 @@ struct feature_set {
|
|||||||
/* Initialize core features (for lightningd). */
|
/* Initialize core features (for lightningd). */
|
||||||
struct feature_set *features_core_init(const u8 *features TAKES);
|
struct feature_set *features_core_init(const u8 *features TAKES);
|
||||||
|
|
||||||
|
/* Initialize subdaemon features. */
|
||||||
|
void features_init(struct feature_set *fset TAKES);
|
||||||
|
|
||||||
/* Free feature allocations */
|
/* Free feature allocations */
|
||||||
void features_cleanup(void);
|
void features_cleanup(void);
|
||||||
|
|
||||||
|
struct feature_set *fromwire_feature_set(const tal_t *ctx,
|
||||||
|
const u8 **ptr, size_t *max);
|
||||||
|
void towire_feature_set(u8 **pptr, const struct feature_set *fset);
|
||||||
|
|
||||||
/* Returns -1 if we're OK with all these offered features, otherwise first
|
/* Returns -1 if we're OK with all these offered features, otherwise first
|
||||||
* unsupported (even) feature. */
|
* unsupported (even) feature. */
|
||||||
int features_unsupported(const u8 *features);
|
int features_unsupported(const u8 *features);
|
||||||
|
|||||||
@@ -30,6 +30,19 @@ bool amount_sat_eq(struct amount_sat a UNNEEDED, struct amount_sat b UNNEEDED)
|
|||||||
/* Generated stub for fromwire_fail */
|
/* Generated stub for fromwire_fail */
|
||||||
const void *fromwire_fail(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
const void *fromwire_fail(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire_fail called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire_fail called!\n"); abort(); }
|
||||||
|
/* Generated stub for fromwire_tal_arrn */
|
||||||
|
u8 *fromwire_tal_arrn(const tal_t *ctx UNNEEDED,
|
||||||
|
const u8 **cursor UNNEEDED, size_t *max UNNEEDED, size_t num UNNEEDED)
|
||||||
|
{ fprintf(stderr, "fromwire_tal_arrn 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 towire_u16 */
|
||||||
|
void towire_u16(u8 **pptr UNNEEDED, u16 v UNNEEDED)
|
||||||
|
{ fprintf(stderr, "towire_u16 called!\n"); abort(); }
|
||||||
|
/* Generated stub for towire_u8_array */
|
||||||
|
void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNEEDED)
|
||||||
|
{ fprintf(stderr, "towire_u8_array called!\n"); abort(); }
|
||||||
/* AUTOGENERATED MOCKS END */
|
/* AUTOGENERATED MOCKS END */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
#include <common/cryptomsg.h>
|
#include <common/cryptomsg.h>
|
||||||
|
#include <common/features.h>
|
||||||
#include <common/per_peer_state.h>
|
#include <common/per_peer_state.h>
|
||||||
#include <common/wireaddr.h>
|
#include <common/wireaddr.h>
|
||||||
#include <lightningd/gossip_msg.h>
|
#include <lightningd/gossip_msg.h>
|
||||||
|
|
||||||
msgtype,connectctl_init,2000
|
msgtype,connectctl_init,2000
|
||||||
msgdata,connectctl_init,chainparams,chainparams,
|
msgdata,connectctl_init,chainparams,chainparams,
|
||||||
|
msgdata,connectctl_init,feature_set,feature_set,
|
||||||
msgdata,connectctl_init,id,node_id,
|
msgdata,connectctl_init,id,node_id,
|
||||||
msgdata,connectctl_init,num_wireaddrs,u16,
|
msgdata,connectctl_init,num_wireaddrs,u16,
|
||||||
msgdata,connectctl_init,wireaddrs,wireaddr_internal,num_wireaddrs
|
msgdata,connectctl_init,wireaddrs,wireaddr_internal,num_wireaddrs
|
||||||
|
|||||||
|
@@ -1188,12 +1188,14 @@ static struct io_plan *connect_init(struct io_conn *conn,
|
|||||||
struct wireaddr_internal *proposed_wireaddr;
|
struct wireaddr_internal *proposed_wireaddr;
|
||||||
enum addr_listen_announce *proposed_listen_announce;
|
enum addr_listen_announce *proposed_listen_announce;
|
||||||
struct wireaddr *announcable;
|
struct wireaddr *announcable;
|
||||||
|
struct feature_set *feature_set;
|
||||||
char *tor_password;
|
char *tor_password;
|
||||||
|
|
||||||
/* Fields which require allocation are allocated off daemon */
|
/* Fields which require allocation are allocated off daemon */
|
||||||
if (!fromwire_connectctl_init(
|
if (!fromwire_connectctl_init(
|
||||||
daemon, msg,
|
daemon, msg,
|
||||||
&chainparams,
|
&chainparams,
|
||||||
|
&feature_set,
|
||||||
&daemon->id,
|
&daemon->id,
|
||||||
&proposed_wireaddr,
|
&proposed_wireaddr,
|
||||||
&proposed_listen_announce,
|
&proposed_listen_announce,
|
||||||
@@ -1206,6 +1208,9 @@ static struct io_plan *connect_init(struct io_conn *conn,
|
|||||||
master_badmsg(WIRE_CONNECTCTL_INIT, msg);
|
master_badmsg(WIRE_CONNECTCTL_INIT, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Now we know what features to advertize. */
|
||||||
|
features_init(take(feature_set));
|
||||||
|
|
||||||
if (!pubkey_from_node_id(&daemon->mykey, &daemon->id))
|
if (!pubkey_from_node_id(&daemon->mykey, &daemon->id))
|
||||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
"Invalid id for me %s",
|
"Invalid id for me %s",
|
||||||
|
|||||||
@@ -33,9 +33,22 @@ bool amount_sat_eq(struct amount_sat a UNNEEDED, struct amount_sat b UNNEEDED)
|
|||||||
/* Generated stub for fromwire_fail */
|
/* Generated stub for fromwire_fail */
|
||||||
const void *fromwire_fail(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
const void *fromwire_fail(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire_fail called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire_fail called!\n"); abort(); }
|
||||||
|
/* Generated stub for fromwire_tal_arrn */
|
||||||
|
u8 *fromwire_tal_arrn(const tal_t *ctx UNNEEDED,
|
||||||
|
const u8 **cursor UNNEEDED, size_t *max UNNEEDED, size_t num UNNEEDED)
|
||||||
|
{ fprintf(stderr, "fromwire_tal_arrn 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 notleak_ */
|
/* Generated stub for notleak_ */
|
||||||
void *notleak_(const void *ptr UNNEEDED, bool plus_children UNNEEDED)
|
void *notleak_(const void *ptr UNNEEDED, bool plus_children UNNEEDED)
|
||||||
{ fprintf(stderr, "notleak_ called!\n"); abort(); }
|
{ fprintf(stderr, "notleak_ 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_u8_array */
|
||||||
|
void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNEEDED)
|
||||||
|
{ fprintf(stderr, "towire_u8_array called!\n"); abort(); }
|
||||||
/* AUTOGENERATED MOCKS END */
|
/* AUTOGENERATED MOCKS END */
|
||||||
|
|
||||||
/* No randomness please, we want to replicate test vectors. */
|
/* No randomness please, we want to replicate test vectors. */
|
||||||
|
|||||||
@@ -33,9 +33,22 @@ bool amount_sat_eq(struct amount_sat a UNNEEDED, struct amount_sat b UNNEEDED)
|
|||||||
/* Generated stub for fromwire_fail */
|
/* Generated stub for fromwire_fail */
|
||||||
const void *fromwire_fail(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
const void *fromwire_fail(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire_fail called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire_fail called!\n"); abort(); }
|
||||||
|
/* Generated stub for fromwire_tal_arrn */
|
||||||
|
u8 *fromwire_tal_arrn(const tal_t *ctx UNNEEDED,
|
||||||
|
const u8 **cursor UNNEEDED, size_t *max UNNEEDED, size_t num UNNEEDED)
|
||||||
|
{ fprintf(stderr, "fromwire_tal_arrn 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 notleak_ */
|
/* Generated stub for notleak_ */
|
||||||
void *notleak_(const void *ptr UNNEEDED, bool plus_children UNNEEDED)
|
void *notleak_(const void *ptr UNNEEDED, bool plus_children UNNEEDED)
|
||||||
{ fprintf(stderr, "notleak_ called!\n"); abort(); }
|
{ fprintf(stderr, "notleak_ 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_u8_array */
|
||||||
|
void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNEEDED)
|
||||||
|
{ fprintf(stderr, "towire_u8_array called!\n"); abort(); }
|
||||||
/* AUTOGENERATED MOCKS END */
|
/* AUTOGENERATED MOCKS END */
|
||||||
|
|
||||||
/* No randomness please, we want to replicate test vectors. */
|
/* No randomness please, we want to replicate test vectors. */
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
#include <common/cryptomsg.h>
|
#include <common/cryptomsg.h>
|
||||||
|
#include <common/features.h>
|
||||||
#include <common/wireaddr.h>
|
#include <common/wireaddr.h>
|
||||||
#include <wire/gen_onion_wire.h>
|
#include <wire/gen_onion_wire.h>
|
||||||
|
|
||||||
# Initialize the gossip daemon.
|
# Initialize the gossip daemon.
|
||||||
msgtype,gossipctl_init,3000
|
msgtype,gossipctl_init,3000
|
||||||
msgdata,gossipctl_init,chainparams,chainparams,
|
msgdata,gossipctl_init,chainparams,chainparams,
|
||||||
|
msgdata,gossipctl_init,feature_set,feature_set,
|
||||||
msgdata,gossipctl_init,id,node_id,
|
msgdata,gossipctl_init,id,node_id,
|
||||||
msgdata,gossipctl_init,gflen,u16,
|
msgdata,gossipctl_init,gflen,u16,
|
||||||
msgdata,gossipctl_init,globalfeatures,u8,gflen
|
msgdata,gossipctl_init,globalfeatures,u8,gflen
|
||||||
|
|||||||
|
Can't render this file because it has a wrong number of fields in line 6.
|
@@ -828,9 +828,11 @@ static struct io_plan *gossip_init(struct io_conn *conn,
|
|||||||
u32 *dev_gossip_time;
|
u32 *dev_gossip_time;
|
||||||
bool dev_fast_gossip, dev_fast_gossip_prune;
|
bool dev_fast_gossip, dev_fast_gossip_prune;
|
||||||
u32 timestamp;
|
u32 timestamp;
|
||||||
|
struct feature_set *feature_set;
|
||||||
|
|
||||||
if (!fromwire_gossipctl_init(daemon, msg,
|
if (!fromwire_gossipctl_init(daemon, msg,
|
||||||
&chainparams,
|
&chainparams,
|
||||||
|
&feature_set,
|
||||||
&daemon->id,
|
&daemon->id,
|
||||||
&daemon->nodefeatures,
|
&daemon->nodefeatures,
|
||||||
daemon->rgb,
|
daemon->rgb,
|
||||||
@@ -842,6 +844,7 @@ static struct io_plan *gossip_init(struct io_conn *conn,
|
|||||||
master_badmsg(WIRE_GOSSIPCTL_INIT, msg);
|
master_badmsg(WIRE_GOSSIPCTL_INIT, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
features_init(take(feature_set));
|
||||||
daemon->rstate = new_routing_state(daemon,
|
daemon->rstate = new_routing_state(daemon,
|
||||||
&daemon->id,
|
&daemon->id,
|
||||||
&daemon->peers,
|
&daemon->peers,
|
||||||
|
|||||||
@@ -459,6 +459,7 @@ void peer_start_channeld(struct channel *channel,
|
|||||||
|
|
||||||
initmsg = towire_channel_init(tmpctx,
|
initmsg = towire_channel_init(tmpctx,
|
||||||
chainparams,
|
chainparams,
|
||||||
|
ld->feature_set,
|
||||||
&channel->funding_txid,
|
&channel->funding_txid,
|
||||||
channel->funding_outnum,
|
channel->funding_outnum,
|
||||||
channel->funding,
|
channel->funding,
|
||||||
|
|||||||
@@ -370,6 +370,7 @@ int connectd_init(struct lightningd *ld)
|
|||||||
|
|
||||||
msg = towire_connectctl_init(
|
msg = towire_connectctl_init(
|
||||||
tmpctx, chainparams,
|
tmpctx, chainparams,
|
||||||
|
ld->feature_set,
|
||||||
&ld->id,
|
&ld->id,
|
||||||
wireaddrs,
|
wireaddrs,
|
||||||
listen_announce,
|
listen_announce,
|
||||||
|
|||||||
@@ -214,6 +214,7 @@ void gossip_init(struct lightningd *ld, int connectd_fd)
|
|||||||
msg = towire_gossipctl_init(
|
msg = towire_gossipctl_init(
|
||||||
tmpctx,
|
tmpctx,
|
||||||
chainparams,
|
chainparams,
|
||||||
|
ld->feature_set,
|
||||||
&ld->id,
|
&ld->id,
|
||||||
node_featurebits,
|
node_featurebits,
|
||||||
ld->rgb,
|
ld->rgb,
|
||||||
|
|||||||
@@ -119,6 +119,9 @@ struct lightningd {
|
|||||||
/* This is us. */
|
/* This is us. */
|
||||||
struct node_id id;
|
struct node_id id;
|
||||||
|
|
||||||
|
/* Feature set we offer. */
|
||||||
|
const struct feature_set *feature_set;
|
||||||
|
|
||||||
/* My name is... my favorite color is... */
|
/* My name is... my favorite color is... */
|
||||||
u8 *alias; /* At least 32 bytes (zero-filled) */
|
u8 *alias; /* At least 32 bytes (zero-filled) */
|
||||||
u8 *rgb; /* tal_len() == 3. */
|
u8 *rgb; /* tal_len() == 3. */
|
||||||
|
|||||||
@@ -999,6 +999,7 @@ void peer_start_openingd(struct peer *peer,
|
|||||||
|
|
||||||
msg = towire_opening_init(NULL,
|
msg = towire_opening_init(NULL,
|
||||||
chainparams,
|
chainparams,
|
||||||
|
peer->ld->feature_set,
|
||||||
&uc->our_config,
|
&uc->our_config,
|
||||||
max_to_self_delay,
|
max_to_self_delay,
|
||||||
min_effective_htlc_capacity,
|
min_effective_htlc_capacity,
|
||||||
|
|||||||
@@ -1004,7 +1004,7 @@ void setup_color_and_alias(struct lightningd *ld)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_default_features(void)
|
static struct feature_set *setup_default_features(void)
|
||||||
{
|
{
|
||||||
static const u32 default_features[] = {
|
static const u32 default_features[] = {
|
||||||
OPTIONAL_FEATURE(OPT_DATA_LOSS_PROTECT),
|
OPTIONAL_FEATURE(OPT_DATA_LOSS_PROTECT),
|
||||||
@@ -1021,7 +1021,7 @@ static void setup_default_features(void)
|
|||||||
for (size_t i = 0; i < ARRAY_SIZE(default_features); i++)
|
for (size_t i = 0; i < ARRAY_SIZE(default_features); i++)
|
||||||
set_feature_bit(&f, default_features[i]);
|
set_feature_bit(&f, default_features[i]);
|
||||||
|
|
||||||
features_core_init(take(f));
|
return features_core_init(take(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_early_opts(struct lightningd *ld, int argc, char *argv[])
|
void handle_early_opts(struct lightningd *ld, int argc, char *argv[])
|
||||||
@@ -1030,7 +1030,7 @@ void handle_early_opts(struct lightningd *ld, int argc, char *argv[])
|
|||||||
setup_option_allocators();
|
setup_option_allocators();
|
||||||
|
|
||||||
/* Make sure options are populated. */
|
/* Make sure options are populated. */
|
||||||
setup_default_features();
|
ld->feature_set = setup_default_features();
|
||||||
|
|
||||||
/*~ List features immediately, before doing anything interesting */
|
/*~ List features immediately, before doing anything interesting */
|
||||||
opt_register_early_noarg("--list-features-only",
|
opt_register_early_noarg("--list-features-only",
|
||||||
|
|||||||
@@ -54,6 +54,13 @@ bool fromwire_onchain_spent(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, s
|
|||||||
/* Generated stub for fromwire_peektype */
|
/* Generated stub for fromwire_peektype */
|
||||||
int fromwire_peektype(const u8 *cursor UNNEEDED)
|
int fromwire_peektype(const u8 *cursor UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire_peektype called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire_peektype called!\n"); abort(); }
|
||||||
|
/* Generated stub for fromwire_tal_arrn */
|
||||||
|
u8 *fromwire_tal_arrn(const tal_t *ctx UNNEEDED,
|
||||||
|
const u8 **cursor UNNEEDED, size_t *max UNNEEDED, size_t num UNNEEDED)
|
||||||
|
{ fprintf(stderr, "fromwire_tal_arrn 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 htlc_offered_wscript */
|
/* Generated stub for htlc_offered_wscript */
|
||||||
u8 *htlc_offered_wscript(const tal_t *ctx UNNEEDED,
|
u8 *htlc_offered_wscript(const tal_t *ctx UNNEEDED,
|
||||||
const struct ripemd160 *ripemd UNNEEDED,
|
const struct ripemd160 *ripemd UNNEEDED,
|
||||||
@@ -164,6 +171,12 @@ u8 *towire_onchain_missing_htlc_output(const tal_t *ctx UNNEEDED, const struct h
|
|||||||
/* Generated stub for towire_onchain_unwatch_tx */
|
/* Generated stub for towire_onchain_unwatch_tx */
|
||||||
u8 *towire_onchain_unwatch_tx(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *txid UNNEEDED)
|
u8 *towire_onchain_unwatch_tx(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *txid UNNEEDED)
|
||||||
{ fprintf(stderr, "towire_onchain_unwatch_tx called!\n"); abort(); }
|
{ fprintf(stderr, "towire_onchain_unwatch_tx 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_u8_array */
|
||||||
|
void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNEEDED)
|
||||||
|
{ fprintf(stderr, "towire_u8_array called!\n"); abort(); }
|
||||||
/* AUTOGENERATED MOCKS END */
|
/* AUTOGENERATED MOCKS END */
|
||||||
|
|
||||||
/* Stubs which do get called. */
|
/* Stubs which do get called. */
|
||||||
|
|||||||
@@ -55,6 +55,13 @@ bool fromwire_onchain_known_preimage(const void *p UNNEEDED, struct preimage *pr
|
|||||||
/* Generated stub for fromwire_onchain_spent */
|
/* Generated stub for fromwire_onchain_spent */
|
||||||
bool fromwire_onchain_spent(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct bitcoin_tx **tx UNNEEDED, u32 *input_num UNNEEDED, u32 *blockheight UNNEEDED)
|
bool fromwire_onchain_spent(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct bitcoin_tx **tx UNNEEDED, u32 *input_num UNNEEDED, u32 *blockheight UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire_onchain_spent called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire_onchain_spent called!\n"); abort(); }
|
||||||
|
/* Generated stub for fromwire_tal_arrn */
|
||||||
|
u8 *fromwire_tal_arrn(const tal_t *ctx UNNEEDED,
|
||||||
|
const u8 **cursor UNNEEDED, size_t *max UNNEEDED, size_t num UNNEEDED)
|
||||||
|
{ fprintf(stderr, "fromwire_tal_arrn 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 htlc_offered_wscript */
|
/* Generated stub for htlc_offered_wscript */
|
||||||
u8 *htlc_offered_wscript(const tal_t *ctx UNNEEDED,
|
u8 *htlc_offered_wscript(const tal_t *ctx UNNEEDED,
|
||||||
const struct ripemd160 *ripemd UNNEEDED,
|
const struct ripemd160 *ripemd UNNEEDED,
|
||||||
@@ -182,6 +189,12 @@ u8 *towire_onchain_missing_htlc_output(const tal_t *ctx UNNEEDED, const struct h
|
|||||||
/* Generated stub for towire_onchain_unwatch_tx */
|
/* Generated stub for towire_onchain_unwatch_tx */
|
||||||
u8 *towire_onchain_unwatch_tx(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *txid UNNEEDED)
|
u8 *towire_onchain_unwatch_tx(const tal_t *ctx UNNEEDED, const struct bitcoin_txid *txid UNNEEDED)
|
||||||
{ fprintf(stderr, "towire_onchain_unwatch_tx called!\n"); abort(); }
|
{ fprintf(stderr, "towire_onchain_unwatch_tx 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_u8_array */
|
||||||
|
void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNEEDED)
|
||||||
|
{ fprintf(stderr, "towire_u8_array called!\n"); abort(); }
|
||||||
/* Generated stub for wire_sync_read */
|
/* Generated stub for wire_sync_read */
|
||||||
u8 *wire_sync_read(const tal_t *ctx UNNEEDED, int fd UNNEEDED)
|
u8 *wire_sync_read(const tal_t *ctx UNNEEDED, int fd UNNEEDED)
|
||||||
{ fprintf(stderr, "wire_sync_read called!\n"); abort(); }
|
{ fprintf(stderr, "wire_sync_read called!\n"); abort(); }
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
#include <common/cryptomsg.h>
|
#include <common/cryptomsg.h>
|
||||||
#include <common/channel_config.h>
|
#include <common/channel_config.h>
|
||||||
#include <common/derive_basepoints.h>
|
#include <common/derive_basepoints.h>
|
||||||
|
#include <common/features.h>
|
||||||
#include <common/per_peer_state.h>
|
#include <common/per_peer_state.h>
|
||||||
|
|
||||||
msgtype,opening_init,6000
|
msgtype,opening_init,6000
|
||||||
# Which network are we configured for?
|
# Which network are we configured for?
|
||||||
msgdata,opening_init,chainparams,chainparams,
|
msgdata,opening_init,chainparams,chainparams,
|
||||||
|
msgdata,opening_init,feature_set,feature_set,
|
||||||
# Base configuration we'll offer (channel reserve will vary with amount)
|
# Base configuration we'll offer (channel reserve will vary with amount)
|
||||||
msgdata,opening_init,our_config,channel_config,
|
msgdata,opening_init,our_config,channel_config,
|
||||||
# Minimum/maximum configuration values we'll accept
|
# Minimum/maximum configuration values we'll accept
|
||||||
|
|||||||
|
@@ -1481,6 +1481,7 @@ int main(int argc, char *argv[])
|
|||||||
struct state *state = tal(NULL, struct state);
|
struct state *state = tal(NULL, struct state);
|
||||||
struct secret *none;
|
struct secret *none;
|
||||||
struct channel_id *force_tmp_channel_id;
|
struct channel_id *force_tmp_channel_id;
|
||||||
|
struct feature_set *feature_set;
|
||||||
|
|
||||||
subdaemon_setup(argc, argv);
|
subdaemon_setup(argc, argv);
|
||||||
|
|
||||||
@@ -1492,6 +1493,7 @@ int main(int argc, char *argv[])
|
|||||||
msg = wire_sync_read(tmpctx, REQ_FD);
|
msg = wire_sync_read(tmpctx, REQ_FD);
|
||||||
if (!fromwire_opening_init(state, msg,
|
if (!fromwire_opening_init(state, msg,
|
||||||
&chainparams,
|
&chainparams,
|
||||||
|
&feature_set,
|
||||||
&state->localconf,
|
&state->localconf,
|
||||||
&state->max_to_self_delay,
|
&state->max_to_self_delay,
|
||||||
&state->min_effective_htlc_capacity,
|
&state->min_effective_htlc_capacity,
|
||||||
@@ -1507,6 +1509,8 @@ int main(int argc, char *argv[])
|
|||||||
&dev_fast_gossip))
|
&dev_fast_gossip))
|
||||||
master_badmsg(WIRE_OPENING_INIT, msg);
|
master_badmsg(WIRE_OPENING_INIT, msg);
|
||||||
|
|
||||||
|
features_init(take(feature_set));
|
||||||
|
|
||||||
#if DEVELOPER
|
#if DEVELOPER
|
||||||
dev_force_tmp_channel_id = force_tmp_channel_id;
|
dev_force_tmp_channel_id = force_tmp_channel_id;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -225,6 +225,7 @@ class Type(FieldSet):
|
|||||||
'fee_states',
|
'fee_states',
|
||||||
'onionreply',
|
'onionreply',
|
||||||
'witscript',
|
'witscript',
|
||||||
|
'feature_set',
|
||||||
]
|
]
|
||||||
|
|
||||||
# Some BOLT types are re-typed based on their field name
|
# Some BOLT types are re-typed based on their field name
|
||||||
|
|||||||
Reference in New Issue
Block a user