Skip to content

Commit 4861e2c

Browse files
committed
connectd: add network to init message
This implements lightning/bolts#682.
1 parent 0e0579c commit 4861e2c

File tree

8 files changed

+93
-41
lines changed

8 files changed

+93
-41
lines changed

connectd/connectd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ static struct io_plan *handshake_in_success(struct io_conn *conn,
472472
struct node_id id;
473473
node_id_from_pubkey(&id, id_key);
474474
status_peer_debug(&id, "Connect IN");
475-
return peer_exchange_initmsg(conn, daemon, cs, &id, addr);
475+
return peer_exchange_initmsg(conn, daemon, cs, &id, addr, daemon->chainparams);
476476
}
477477

478478
/*~ When we get a connection in we set up its network address then call
@@ -532,7 +532,7 @@ static struct io_plan *handshake_out_success(struct io_conn *conn,
532532
node_id_from_pubkey(&id, key);
533533
connect->connstate = "Exchanging init messages";
534534
status_peer_debug(&id, "Connect OUT");
535-
return peer_exchange_initmsg(conn, connect->daemon, cs, &id, addr);
535+
return peer_exchange_initmsg(conn, connect->daemon, cs, &id, addr, connect->daemon->chainparams);
536536
}
537537

538538
struct io_plan *connection_out(struct io_conn *conn, struct connecting *connect)

connectd/peer_exchange_initmsg.c

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,21 @@ struct peer {
2525

2626
/* Buffer for reading/writing message. */
2727
u8 *msg;
28+
29+
/* We signal the network we're on at init. */
30+
const struct bitcoin_blkid *genesis_blockhash;
2831
};
2932

33+
static bool contains_common_chain(struct bitcoin_blkid *chains,
34+
const struct bitcoin_blkid *genesis_hash)
35+
{
36+
for (size_t i = 0; i < tal_count(chains); i++) {
37+
if (bitcoin_blkid_eq(&chains[0], genesis_hash))
38+
return true;
39+
}
40+
return false;
41+
}
42+
3043
/* Here in case we need to read another message. */
3144
static struct io_plan *read_init(struct io_conn *conn, struct peer *peer);
3245

@@ -36,6 +49,7 @@ static struct io_plan *peer_init_received(struct io_conn *conn,
3649
u8 *msg = cryptomsg_decrypt_body(tmpctx, &peer->cs, peer->msg);
3750
u8 *globalfeatures, *features;
3851
int unsup;
52+
struct tlv_init_tlvs *tlvs = tlv_init_tlvs_new(msg);
3953

4054
if (!msg)
4155
return io_close(conn);
@@ -51,13 +65,35 @@ static struct io_plan *peer_init_received(struct io_conn *conn,
5165
if (unlikely(is_unknown_msg_discardable(msg)))
5266
return read_init(conn, peer);
5367

54-
if (!fromwire_init(tmpctx, msg, &globalfeatures, &features)) {
68+
if (!fromwire_init(tmpctx, msg, &globalfeatures, &features, tlvs)) {
5569
status_peer_debug(&peer->id,
5670
"bad fromwire_init '%s', closing",
5771
tal_hex(tmpctx, msg));
5872
return io_close(conn);
5973
}
6074

75+
/* BOLT-ef7c97c02b6fa67a1df1af30b3843eb576100ebd #1:
76+
* The receiving node:
77+
* ...
78+
* - upon receiving `networks` containing no common chains
79+
* - MAY fail the connection.
80+
*/
81+
if (tlvs->networks) {
82+
if (!tlvs->networks->chains) {
83+
status_peer_debug(&peer->id,
84+
"bad networks TLV in init '%s', closing",
85+
tal_hex(tmpctx, msg));
86+
return io_close(conn);
87+
}
88+
if (!contains_common_chain(tlvs->networks->chains,
89+
peer->genesis_blockhash)) {
90+
status_peer_debug(&peer->id,
91+
"No common chain with this peer '%s', closing",
92+
tal_hex(tmpctx, msg));
93+
return io_close(conn);
94+
}
95+
}
96+
6197
/* The globalfeatures field is now unused, but there was a
6298
* window where it was: combine the two. */
6399
for (size_t i = 0; i < tal_bytelen(globalfeatures) * 8; i++) {
@@ -131,23 +167,34 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn,
131167
struct daemon *daemon,
132168
const struct crypto_state *cs,
133169
const struct node_id *id,
134-
const struct wireaddr_internal *addr)
170+
const struct wireaddr_internal *addr,
171+
const struct chainparams *chainparams)
135172
{
136173
/* If conn is closed, forget peer */
137174
struct peer *peer = tal(conn, struct peer);
138175
struct io_plan *(*next)(struct io_conn *, struct peer *);
176+
struct tlv_init_tlvs *tlvs;
139177

140178
peer->daemon = daemon;
141179
peer->id = *id;
142180
peer->addr = *addr;
143181
peer->cs = *cs;
182+
peer->genesis_blockhash = &chainparams->genesis_blockhash;
144183

145-
/* BOLT #1:
184+
/* BOLT-ef7c97c02b6fa67a1df1af30b3843eb576100ebd #1:
146185
*
147186
* The sending node:
148187
* - MUST send `init` as the first Lightning message for any
149188
* connection.
189+
* ...
190+
* - SHOULD set `networks` to all chains it will gossip or open
191+
* channels for.
150192
*/
193+
tlvs = tlv_init_tlvs_new(tmpctx);
194+
tlvs->networks = tal(tlvs, struct tlv_init_tlvs_networks);
195+
tlvs->networks->chains = tal_arr(tlvs->networks, struct bitcoin_blkid, 1);
196+
tlvs->networks->chains[0] = chainparams->genesis_blockhash;
197+
151198
/* Initially, there were two sets of feature bits: global and local.
152199
* Local affected peer nodes only, global affected everyone. Both were
153200
* sent in the `init` message, but node_announcement only advertized
@@ -167,7 +214,8 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn,
167214
* from now on they'll all go in initfeatures. */
168215
peer->msg = towire_init(NULL,
169216
get_offered_globalinitfeatures(tmpctx),
170-
get_offered_initfeatures(tmpctx));
217+
get_offered_initfeatures(tmpctx),
218+
tlvs);
171219
status_peer_io(LOG_IO_OUT, &peer->id, peer->msg);
172220
peer->msg = cryptomsg_encrypt_msg(peer, &peer->cs, take(peer->msg));
173221

connectd/peer_exchange_initmsg.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn,
1313
struct daemon *daemon,
1414
const struct crypto_state *cs,
1515
const struct node_id *id,
16-
const struct wireaddr_internal *addr);
16+
const struct wireaddr_internal *addr,
17+
const struct chainparams *chainparams);
1718

