lighningd: Add zeroconf primitives

These are used to manage zeroconf related operations, such as managing
options, determining if a peer is trusted to do a zeroconf channel
open, etc.
This commit is contained in:
Christian Decker 2022-04-15 15:57:39 +02:00
parent 49a22a8dd7
commit 54340b4b09
6 changed files with 88 additions and 25 deletions

View File

@ -89,7 +89,8 @@ COMMON_SRC_NOGEN := \
common/version.c \
common/wallet.c \
common/wireaddr.c \
common/wire_error.c
common/wire_error.c \
common/zeroconf.c
COMMON_SRC_GEN := common/status_wiregen.c common/peer_status_wiregen.c

46
common/zeroconf.c Normal file
View File

@ -0,0 +1,46 @@
#include "config.h"
#include <assert.h>
#include <common/zeroconf.h>
#include <wire/wire.h>
struct zeroconf_options *zeroconf_options_new(const tal_t *ctx)
{
struct zeroconf_options *z = tal(ctx, struct zeroconf_options);
z->allow_all = false;
z->allowlist = tal_arr(z, struct node_id, 0);
return z;
}
bool fromwire_zeroconf_options(const u8 **cursor, size_t *max,
struct zeroconf_options *opts)
{
size_t listsize;
opts->allow_all = fromwire_bool(cursor, max);
listsize = fromwire_u16(cursor, max);
opts->allowlist = tal_arr(opts, struct node_id, listsize);
for (size_t i = 0; i < listsize; i++)
fromwire_node_id(cursor, max, &opts->allowlist[i]);
return *cursor != NULL;
}
void towire_zeroconf_options(u8 **pptr, const struct zeroconf_options *opts)
{
towire_bool(pptr, opts->allow_all);
assert(opts->allowlist != NULL);
towire_u16(pptr, tal_count(opts->allowlist));
for (size_t i = 0; i < tal_count(opts->allowlist); i++)
towire_node_id(pptr, &opts->allowlist[i]);
}
bool zeroconf_allow_peer(const struct zeroconf_options *zopts,
const struct node_id *node_id)
{
if (zopts->allow_all)
return true;
for (size_t i=0; i<tal_count(zopts->allowlist); i++)
if (node_id_eq(node_id, &zopts->allowlist[i]))
return true;
return false;
}

34
common/zeroconf.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef LIGHTNING_COMMON_ZEROCONF_H
#define LIGHTNING_COMMON_ZEROCONF_H
#include "config.h"
#include <common/node_id.h>
/* Helper struct to hand options around various daemons. */
struct zeroconf_options {
bool allow_all;
/* List of nodes we allow zeroconf from/to */
struct node_id *allowlist;
};
struct zeroconf_options *zeroconf_options_new(const tal_t *ctx);
bool fromwire_zeroconf_options(const u8 **cursor, size_t *max,
struct zeroconf_options *opts);
void towire_zeroconf_options(u8 **pptr, const struct zeroconf_options *opts);
/**
* Check if a given node should be allowed for zeroconf.
*
* Determines whether we'd be happy to open or accept a zeroconf
* channel with this peers. It is used to selectively apply the
* `option_zeroconf` to the `init` message we'll send to the peer when
* a connection is established. This is sticky, as in it applies to
* all channels we'll open or accept on this connection. Notice that
* this does not differentiate between opening of accepting a channel,
* and that's because the accepter doesn't get a say in the channel
* negotiation.
*/
bool zeroconf_allow_peer(const struct zeroconf_options *zopts,
const struct node_id *node_id);
#endif /* LIGHTNING_COMMON_ZEROCONF_H */

View File

@ -167,10 +167,3 @@ void channel_config(struct lightningd *ld,
/* This is filled in by lightning_openingd, for consistency. */
ours->channel_reserve = AMOUNT_SAT(UINT64_MAX);
}
bool opening_zeroconf_allow(struct lightningd *ld, struct node_id *peer)
{
/* FIXME: Actually read the options from `ld` and return
* `true` if we were configured to do so. */
return true;
}

View File

@ -127,18 +127,4 @@ void channel_config(struct lightningd *ld,
u32 *max_to_self_delay,
struct amount_msat *min_effective_htlc_capacity);
/**
* Are we ok with this peer opening a zeroconf channel?
*
* Determines whether we'd be happy to open or accept a zeroconf
* channel with this peers. It is used to selectively apply the
* `option_zeroconf` to the `init` message we'll send to the peer when
* a connection is established. This is sticky, as in it applies to
* all channels we'll open or accept on this connection. Notice that
* this does not differentiate between opening of accepting a channel,
* and that's because the accepter doesn't get a say in the channel
* negotiation.
*/
bool opening_zeroconf_allow(struct lightningd *ld, struct node_id *peer);
#endif /* LIGHTNING_LIGHTNINGD_OPENING_COMMON_H */

View File

@ -897,14 +897,17 @@ bool peer_start_openingd(struct peer *peer, struct peer_fd *peer_fd)
* reasonable to avoid double-spending of the funding transaction.
*/
uc->minimum_depth = peer->ld->config.anchor_confirms;
#ifdef EXPERIMENTAL_FEATURES /* zeroconf */
if (opening_zeroconf_allow(peer->ld, &peer->id)) {
if (zeroconf_allow_peer(peer->ld->config.zeroconf, &peer->id)) {
uc->minimum_depth = 0;
} else {
/* Unset the bit for ZEROCONF, since we don't want to signal
* support and then reject when they try to use it. */
featurebits_unset(&uc->our_features->bits[INIT_FEATURE], OPT_ZEROCONF);
}
msg = towire_openingd_init(NULL,
chainparams,
peer->ld->our_features,
uc->our_features,
peer->their_features,
&uc->our_config,
max_to_self_delay,