mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
connectd: add network to init message
Changelog-Added: protocol: We now signal the network we are running on at init.
This commit is contained in:
parent
4b13b88f6c
commit
3322048774
@ -27,6 +27,15 @@ struct peer {
|
||||
u8 *msg;
|
||||
};
|
||||
|
||||
static bool contains_common_chain(struct bitcoin_blkid *chains)
|
||||
{
|
||||
for (size_t i = 0; i < tal_count(chains); i++) {
|
||||
if (bitcoin_blkid_eq(&chains[0], &chainparams->genesis_blockhash))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Here in case we need to read another message. */
|
||||
static struct io_plan *read_init(struct io_conn *conn, struct peer *peer);
|
||||
|
||||
@ -36,6 +45,7 @@ static struct io_plan *peer_init_received(struct io_conn *conn,
|
||||
u8 *msg = cryptomsg_decrypt_body(tmpctx, &peer->cs, peer->msg);
|
||||
u8 *globalfeatures, *features;
|
||||
int unsup;
|
||||
struct tlv_init_tlvs *tlvs = tlv_init_tlvs_new(msg);
|
||||
|
||||
if (!msg)
|
||||
return io_close(conn);
|
||||
@ -51,13 +61,34 @@ static struct io_plan *peer_init_received(struct io_conn *conn,
|
||||
if (unlikely(is_unknown_msg_discardable(msg)))
|
||||
return read_init(conn, peer);
|
||||
|
||||
if (!fromwire_init(tmpctx, msg, &globalfeatures, &features)) {
|
||||
if (!fromwire_init(tmpctx, msg, &globalfeatures, &features, tlvs)) {
|
||||
status_peer_debug(&peer->id,
|
||||
"bad fromwire_init '%s', closing",
|
||||
tal_hex(tmpctx, msg));
|
||||
return io_close(conn);
|
||||
}
|
||||
|
||||
/* BOLT-ef7c97c02b6fa67a1df1af30b3843eb576100ebd #1:
|
||||
* The receiving node:
|
||||
* ...
|
||||
* - upon receiving `networks` containing no common chains
|
||||
* - MAY fail the connection.
|
||||
*/
|
||||
if (tlvs->networks) {
|
||||
if (!tlvs->networks->chains) {
|
||||
status_peer_debug(&peer->id,
|
||||
"bad networks TLV in init '%s', closing",
|
||||
tal_hex(tmpctx, msg));
|
||||
return io_close(conn);
|
||||
}
|
||||
if (!contains_common_chain(tlvs->networks->chains)) {
|
||||
status_peer_debug(&peer->id,
|
||||
"No common chain with this peer '%s', closing",
|
||||
tal_hex(tmpctx, msg));
|
||||
return io_close(conn);
|
||||
}
|
||||
}
|
||||
|
||||
/* The globalfeatures field is now unused, but there was a
|
||||
* window where it was: combine the two. */
|
||||
for (size_t i = 0; i < tal_bytelen(globalfeatures) * 8; i++) {
|
||||
@ -136,18 +167,27 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn,
|
||||
/* If conn is closed, forget peer */
|
||||
struct peer *peer = tal(conn, struct peer);
|
||||
struct io_plan *(*next)(struct io_conn *, struct peer *);
|
||||
struct tlv_init_tlvs *tlvs;
|
||||
|
||||
peer->daemon = daemon;
|
||||
peer->id = *id;
|
||||
peer->addr = *addr;
|
||||
peer->cs = *cs;
|
||||
|
||||
/* BOLT #1:
|
||||
/* BOLT-ef7c97c02b6fa67a1df1af30b3843eb576100ebd #1:
|
||||
*
|
||||
* The sending node:
|
||||
* - MUST send `init` as the first Lightning message for any
|
||||
* connection.
|
||||
* ...
|
||||
* - SHOULD set `networks` to all chains it will gossip or open
|
||||
* channels for.
|
||||
*/
|
||||
tlvs = tlv_init_tlvs_new(tmpctx);
|
||||
tlvs->networks = tal(tlvs, struct tlv_init_tlvs_networks);
|
||||
tlvs->networks->chains = tal_arr(tlvs->networks, struct bitcoin_blkid, 1);
|
||||
tlvs->networks->chains[0] = chainparams->genesis_blockhash;
|
||||
|
||||
/* Initially, there were two sets of feature bits: global and local.
|
||||
* Local affected peer nodes only, global affected everyone. Both were
|
||||
* sent in the `init` message, but node_announcement only advertized
|
||||
@ -167,7 +207,8 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn,
|
||||
* from now on they'll all go in initfeatures. */
|
||||
peer->msg = towire_init(NULL,
|
||||
get_offered_globalinitfeatures(tmpctx),
|
||||
get_offered_initfeatures(tmpctx));
|
||||
get_offered_initfeatures(tmpctx),
|
||||
tlvs);
|
||||
status_peer_io(LOG_IO_OUT, &peer->id, peer->msg);
|
||||
peer->msg = cryptomsg_encrypt_msg(peer, &peer->cs, take(peer->msg));
|
||||
|
||||
|
@ -137,7 +137,7 @@ static struct io_plan *handshake_success(struct io_conn *conn,
|
||||
OPTIONAL_FEATURE(OPT_INITIAL_ROUTING_SYNC));
|
||||
|
||||
if (!no_init) {
|
||||
msg = towire_init(NULL, NULL, features);
|
||||
msg = towire_init(NULL, NULL, features, NULL);
|
||||
|
||||
sync_crypto_write(pps, take(msg));
|
||||
/* Ignore their init message. */
|
||||
|
@ -361,7 +361,8 @@ int connectd_init(struct lightningd *ld)
|
||||
}
|
||||
|
||||
msg = towire_connectctl_init(
|
||||
tmpctx, &ld->id,
|
||||
tmpctx, chainparams,
|
||||
&ld->id,
|
||||
wireaddrs,
|
||||
listen_announce,
|
||||
ld->proxyaddr, ld->use_proxy_always || ld->pure_tor_setup,
|
||||
|
@ -3,6 +3,9 @@ msgdata,init,gflen,u16,
|
||||
msgdata,init,globalfeatures,byte,gflen
|
||||
msgdata,init,lflen,u16,
|
||||
msgdata,init,localfeatures,byte,lflen
|
||||
msgdata,init,tlvs,init_tlvs,
|
||||
tlvtype,init_tlvs,networks,1
|
||||
tlvdata,init_tlvs,networks,chains,chain_hash,...
|
||||
msgtype,error,17
|
||||
msgdata,error,channel_id,channel_id,
|
||||
msgdata,error,len,u16,
|
||||
|
@ -21,3 +21,4 @@ ALL_TEST_PROGRAMS += $(WIRE_TEST_PROGRAMS)
|
||||
|
||||
wire-tests: $(WIRE_TEST_PROGRAMS:%=unittest/%)
|
||||
|
||||
wire/test/run-peer-wire: wire/gen_peer_wire.o wire/tlvstream.o common/bigsize.o
|
||||
|
@ -1,13 +1,16 @@
|
||||
#include "../gen_peer_wire.c"
|
||||
|
||||
#include "../towire.c"
|
||||
#include "../fromwire.c"
|
||||
#include "../peer_wire.c"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <ccan/str/hex/hex.h>
|
||||
#include <common/amount.h>
|
||||
#include <common/bigsize.h>
|
||||
#include <bitcoin/chainparams.h>
|
||||
#include <common/sphinx.h>
|
||||
#include <wire/gen_peer_wire.h>
|
||||
|
||||
secp256k1_context *secp256k1_ctx;
|
||||
|
||||
@ -31,24 +34,6 @@ bool amount_sat_eq(struct amount_sat a UNNEEDED, struct amount_sat b UNNEEDED)
|
||||
struct amount_sat a UNNEEDED,
|
||||
struct amount_sat b UNNEEDED)
|
||||
{ fprintf(stderr, "amount_sat_sub called!\n"); abort(); }
|
||||
/* Generated stub for bigsize_get */
|
||||
size_t bigsize_get(const u8 *p UNNEEDED, size_t max UNNEEDED, bigsize_t *val UNNEEDED)
|
||||
{ fprintf(stderr, "bigsize_get called!\n"); abort(); }
|
||||
/* Generated stub for bigsize_put */
|
||||
size_t bigsize_put(u8 buf[BIGSIZE_MAX_LEN] UNNEEDED, bigsize_t v UNNEEDED)
|
||||
{ fprintf(stderr, "bigsize_put called!\n"); abort(); }
|
||||
/* Generated stub for fromwire_tlvs */
|
||||
bool fromwire_tlvs(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
|
||||
const struct tlv_record_type types[] UNNEEDED,
|
||||
size_t num_types UNNEEDED,
|
||||
void *record UNNEEDED)
|
||||
{ fprintf(stderr, "fromwire_tlvs called!\n"); abort(); }
|
||||
/* Generated stub for towire_tlvs */
|
||||
void towire_tlvs(u8 **pptr UNNEEDED,
|
||||
const struct tlv_record_type types[] UNNEEDED,
|
||||
size_t num_types UNNEEDED,
|
||||
const void *record UNNEEDED)
|
||||
{ fprintf(stderr, "towire_tlvs called!\n"); abort(); }
|
||||
/* AUTOGENERATED MOCKS END */
|
||||
|
||||
/* memsetting pubkeys doesn't work */
|
||||
@ -236,6 +221,7 @@ struct msg_channel_announcement {
|
||||
struct msg_init {
|
||||
u8 *globalfeatures;
|
||||
u8 *localfeatures;
|
||||
struct tlv_init_tlvs *tlvs;
|
||||
};
|
||||
struct msg_update_add_htlc {
|
||||
struct channel_id channel_id;
|
||||
@ -761,16 +747,19 @@ static void *towire_struct_init(const tal_t *ctx,
|
||||
{
|
||||
return towire_init(ctx,
|
||||
s->globalfeatures,
|
||||
s->localfeatures);
|
||||
s->localfeatures,
|
||||
s->tlvs);
|
||||
}
|
||||
|
||||
static struct msg_init *fromwire_struct_init(const tal_t *ctx, const void *p)
|
||||
{
|
||||
struct msg_init *s = tal(ctx, struct msg_init);
|
||||
s->tlvs = tlv_init_tlvs_new(s);
|
||||
|
||||
if (!fromwire_init(s, p,
|
||||
&s->globalfeatures,
|
||||
&s->localfeatures))
|
||||
&s->localfeatures,
|
||||
s->tlvs))
|
||||
return tal_free(s);
|
||||
|
||||
return s;
|
||||
@ -844,6 +833,9 @@ static bool error_eq(const struct msg_error *a,
|
||||
static bool init_eq(const struct msg_init *a,
|
||||
const struct msg_init *b)
|
||||
{
|
||||
for (size_t i = 0; i < tal_count(a->tlvs->networks->chains); i++)
|
||||
assert(bitcoin_blkid_eq(&a->tlvs->networks->chains[i],
|
||||
&b->tlvs->networks->chains[i]));
|
||||
return eq_var(a, b, globalfeatures)
|
||||
&& eq_var(a, b, localfeatures);
|
||||
}
|
||||
@ -959,6 +951,7 @@ int main(void)
|
||||
void *ctx = tal(NULL, char);
|
||||
size_t i;
|
||||
u8 *msg;
|
||||
const struct chainparams **chains;
|
||||
|
||||
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
|
||||
| SECP256K1_CONTEXT_SIGN);
|
||||
@ -1039,16 +1032,21 @@ int main(void)
|
||||
assert(error_eq(&e, e2));
|
||||
test_corruption(&e, e2, error);
|
||||
|
||||
chains = chainparams_for_networks(ctx);
|
||||
for (i = 0; i < tal_count(chains); i++) {
|
||||
memset(&init, 2, sizeof(init));
|
||||
init.globalfeatures = tal_arr(ctx, u8, 2);
|
||||
memset(init.globalfeatures, 2, 2);
|
||||
init.localfeatures = tal_arr(ctx, u8, 2);
|
||||
memset(init.localfeatures, 2, 2);
|
||||
|
||||
init.tlvs = tlv_init_tlvs_new(ctx);
|
||||
init.tlvs->networks = tal(init.tlvs, struct tlv_init_tlvs_networks);
|
||||
init.tlvs->networks->chains = tal_arr(ctx, struct bitcoin_blkid, 1);
|
||||
init.tlvs->networks->chains[0] = chains[i]->genesis_blockhash;
|
||||
msg = towire_struct_init(ctx, &init);
|
||||
init2 = fromwire_struct_init(ctx, msg);
|
||||
assert(init_eq(&init, init2));
|
||||
test_corruption(&init, init2, init);
|
||||
}
|
||||
|
||||
memset(&uf, 2, sizeof(uf));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user