1819
#endif /* LIGHTNING_CONNECTD_PEER_EXCHANGE_INITMSG_H */

devtools/gossipwith.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ static struct io_plan *handshake_success(struct io_conn *conn,
137137
OPTIONAL_FEATURE(OPT_INITIAL_ROUTING_SYNC));
138138

139139
if (!no_init) {
140-
msg = towire_init(NULL, NULL, features);
140+
msg = towire_init(NULL, NULL, features, NULL);
141141

142142
sync_crypto_write(pps, take(msg));
143143
/* Ignore their init message. */

lightningd/connect_control.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,8 @@ int connectd_init(struct lightningd *ld)
361361
}
362362

363363
msg = towire_connectctl_init(
364-
tmpctx, &ld->id,
364+
tmpctx, chainparams,
365+
&ld->id,
365366
wireaddrs,
366367
listen_announce,
367368
ld->proxyaddr, ld->use_proxy_always || ld->pure_tor_setup,

wire/extracted_peer_wire_csv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ msgdata,init,gflen,u16,
33
msgdata,init,globalfeatures,byte,gflen
44
msgdata,init,lflen,u16,
55
msgdata,init,localfeatures,byte,lflen
6+
msgdata,init,tlvs,init_tlvs,
7+
tlvtype,init_tlvs,networks,1
8+
tlvdata,init_tlvs,networks,chains,chain_hash,...
69
msgtype,error,17
710
msgdata,error,channel_id,channel_id,
811
msgdata,error,len,u16,

wire/test/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ ALL_TEST_PROGRAMS += $(WIRE_TEST_PROGRAMS)
2121

2222
wire-tests: $(WIRE_TEST_PROGRAMS:%=unittest/%)
2323

24+
wire/test/run-peer-wire: wire/gen_peer_wire.o wire/tlvstream.o common/bigsize.o

wire/test/run-peer-wire.c

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1-
#include "../gen_peer_wire.c"
2-
31
#include "../towire.c"
42
#include "../fromwire.c"
53
#include "../peer_wire.c"
64

75
#include <assert.h>
86
#include <stdio.h>
7+
8+
#include <ccan/str/hex/hex.h>
99
#include <common/amount.h>
10+
#include <common/bigsize.h>
11+
#include <bitcoin/chainparams.h>
1012
#include <common/sphinx.h>
13+
#include <wire/gen_peer_wire.h>
1114

1215
secp256k1_context *secp256k1_ctx;
1316

@@ -31,24 +34,6 @@ bool amount_sat_eq(struct amount_sat a UNNEEDED, struct amount_sat b UNNEEDED)
3134
struct amount_sat a UNNEEDED,
3235
struct amount_sat b UNNEEDED)
3336
{ fprintf(stderr, "amount_sat_sub called!\n"); abort(); }
34-
/* Generated stub for bigsize_get */
35-
size_t bigsize_get(const u8 *p UNNEEDED, size_t max UNNEEDED, bigsize_t *val UNNEEDED)
36-
{ fprintf(stderr, "bigsize_get called!\n"); abort(); }
37-
/* Generated stub for bigsize_put */
38-
size_t bigsize_put(u8 buf[BIGSIZE_MAX_LEN] UNNEEDED, bigsize_t v UNNEEDED)
39-
{ fprintf(stderr, "bigsize_put called!\n"); abort(); }
40-
/* Generated stub for fromwire_tlvs */
41-
bool fromwire_tlvs(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
42-
const struct tlv_record_type types[] UNNEEDED,
43-
size_t num_types UNNEEDED,
44-
void *record UNNEEDED)
45-
{ fprintf(stderr, "fromwire_tlvs called!\n"); abort(); }
46-
/* Generated stub for towire_tlvs */
47-
void towire_tlvs(u8 **pptr UNNEEDED,
48-
const struct tlv_record_type types[] UNNEEDED,
49-
size_t num_types UNNEEDED,
50-
const void *record UNNEEDED)
51-
{ fprintf(stderr, "towire_tlvs called!\n"); abort(); }
5237
/* AUTOGENERATED MOCKS END */
5338

