-
Notifications
You must be signed in to change notification settings - Fork 906
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
getroutes
: allocating more than spendable_msat
#7563
Comments
OK, this is hard to reproduce, since I can't get getroutes() to even try to jam that much down a channel (so close to capacity). Got a setup I can copy? |
def test_mpp_pay2(node_factory, bitcoind):
import logging
logger = logging.getLogger(__name__)
l1, l2, l3 = node_factory.get_nodes(
3,
opts=[
{},
{},
{},
],
)
l1.fundwallet(10_000_000)
l2.fundwallet(10_000_000)
l1.rpc.fundchannel(
l2.info["id"] + "@localhost:" + str(l2.port), 100_000, mindepth=1
)
l2.rpc.fundchannel(
l3.info["id"] + "@localhost:" + str(l3.port), 100_000, mindepth=1
)
bitcoind.generate_block(1)
sync_blockheight(bitcoind, [l1, l2])
l1.rpc.fundchannel(
l2.info["id"] + "@localhost:" + str(l2.port), 100_000, mindepth=1
)
l2.rpc.fundchannel(
l3.info["id"] + "@localhost:" + str(l3.port), 100_000, mindepth=1
)
bitcoind.generate_block(1)
sync_blockheight(bitcoind, [l1, l2])
l1.rpc.fundchannel(
l2.info["id"] + "@localhost:" + str(l2.port), 200_000, mindepth=1
)
l2.rpc.fundchannel(
l3.info["id"] + "@localhost:" + str(l3.port), 200_000, mindepth=1
)
bitcoind.generate_block(1)
sync_blockheight(bitcoind, [l1, l2])
l1.rpc.fundchannel(
l2.info["id"] + "@localhost:" + str(l2.port), 300_000, mindepth=1
)
l2.rpc.fundchannel(
l3.info["id"] + "@localhost:" + str(l3.port), 300_000, mindepth=1
)
bitcoind.generate_block(1)
sync_blockheight(bitcoind, [l1, l2])
l1.rpc.fundchannel(
l2.info["id"] + "@localhost:" + str(l2.port), 400_000, mindepth=1
)
l2.rpc.fundchannel(
l3.info["id"] + "@localhost:" + str(l3.port), 400_000, mindepth=1
)
bitcoind.generate_block(6)
sync_blockheight(bitcoind, [l1, l2, l3])
wait_for(lambda: len(l1.rpc.listchannels()["channels"]) == 20)
routes = l1.rpc.call(
"getroutes",
{
"source": l1.info["id"],
"destination": l3.info["id"],
"amount_msat": 800_000_000,
"layers": ["auto.localchans", "auto.sourcefree"],
"maxfee_msat": 50_000_000,
"finalcltv": 10,
},
)
channels = l1.rpc.call("listpeerchannels")
logger.info(routes)
logger.info(channels) Atleast one channel gets overallocated in this setup for me. |
Thanks, IOU a beer. I'll take a look... |
Seems to work for me:
|
Sorry, i wasn't precise enough: I meant that if you add up all the amounts+fee that def test_mpp_pay2(node_factory, bitcoind):
l1, l2, l3 = node_factory.get_nodes(3)
l1.fundwallet(10_000_000)
l2.fundwallet(10_000_000)
l1.rpc.connect(l2.info["id"], "localhost", port=l2.port)
l2.rpc.connect(l3.info["id"], "localhost", port=l3.port)
capacities = (100_000, 100_000, 200_000, 300_000, 400_000)
for capacity in capacities:
l1.rpc.fundchannel(l2.info["id"], capacity, mindepth=1)
l2.rpc.fundchannel(l3.info["id"], capacity, mindepth=1)
bitcoind.generate_block(1, wait_for_mempool=2)
sync_blockheight(bitcoind, [l1, l2])
bitcoind.generate_block(5)
wait_for(lambda: len(l1.rpc.listchannels()["channels"]) == 2 * 2 * len(capacities))
routes = l1.rpc.getroutes(
source=l1.info["id"],
destination=l3.info["id"],
amount_msat=800_000_000,
layers=["auto.localchans", "auto.sourcefree"],
maxfee_msat=50_000_000,
finalcltv=10,
)
# Don't exceed spendable_msat
maxes = {}
for chan in l1.rpc.listpeerchannels()["channels"]:
maxes["{}/{}".format(chan["short_channel_id"], chan["direction"])] = chan[
"spendable_msat"
]
path_maxes = {}
for r in routes["routes"]:
key = "{}/{}".format(
r["path"][0]["short_channel_id"], r["path"][0]["direction"]
)
path_maxes[key] = path_maxes.get(key, 0) + r["path"][0]["amount_msat"]
for scidd in maxes.keys():
if scidd in path_maxes:
assert maxes[scidd] >= path_maxes[scidd] This returns |
This is my fault! There is a sat precision in the MCF capacities to avoid large numbers. In the future I would like to set the smallest unit according to the payment amount... UPD: fixed in renepay 5a68289, but it is not the same thing in askrene. |
Of course, we still will, since spendable is for a single HTLC, but this also shows why we should treat *minimum* as the incorrect answer if they cross, too. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Fixes: ElementsProject#7563
Of course, we still will, since spendable is for a single HTLC, but this also shows why we should treat *minimum* as the incorrect answer if they cross, too. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Fixes: ElementsProject#7563
Of course, we still will, since spendable is for a single HTLC, but this also shows why we should treat *minimum* as the incorrect answer if they cross, too. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Fixes: ElementsProject#7563
Of course, we still will, since spendable is for a single HTLC, but this also shows why we should treat *minimum* as the incorrect answer if they cross, too. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Fixes: ElementsProject#7563
Of course, we still will, since spendable is for a single HTLC, but this also shows why we should treat *minimum* as the incorrect answer if they cross, too. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Fixes: ElementsProject#7563
Of course, we still will, since spendable is for a single HTLC, but this also shows why we should treat *minimum* as the incorrect answer if they cross, too. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Fixes: ElementsProject#7563
On regtest with a few nodes and channels i call
getroutes
with a large amount and it will return paths that immediately failsendpay
withCapacity exceeded
. I added up the amounts+fees of the first, local channel and compared them with thespendable_msat
value.Some channels are over-allocated by
getroutes
:spendable_msat
: 384718000amount_msat
allocated by getroutes without fee: 384718000I expect
getroutes
to not go overspendable_msat
or even be below that since iirc this value does not account for some things and the real value is even lower?Could be related to #7550
The text was updated successfully, but these errors were encountered: