mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-23 06:55:13 +01:00
lightningd: generalize peer_any_channel to filter on entire channel, not just state.
We're going to use this to ask if there are any channels which make it important to reconnect to the peer. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
4ee59e7a49
commit
64af5db45c
9 changed files with 75 additions and 28 deletions
|
@ -653,28 +653,56 @@ const char *channel_state_str(enum channel_state state)
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
struct channel *peer_any_channel(struct peer *peer,
|
#define peer_any_channel(peer, filter, arg, others) \
|
||||||
bool (*channel_state_filter)(enum channel_state),
|
peer_any_channel_((peer), \
|
||||||
bool *others)
|
typesafe_cb_preargs(bool, void *, \
|
||||||
|
(filter), (arg), \
|
||||||
|
const struct channel *), \
|
||||||
|
(arg), \
|
||||||
|
others)
|
||||||
|
|
||||||
|
struct channel *peer_any_channel_(struct peer *peer,
|
||||||
|
bool (*filter)(const struct channel *,
|
||||||
|
void *arg),
|
||||||
|
void *arg,
|
||||||
|
bool *others)
|
||||||
{
|
{
|
||||||
struct channel *channel, *ret = NULL;
|
struct channel *channel, *ret = NULL;
|
||||||
|
|
||||||
list_for_each(&peer->channels, channel, list) {
|
list_for_each(&peer->channels, channel, list) {
|
||||||
if (channel_state_filter && !channel_state_filter(channel->state))
|
if (filter && !filter(channel, arg))
|
||||||
continue;
|
continue;
|
||||||
/* Already found one? */
|
/* Already found one? */
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (others)
|
*others = true;
|
||||||
*others = true;
|
|
||||||
} else {
|
} else {
|
||||||
if (others)
|
if (others)
|
||||||
*others = false;
|
*others = false;
|
||||||
ret = channel;
|
ret = channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Don't keep searching if others is NULL (they don't care). */
|
||||||
|
if (!others)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool filter_by_state(const struct channel *c,
|
||||||
|
bool (*channel_state_filter)(enum channel_state))
|
||||||
|
{
|
||||||
|
return channel_state_filter(c->state);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct channel *peer_any_channel_bystate(struct peer *peer,
|
||||||
|
bool (*channel_state_filter)(enum channel_state),
|
||||||
|
bool *others)
|
||||||
|
{
|
||||||
|
return peer_any_channel(peer,
|
||||||
|
filter_by_state, channel_state_filter,
|
||||||
|
others);
|
||||||
|
}
|
||||||
|
|
||||||
struct channel_inflight *channel_inflight_find(struct channel *channel,
|
struct channel_inflight *channel_inflight_find(struct channel *channel,
|
||||||
const struct bitcoin_txid *txid)
|
const struct bitcoin_txid *txid)
|
||||||
{
|
{
|
||||||
|
|
|
@ -771,9 +771,24 @@ const char *channel_change_state_reason_str(enum state_change reason);
|
||||||
|
|
||||||
/* Find a channel which is passes filter, if any: sets *others if there
|
/* Find a channel which is passes filter, if any: sets *others if there
|
||||||
* is more than one. */
|
* is more than one. */
|
||||||
struct channel *peer_any_channel(struct peer *peer,
|
#define peer_any_channel(peer, filter, arg, others) \
|
||||||
bool (*channel_state_filter)(enum channel_state),
|
peer_any_channel_((peer), \
|
||||||
bool *others);
|
typesafe_cb_preargs(bool, void *, \
|
||||||
|
(filter), (arg), \
|
||||||
|
const struct channel *), \
|
||||||
|
(arg), \
|
||||||
|
others)
|
||||||
|
|
||||||
|
struct channel *peer_any_channel_(struct peer *peer,
|
||||||
|
bool (*filter)(const struct channel *,
|
||||||
|
void *arg),
|
||||||
|
void *arg,
|
||||||
|
bool *others);
|
||||||
|
|
||||||
|
/* More common version for filtering by state */
|
||||||
|
struct channel *peer_any_channel_bystate(struct peer *peer,
|
||||||
|
bool (*channel_state_filter)(enum channel_state),
|
||||||
|
bool *others);
|
||||||
|
|
||||||
struct channel *channel_by_dbid(struct lightningd *ld, const u64 dbid);
|
struct channel *channel_by_dbid(struct lightningd *ld, const u64 dbid);
|
||||||
|
|
||||||
|
|
|
@ -2576,7 +2576,8 @@ static struct command_result *json_dev_feerate(struct command *cmd,
|
||||||
if (!peer)
|
if (!peer)
|
||||||
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
||||||
|
|
||||||
channel = peer_any_channel(peer, channel_state_can_add_htlc, &more_than_one);
|
channel = peer_any_channel_bystate(peer, channel_state_can_add_htlc,
|
||||||
|
&more_than_one);
|
||||||
if (!channel || !channel->owner)
|
if (!channel || !channel->owner)
|
||||||
return command_fail(cmd, LIGHTNINGD, "Peer bad state");
|
return command_fail(cmd, LIGHTNINGD, "Peer bad state");
|
||||||
/* This is a dev command: fix the api if you need this! */
|
/* This is a dev command: fix the api if you need this! */
|
||||||
|
@ -2628,7 +2629,7 @@ static struct command_result *json_dev_peer_shachain(struct command *cmd,
|
||||||
if (!peer)
|
if (!peer)
|
||||||
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
||||||
|
|
||||||
channel = peer_any_channel(peer, channel_state_can_add_htlc, &more_than_one);
|
channel = peer_any_channel_bystate(peer, channel_state_can_add_htlc, &more_than_one);
|
||||||
if (!channel || !channel->owner)
|
if (!channel || !channel->owner)
|
||||||
return command_fail(cmd, LIGHTNINGD, "Peer bad state");
|
return command_fail(cmd, LIGHTNINGD, "Peer bad state");
|
||||||
/* This is a dev command: fix the api if you need this! */
|
/* This is a dev command: fix the api if you need this! */
|
||||||
|
@ -2683,7 +2684,8 @@ static struct command_result *json_dev_quiesce(struct command *cmd,
|
||||||
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
||||||
|
|
||||||
/* FIXME: If this becomes a real API, check for OPT_QUIESCE! */
|
/* FIXME: If this becomes a real API, check for OPT_QUIESCE! */
|
||||||
channel = peer_any_channel(peer, channel_state_wants_peercomms, &more_than_one);
|
channel = peer_any_channel_bystate(peer, channel_state_wants_peercomms,
|
||||||
|
&more_than_one);
|
||||||
if (!channel || !channel->owner)
|
if (!channel || !channel->owner)
|
||||||
return command_fail(cmd, LIGHTNINGD, "Peer bad state");
|
return command_fail(cmd, LIGHTNINGD, "Peer bad state");
|
||||||
/* This is a dev command: fix the api if you need this! */
|
/* This is a dev command: fix the api if you need this! */
|
||||||
|
|
|
@ -608,7 +608,7 @@ static struct command_result *param_channel_or_peer(struct command *cmd,
|
||||||
(*sc)->uc = NULL;
|
(*sc)->uc = NULL;
|
||||||
|
|
||||||
if (peer) {
|
if (peer) {
|
||||||
(*sc)->channel = peer_any_channel(peer, channel_state_can_close, &more_than_one);
|
(*sc)->channel = peer_any_channel_bystate(peer, channel_state_can_close, &more_than_one);
|
||||||
if ((*sc)->channel) {
|
if ((*sc)->channel) {
|
||||||
if (more_than_one)
|
if (more_than_one)
|
||||||
goto more_than_one;
|
goto more_than_one;
|
||||||
|
@ -632,7 +632,7 @@ static struct command_result *param_channel_or_peer(struct command *cmd,
|
||||||
if ((*sc)->uc)
|
if ((*sc)->uc)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
(*sc)->unsaved_channel = peer_any_channel(peer, channel_state_uncommitted, &more_than_one);
|
(*sc)->unsaved_channel = peer_any_channel_bystate(peer, channel_state_uncommitted, &more_than_one);
|
||||||
if ((*sc)->unsaved_channel) {
|
if ((*sc)->unsaved_channel) {
|
||||||
if (more_than_one)
|
if (more_than_one)
|
||||||
goto more_than_one;
|
goto more_than_one;
|
||||||
|
|
|
@ -291,7 +291,7 @@ static void do_connect(struct delayed_reconnect *d)
|
||||||
|
|
||||||
/* We consider this transient unless we have a channel */
|
/* We consider this transient unless we have a channel */
|
||||||
peer = peer_by_id(d->ld, &d->id);
|
peer = peer_by_id(d->ld, &d->id);
|
||||||
transient = !peer || !peer_any_channel(peer, channel_state_wants_peercomms, NULL);
|
transient = !peer || !peer_any_channel_bystate(peer, channel_state_wants_peercomms, NULL);
|
||||||
|
|
||||||
connectmsg = towire_connectd_connect_to_peer(NULL,
|
connectmsg = towire_connectd_connect_to_peer(NULL,
|
||||||
&d->id,
|
&d->id,
|
||||||
|
@ -427,7 +427,7 @@ static void connect_failed(struct lightningd *ld,
|
||||||
|
|
||||||
/* If we have an active channel, then reconnect. */
|
/* If we have an active channel, then reconnect. */
|
||||||
peer = peer_by_id(ld, id);
|
peer = peer_by_id(ld, id);
|
||||||
if (peer && peer_any_channel(peer, channel_state_wants_peercomms, NULL)) {
|
if (peer && peer_any_channel_bystate(peer, channel_state_wants_peercomms, NULL)) {
|
||||||
try_reconnect(peer, peer, addrhint);
|
try_reconnect(peer, peer, addrhint);
|
||||||
} else
|
} else
|
||||||
log_peer_debug(ld->log, id, "Not reconnecting: %s",
|
log_peer_debug(ld->log, id, "Not reconnecting: %s",
|
||||||
|
|
|
@ -1387,7 +1387,7 @@ wallet_commit_channel(struct lightningd *ld,
|
||||||
bool anysegwit = !chainparams->is_elements && feature_negotiated(channel->peer->ld->our_features,
|
bool anysegwit = !chainparams->is_elements && feature_negotiated(channel->peer->ld->our_features,
|
||||||
channel->peer->their_features,
|
channel->peer->their_features,
|
||||||
OPT_SHUTDOWN_ANYSEGWIT);
|
OPT_SHUTDOWN_ANYSEGWIT);
|
||||||
bool any_active = peer_any_channel(channel->peer, channel_state_wants_peercomms, NULL);
|
bool any_active = peer_any_channel_bystate(channel->peer, channel_state_wants_peercomms, NULL);
|
||||||
|
|
||||||
if (!amount_sat_to_msat(&our_msat, our_funding)) {
|
if (!amount_sat_to_msat(&our_msat, our_funding)) {
|
||||||
log_broken(channel->log, "Unable to convert funds");
|
log_broken(channel->log, "Unable to convert funds");
|
||||||
|
|
|
@ -108,7 +108,7 @@ wallet_commit_channel(struct lightningd *ld,
|
||||||
u64 static_remotekey_start;
|
u64 static_remotekey_start;
|
||||||
u32 lease_start_blockheight = 0; /* No leases on v1 */
|
u32 lease_start_blockheight = 0; /* No leases on v1 */
|
||||||
struct timeabs timestamp;
|
struct timeabs timestamp;
|
||||||
bool any_active = peer_any_channel(uc->peer, channel_state_wants_peercomms, NULL);
|
bool any_active = peer_any_channel_bystate(uc->peer, channel_state_wants_peercomms, NULL);
|
||||||
struct channel_stats zero_channel_stats;
|
struct channel_stats zero_channel_stats;
|
||||||
enum addrtype addrtype;
|
enum addrtype addrtype;
|
||||||
|
|
||||||
|
|
|
@ -1546,9 +1546,9 @@ static const struct wireaddr *best_remote_addr(const tal_t *ctx,
|
||||||
continue;
|
continue;
|
||||||
if (peer->remote_addr->type != atype)
|
if (peer->remote_addr->type != atype)
|
||||||
continue;
|
continue;
|
||||||
daddr.preferred = peer_any_channel(peer,
|
daddr.preferred = peer_any_channel_bystate(peer,
|
||||||
channel_state_relationship,
|
channel_state_relationship,
|
||||||
NULL);
|
NULL);
|
||||||
daddr.addr = *peer->remote_addr;
|
daddr.addr = *peer->remote_addr;
|
||||||
daddr.addr.port = ld->config.ip_discovery_port;
|
daddr.addr.port = ld->config.ip_discovery_port;
|
||||||
log_debug(ld->log, "best_remote_addr: peer %s gave addr %s (%s)",
|
log_debug(ld->log, "best_remote_addr: peer %s gave addr %s (%s)",
|
||||||
|
@ -2647,7 +2647,8 @@ static struct command_result *json_disconnect(struct command *cmd,
|
||||||
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
return command_fail(cmd, LIGHTNINGD, "Peer not connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = peer_any_channel(peer, channel_state_wants_peercomms, NULL);
|
channel = peer_any_channel_bystate(peer, channel_state_wants_peercomms,
|
||||||
|
NULL);
|
||||||
if (channel && !*force) {
|
if (channel && !*force) {
|
||||||
return command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"Peer has (at least one) channel in state %s",
|
"Peer has (at least one) channel in state %s",
|
||||||
|
@ -3195,7 +3196,8 @@ static struct command_result *param_dev_channel(struct command *cmd,
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
*channel = peer_any_channel(peer, channel_state_wants_peercomms, &more_than_one);
|
*channel = peer_any_channel_bystate(peer, channel_state_wants_peercomms,
|
||||||
|
&more_than_one);
|
||||||
if (!*channel)
|
if (!*channel)
|
||||||
return command_fail_badparam(cmd, name, buffer, tok,
|
return command_fail_badparam(cmd, name, buffer, tok,
|
||||||
"No channel with that peer");
|
"No channel with that peer");
|
||||||
|
|
|
@ -875,11 +875,11 @@ struct command_result *param_u64(struct command *cmd UNNEEDED, const char *name
|
||||||
const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||||
uint64_t **num UNNEEDED)
|
uint64_t **num UNNEEDED)
|
||||||
{ fprintf(stderr, "param_u64 called!\n"); abort(); }
|
{ fprintf(stderr, "param_u64 called!\n"); abort(); }
|
||||||
/* Generated stub for peer_any_channel */
|
/* Generated stub for peer_any_channel_bystate */
|
||||||
struct channel *peer_any_channel(struct peer *peer UNNEEDED,
|
struct channel *peer_any_channel_bystate(struct peer *peer UNNEEDED,
|
||||||
bool (*channel_state_filter)(enum channel_state) UNNEEDED,
|
bool (*channel_state_filter)(enum channel_state) UNNEEDED,
|
||||||
bool *others UNNEEDED)
|
bool *others UNNEEDED)
|
||||||
{ fprintf(stderr, "peer_any_channel called!\n"); abort(); }
|
{ fprintf(stderr, "peer_any_channel_bystate called!\n"); abort(); }
|
||||||
/* Generated stub for peer_restart_dualopend */
|
/* Generated stub for peer_restart_dualopend */
|
||||||
bool peer_restart_dualopend(struct peer *peer UNNEEDED,
|
bool peer_restart_dualopend(struct peer *peer UNNEEDED,
|
||||||
struct peer_fd *peer_fd UNNEEDED,
|
struct peer_fd *peer_fd UNNEEDED,
|
||||||
|
|
Loading…
Add table
Reference in a new issue