Description
Background
I would like to propose adding more structured error codes to the BuildRoute rpc, similar to what is available in SendToRouteV2. When building rebalancing software, you are often building routes, probing, and then deciding what route to actually send to. SendToRouteV2 provides nice error messaging, which allows me to be able to determine if there is no liquidity in a route, or if the probe has succeded.
No Liquidity: TEMPORARY_CHANNEL_FAILURE
Probe Succeeded: INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS
Example SendToRouteV2 probing command.
Yields INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS
error.
fee rate ppm: 2.7999921600219517
status: FAILED
route {
total_time_lock: 679
total_fees: 7
total_amt: 2500007
hops {
chan_id: 192414534926336
chan_capacity: 5000000
amt_to_forward: 2500003
fee: 3
expiry: 639
amt_to_forward_msat: 2500003500
fee_msat: 3500
pub_key: "03c26cc9150b125ceed9f293354bab8a78ede73aeebc05fb8e5883b8cec52a2ec1"
tlv_payload: true
}
hops {
chan_id: 212205744226304
chan_capacity: 5000000
amt_to_forward: 2500000
fee: 3
expiry: 599
amt_to_forward_msat: 2500000000
fee_msat: 3500
pub_key: "02d09397bde034627b4aaf68a62d785145aebd03ce54b5b55a6e8270326fa887f9"
tlv_payload: true
}
hops {
chan_id: 216603790802944
chan_capacity: 5000000
amt_to_forward: 2500000
expiry: 599
amt_to_forward_msat: 2500000000
pub_key: "026ad2fe25313253de57f5242f8750bef8732799f987a45e7c9675a0397aac0be3"
tlv_payload: true
custom_records {
key: 34349334
value: "rebalance txn"
}
custom_records {
key: 5482373484
value: "&\372c Ld`Z3\213|N\252\231\241\336\250`W=\261\217*\325\004\332\253\220fQzi"
}
}
total_fees_msat: 7000
total_amt_msat: 2500007000
}
attempt_time_ns: 1661541105813051012
resolve_time_ns: 1661541106136519084
failure {
code: INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS
failure_source_index: 3
height: 199
}
attempt_id: 1
Example BuildRoute rpc with lack of structured errors
>>> ln.lnd.build_route(amt_msat=1, oid=0, hop_pubkeys=list_pks)
<_InactiveRpcError of RPC that terminated with:
status = StatusCode.UNKNOWN
details = "no matching outgoing channel available for node 2 (02d09397bde034627b4aaf68a62d785145aebd03ce54b5b55a6e8270326fa887f9)"
debug_error_string = "{"created":"@1661541716.345689597","description":"Error received from peer ipv4:127.0.0.1:10001","file":"src/core/lib/surface/call.cc","file_line":966,"grpc_message":"no matching outgoing channel available for node 2 (02d09397bde034627b4aaf68a62d785145aebd03ce54b5b55a6e8270326fa887f9)","grpc_status":2}"
>
Piece of code which generates this error code:
https://github.com/lightningnetwork/lnd/blob/master/routing/router.go#L2691
Potential Different Error Types:
I've listed the errors in order of things to check first to things to check last:
ROUTE_DOESNT_EXIST
- the route "physically doesnt exist"
ROUTE_CHAN_DISABLED
- the route "exists", but one of the hops is disabled
VIOLATED_CHANNEL_SIZE_CONSTRAINT
- you cant send larger than your channel size
VIOLATED_MIN_HTLC_CONSTRAINT
- for example, sending 1 msat when default MIN_HTLC
is 1000msat
VIOLATED_MAX_HTLC_CONSTRAINT
- people might actually set this to communicate liquidity
Conclusion
PATH 1:
Having these error codes will allow for building better programs for rebalancing liquidity. Currently when the status = StatusCode.UNKNOWN
error is thrown, I am rather clueless until I do some digging why the route really failed to build.
PATH 2:
I also think it could be valid for BuildRoute
to be far more lax about these above constaints. What is the harm of BuildRoute
building an impossible route (disabled channel, sending too much, etc), as long as the hops exist on the graph. Once you send to it, it would error out anyways...
This actually could make a lot of sense, since many of the failure cases I outline above, are standard spec errors anyways.
In this case, the structured error codes for BuildRoute
could be simply ROUTE_DOESNT_EXIST
.
Your environment
- version of
lnd
LND 0.15.0-beta