5439
/* memsetting pubkeys doesn't work */
@@ -236,6 +221,7 @@ struct msg_channel_announcement {
236221
struct msg_init {
237222
u8 *globalfeatures;
238223
u8 *localfeatures;
224+
struct tlv_init_tlvs *tlvs;
239225
};
240226
struct msg_update_add_htlc {
241227
struct channel_id channel_id;
@@ -761,16 +747,19 @@ static void *towire_struct_init(const tal_t *ctx,
761747
{
762748
return towire_init(ctx,
763749
s->globalfeatures,
764-
s->localfeatures);
750+
s->localfeatures,
751+
s->tlvs);
765752
}
766753

767754
static struct msg_init *fromwire_struct_init(const tal_t *ctx, const void *p)
768755
{
769756
struct msg_init *s = tal(ctx, struct msg_init);
757+
s->tlvs = tlv_init_tlvs_new(s);
770758

771759
if (!fromwire_init(s, p,
772760
&s->globalfeatures,
773-
&s->localfeatures))
761+
&s->localfeatures,
762+
s->tlvs))
774763
return tal_free(s);
775764

776765
return s;
@@ -844,6 +833,9 @@ static bool error_eq(const struct msg_error *a,
844833
static bool init_eq(const struct msg_init *a,
845834
const struct msg_init *b)
846835
{
836+
for (size_t i = 0; i < tal_count(a->tlvs->networks->chains); i++)
837+
assert(bitcoin_blkid_eq(&a->tlvs->networks->chains[i],
838+
&b->tlvs->networks->chains[i]));
847839
return eq_var(a, b, globalfeatures)
848840
&& eq_var(a, b, localfeatures);
849841
}
@@ -959,6 +951,7 @@ int main(void)
959951
void *ctx = tal(NULL, char);
960952
size_t i;
961953
u8 *msg;
954+
const struct chainparams **chains;
962955

963956
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
964957
| SECP256K1_CONTEXT_SIGN);
@@ -1039,16 +1032,21 @@ int main(void)
10391032
assert(error_eq(&e, e2));
10401033
test_corruption(&e, e2, error);
10411034

1042-
memset(&init, 2, sizeof(init));
1043-
init.globalfeatures = tal_arr(ctx, u8, 2);
1044-
memset(init.globalfeatures, 2, 2);
1045-
init.localfeatures = tal_arr(ctx, u8, 2);
1046-
memset(init.localfeatures, 2, 2);
1047-
1048-
msg = towire_struct_init(ctx, &init);
1049-
init2 = fromwire_struct_init(ctx, msg);
1050-
assert(init_eq(&init, init2));
1051-
test_corruption(&init, init2, init);
1035+
chains = chainparams_for_networks(ctx);
1036+
for (i = 0; i < tal_count(chains); i++) {
1037+
memset(&init, 2, sizeof(init));
1038+
init.globalfeatures = tal_arr(ctx, u8, 2);
1039+
memset(init.globalfeatures, 2, 2);
1040+
init.localfeatures = tal_arr(ctx, u8, 2);
1041+
memset(init.localfeatures, 2, 2);
1042+
init.tlvs = tlv_init_tlvs_new(ctx);
1043+
init.tlvs->networks = tal(init.tlvs, struct tlv_init_tlvs_networks);
1044+
init.tlvs->networks->chains = tal_arr(ctx, struct bitcoin_blkid, 1);
1045+
init.tlvs->networks->chains[0] = chains[i]->genesis_blockhash;
1046+
msg = towire_struct_init(ctx, &init);
1047+
init2 = fromwire_struct_init(ctx, msg);
1048+
assert(init_eq(&init, init2));
1049+
}
10521050

10531051
memset(&uf, 2, sizeof(uf));
10541052

0 commit comments

Comments
 (0)