mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 14:42:40 +01:00
lightningd: use a better channel if available to next hop.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
debc1b90d3
commit
75596b3e0f
7 changed files with 66 additions and 35 deletions
|
@ -601,15 +601,6 @@ struct channel_inflight *channel_inflight_find(struct channel *channel,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct channel *active_channel_by_scid(struct lightningd *ld,
|
||||
const struct short_channel_id *scid)
|
||||
{
|
||||
struct channel *chan = any_channel_by_scid(ld, scid);
|
||||
if (chan && !channel_active(chan))
|
||||
chan = NULL;
|
||||
return chan;
|
||||
}
|
||||
|
||||
struct channel *any_channel_by_scid(struct lightningd *ld,
|
||||
const struct short_channel_id *scid)
|
||||
{
|
||||
|
|
|
@ -394,8 +394,6 @@ struct channel *peer_any_unsaved_channel(struct peer *peer, bool *others);
|
|||
|
||||
struct channel *channel_by_dbid(struct lightningd *ld, const u64 dbid);
|
||||
|
||||
struct channel *active_channel_by_scid(struct lightningd *ld,
|
||||
const struct short_channel_id *scid);
|
||||
struct channel *any_channel_by_scid(struct lightningd *ld,
|
||||
const struct short_channel_id *scid);
|
||||
|
||||
|
|
|
@ -546,7 +546,7 @@ static void subtract_received_htlcs(const struct channel *channel,
|
|||
}
|
||||
}
|
||||
|
||||
static struct amount_msat channel_amount_spendable(const struct channel *channel)
|
||||
struct amount_msat channel_amount_spendable(const struct channel *channel)
|
||||
{
|
||||
struct amount_msat spendable;
|
||||
|
||||
|
@ -1770,14 +1770,18 @@ command_find_channel(struct command *cmd,
|
|||
tok->end - tok->start,
|
||||
buffer + tok->start);
|
||||
} else if (json_to_short_channel_id(buffer, tok, &scid)) {
|
||||
*channel = active_channel_by_scid(ld, &scid);
|
||||
if (*channel)
|
||||
return NULL;
|
||||
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Short channel ID not found: '%.*s'",
|
||||
tok->end - tok->start,
|
||||
buffer + tok->start);
|
||||
*channel = any_channel_by_scid(ld, &scid);
|
||||
if (!*channel)
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Short channel ID not found: '%.*s'",
|
||||
tok->end - tok->start,
|
||||
buffer + tok->start);
|
||||
if (!channel_active(*channel))
|
||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
||||
"Short channel ID not active: '%.*s'",
|
||||
tok->end - tok->start,
|
||||
buffer + tok->start);
|
||||
return NULL;
|
||||
} else {
|
||||
return command_fail_badparam(cmd, "id", buffer, tok,
|
||||
"should be a channel ID or short channel ID");
|
||||
|
|
|
@ -92,6 +92,10 @@ void channel_watch_funding(struct lightningd *ld, struct channel *channel);
|
|||
/* If this channel has a "wrong funding" shutdown, watch that too. */
|
||||
void channel_watch_wrong_funding(struct lightningd *ld, struct channel *channel);
|
||||
|
||||
/* How much can we spend in this channel? */
|
||||
struct amount_msat channel_amount_spendable(const struct channel *channel);
|
||||
|
||||
/* How much can we receive in this channel? */
|
||||
struct amount_msat channel_amount_receivable(const struct channel *channel);
|
||||
|
||||
/* Pull peers, channels and HTLCs from db, and wire them up.
|
||||
|
|
|
@ -621,11 +621,45 @@ static void forward_htlc(struct htlc_in *hin,
|
|||
{
|
||||
const u8 *failmsg;
|
||||
struct lightningd *ld = hin->key.channel->peer->ld;
|
||||
struct channel *next = active_channel_by_scid(ld, scid);
|
||||
struct channel *next;
|
||||
struct htlc_out *hout = NULL;
|
||||
|
||||
/* This is a shortcut for specifying next peer; doesn't mean
|
||||
* the actual channel! */
|
||||
next = any_channel_by_scid(ld, scid);
|
||||
if (next) {
|
||||
struct peer *peer = next->peer;
|
||||
struct channel *channel;
|
||||
struct amount_msat best_spendable = channel_amount_spendable(next);
|
||||
|
||||
/* Seek channel with largest spendable! */
|
||||
list_for_each(&peer->channels, channel, list) {
|
||||
struct amount_msat spendable;
|
||||
if (!channel_can_add_htlc(channel))
|
||||
continue;
|
||||
spendable = channel_amount_spendable(channel);
|
||||
if (!amount_msat_greater(spendable, best_spendable))
|
||||
continue;
|
||||
|
||||
/* Don't override if fees differ... */
|
||||
if (channel->feerate_base != next->feerate_base
|
||||
|| channel->feerate_ppm != next->feerate_ppm)
|
||||
continue;
|
||||
/* Or if this would be below min for channel! */
|
||||
if (amount_msat_less(amt_to_forward,
|
||||
channel->channel_info.their_config.htlc_minimum))
|
||||
continue;
|
||||
|
||||
/* OK, it's better! */
|
||||
log_debug(next->log, "Chose a better channel: %s",
|
||||
type_to_string(tmpctx, struct short_channel_id,
|
||||
channel->scid));
|
||||
next = channel;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unknown peer, or peer not ready. */
|
||||
if (!next || !next->scid) {
|
||||
if (!next || !channel_active(next)) {
|
||||
local_fail_in_htlc(hin, take(towire_unknown_next_peer(NULL)));
|
||||
wallet_forwarded_payment_add(hin->key.channel->peer->ld->wallet,
|
||||
hin, next ? next->scid : NULL, NULL,
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
bool deprecated_apis = false;
|
||||
|
||||
/* AUTOGENERATED MOCKS START */
|
||||
/* Generated stub for active_channel_by_scid */
|
||||
struct channel *active_channel_by_scid(struct lightningd *ld UNNEEDED,
|
||||
const struct short_channel_id *scid UNNEEDED)
|
||||
{ fprintf(stderr, "active_channel_by_scid called!\n"); abort(); }
|
||||
/* Generated stub for any_channel_by_scid */
|
||||
struct channel *any_channel_by_scid(struct lightningd *ld UNNEEDED,
|
||||
const struct short_channel_id *scid UNNEEDED)
|
||||
{ fprintf(stderr, "any_channel_by_scid called!\n"); abort(); }
|
||||
/* Generated stub for bitcoind_getutxout_ */
|
||||
void bitcoind_getutxout_(struct bitcoind *bitcoind UNNEEDED,
|
||||
const struct bitcoin_outpoint *outpoint UNNEEDED,
|
||||
|
|
|
@ -3784,11 +3784,11 @@ def test_multichan(node_factory, executor, bitcoind):
|
|||
scid12 = l1.get_channel_scid(l2)
|
||||
scid23a = l2.get_channel_scid(l3)
|
||||
|
||||
# Now fund *second* channel l2->l3.
|
||||
# Now fund *second* channel l2->l3 (slightly larger)
|
||||
bitcoind.rpc.sendtoaddress(l2.rpc.newaddr()['bech32'], 0.1)
|
||||
bitcoind.generate_block(1)
|
||||
sync_blockheight(bitcoind, [l2])
|
||||
l2.rpc.fundchannel(l3.info['id'], '0.05btc')
|
||||
l2.rpc.fundchannel(l3.info['id'], '0.01001btc')
|
||||
assert(len(only_one(l2.rpc.listpeers(l3.info['id'])['peers'])['channels']) == 2)
|
||||
assert(len(only_one(l3.rpc.listpeers(l2.info['id'])['peers'])['channels']) == 2)
|
||||
|
||||
|
@ -3830,9 +3830,9 @@ def test_multichan(node_factory, executor, bitcoind):
|
|||
chan23a_idx = 1
|
||||
chan23b_idx = 0
|
||||
|
||||
# Check it used the right scid!
|
||||
assert before[chan23a_idx]['to_us_msat'] != after[chan23a_idx]['to_us_msat']
|
||||
assert before[chan23b_idx]['to_us_msat'] == after[chan23b_idx]['to_us_msat']
|
||||
# Check it used the larger channel!
|
||||
assert before[chan23a_idx]['to_us_msat'] == after[chan23a_idx]['to_us_msat']
|
||||
assert before[chan23b_idx]['to_us_msat'] != after[chan23b_idx]['to_us_msat']
|
||||
|
||||
before = only_one(l2.rpc.listpeers(l3.info['id'])['peers'])['channels']
|
||||
route[1]['channel'] = scid23b
|
||||
|
@ -3843,9 +3843,9 @@ def test_multichan(node_factory, executor, bitcoind):
|
|||
wait_for(lambda: [c['htlcs'] for c in only_one(l2.rpc.listpeers(l3.info['id'])['peers'])['channels']] == [[], []])
|
||||
after = only_one(l2.rpc.listpeers(l3.info['id'])['peers'])['channels']
|
||||
|
||||
# Check it used the right scid!
|
||||
assert before[chan23a_idx]['to_us_msat'] == after[chan23a_idx]['to_us_msat']
|
||||
assert before[chan23b_idx]['to_us_msat'] != after[chan23b_idx]['to_us_msat']
|
||||
# Now the first channel is larger!
|
||||
assert before[chan23a_idx]['to_us_msat'] != after[chan23a_idx]['to_us_msat']
|
||||
assert before[chan23b_idx]['to_us_msat'] == after[chan23b_idx]['to_us_msat']
|
||||
|
||||
# Make sure gossip works.
|
||||
bitcoind.generate_block(5)
|
||||
|
@ -3862,5 +3862,5 @@ def test_multichan(node_factory, executor, bitcoind):
|
|||
|
||||
assert chan23a['amount_msat'] == Millisatoshi(1000000000)
|
||||
assert chan23a['short_channel_id'] == scid23a
|
||||
assert chan23b['amount_msat'] == Millisatoshi(5000000000)
|
||||
assert chan23b['amount_msat'] == Millisatoshi(1001000000)
|
||||
assert chan23b['short_channel_id'] == scid23b
|
||||
|
|
Loading…
Add table
Reference in a new issue