Commit Graph

929 Commits

Author SHA1 Message Date
bitromortac
26d1f427df
routing: trace capacity in probability log 2023-02-24 15:28:55 +01:00
bitromortac
75a9dc9103
routing: limit capacity factor and tune parameters
* The maximal reduction in the probability is limited to 0.5 (previously
  ~0.05), such that we don't get too low apriori probabilities.
  Otherwise, this may lead to a too strong selection of large (and maybe
  expensive) channels. A two-hop path would get total probability
  penalties of:

  - 1000PPM/(0.6*0.6) = 2778 PPM in the unsaturated case
  - 1000PPM/(0.6*(0.6*0.5)) = 5556 PPM in the saturated case, where the
    second hop is saturated

  The difference in PPM of 2778 PPM should be enough to bias towards the
  first path.

* The smearing factor is reduced. Previously we had to keep a higher
  smearing factor in order to make the capacity factor not go to zero
  for high amounts, to still give a fully saturated channel a chance.
  This is not needed anymore due to the capping to 0.5. A lower value of
  the smearing factor lets us more precisely choose a capacity fraction
  and the capacity factor is more neutral when it comes to intermediate
  amounts.

We set a conservative default value for the capacity fraction, which
still has the effect of discarding exhausted channels, giving a
noticeable effect when about 90% of the capacity is being used.
2023-02-24 15:28:55 +01:00
bitromortac
a73581610e
routing+lnrpc: make capacity factor configurable
We make the capacity factor configurable via an lnd.conf routerrpc
apriori parameter. The capacity factor trades off increased success
probability with a reduced set of channel candidates, which may lead to
increased fees. To let users choose whether the factor is active or not,
we add a config setting where a capacity fraction of 1.0 disables the
factor. We limit the capacity fraction to values between 0.75 and 1.0.
Lower values may discard too many channels.
2023-02-24 15:28:55 +01:00
yyforyongyu
6618ab493a
multi: enhance loggings and fix logging format
Also adds TODO for a possible bug.
2023-02-23 21:56:08 +08:00
bitromortac
6aac2762b3
routing: stricter maxHTLC checks
We require channel updates to have the max HTLC message flag set.

Several flows need to pass that check before channel updates are
forwarded to peers:
* after channel funding: `addToRouterGraph`
* after receiving channel updates from a peer:
  `ProcessRemoteAnnouncement`
* after we update channel policies: `PropagateChanPolicyUpdate`
2023-02-21 14:03:51 +01:00
bitromortac
dd5273c88c
multi: rename due to required maxHTLC bit
We rename `ChanUpdateOptionMaxHtlc` to `ChanUpdateRequiredMaxHtlc`
as with the latest changes it is now required.

Similarly, rename `validateOptionalFields` to
`ValidateChannelUpdateFields`, export it to use it in a later commit.
2023-02-21 11:10:39 +01:00
bitromortac
d78e756406
routing: add probability benchmarks
$ go test -bench=PairProbability ./routing
goos: linux
goarch: amd64
pkg: github.com/lightningnetwork/lnd/routing
cpu: AMD Ryzen 5 3600 6-Core Processor
BenchmarkBimodalPairProbability-4   	 2050206	       599.8 ns/op
BenchmarkAprioriPairProbability-4   	 9524289	       126.7 ns/op

* math.Exp:
goos: linux
goarch: amd64
pkg: github.com/lightningnetwork/lnd/routing
cpu: AMD Ryzen 5 3600 6-Core Processor
BenchmarkExp-4   	143843622	         8.700 ns/op

* bimodal benchmark profile:
Showing nodes accounting for 2000ms, 76.05% of 2630ms total
Dropped 156 nodes (cum <= 13.15ms)
Showing top 10 nodes out of 141
      flat  flat%   sum%        cum   cum%
    1110ms 42.21% 42.21%     1110ms 42.21%  math.archExp
     230ms  8.75% 50.95%      230ms  8.75%  runtime.memclrNoHeapPointers
     180ms  6.84% 57.79%      930ms 35.36%  github.com/lightningnetwork/lnd/routing.(*BimodalEstimator).calculateProbability
     110ms  4.18% 61.98%      130ms  4.94%  runtime.scanobject
      90ms  3.42% 65.40%       90ms  3.42%  memeqbody
      60ms  2.28% 67.68%      940ms 35.74%  github.com/lightningnetwork/lnd/routing.(*BimodalEstimator).directProbability
      60ms  2.28% 69.96%      230ms  8.75%  github.com/lightningnetwork/lnd/routing.cannotSend
      60ms  2.28% 72.24%       60ms  2.28%  runtime.madvise
      50ms  1.90% 74.14%      480ms 18.25%  github.com/lightningnetwork/lnd/routing.(*BimodalEstimator).primitive
      50ms  1.90% 76.05%       60ms  2.28%  runtime.mapiternext

* apriori benchmark profile:
Showing nodes accounting for 1570ms, 77.34% of 2030ms total
Dropped 138 nodes (cum <= 10.15ms)
Showing top 10 nodes out of 151
      flat  flat%   sum%        cum   cum%
     340ms 16.75% 16.75%      340ms 16.75%  math.archExp
     290ms 14.29% 31.03%      980ms 48.28%  github.com/lightningnetwork/lnd/routing.(*AprioriEstimator).getNodeProbability
     190ms  9.36% 40.39%      260ms 12.81%  runtime.mapiternext
     190ms  9.36% 49.75%      190ms  9.36%  runtime.memclrNoHeapPointers
     160ms  7.88% 57.64%      340ms 16.75%  github.com/lightningnetwork/lnd/routing.(*AprioriEstimator).calculateProbability
     110ms  5.42% 63.05%      110ms  5.42%  aeshashbody
     110ms  5.42% 68.47%      130ms  6.40%  runtime.scanobject
      80ms  3.94% 72.41%      420ms 20.69%  github.com/lightningnetwork/lnd/routing.capacityFactor
      60ms  2.96% 75.37%       60ms  2.96%  runtime.madvise
      40ms  1.97% 77.34%       40ms  1.97%  runtime.isEmpty (inline)
2023-02-14 13:34:25 +01:00
bitromortac
58d5131e31
lnd+routerrpc: configure server with new estimator
We add new lnd.conf configuration options for both probability
estimators. Note that this is a breaking change for the existing apriori
parameters.
2023-02-14 13:34:25 +01:00
bitromortac
16986ee5c7
lnd+routing+rpc: switch mc to (external) estimator
We use a more general `Estimator` interface for probability estimation
in missioncontrol.

The estimator is created outside of `NewMissionControl`, passed in as a
`MissionControlConfig` field, to facilitate usage of externally supplied
estimators.
2023-02-14 13:34:25 +01:00
bitromortac
686816d784
routing: implement bimodal probability estimator
Implements a new probability estimator based on a probability theory
framework.

The computed probability consists of:
* the direct channel probability, which is estimated based on a
  depleted liquidity distribution model, formulas and broader concept derived
  after Pickhardt et al. https://arxiv.org/abs/2103.08576
* an extension of the probability model to incorporate knowledge decay
  after time for previous successes and failures
* a mixed node probability taking into account successes/failures on other
  channels of the node (similar to the apriori approach)
2023-02-14 13:34:25 +01:00
bitromortac
b8c6227383
routing: add probability estimator interface
We introduce a probability `Estimator` interface which is implemented by
the current apriori probability estimator. A second implementation, the
bimodal probability estimator follows.
2023-02-10 09:58:40 +01:00
bitromortac
b0a998af8d
routing: rename apriori estimator
* we rename the current probability estimator to be the "apriori"
  probability estimator to distinguish from a different implementation
  later
* the AprioriEstimator is exported to later be able to type switch
* getLocalPairProbability -> LocalPairProbabiltiy (later part of an
  exported interface)
* getPairProbability -> getPairProbabiltiy (later part of an exported
  interface)
2023-02-07 16:18:38 +01:00
yyforyongyu
fa2c766866
routing: remove the mutex and use SyncMap instead
This commit removes the lock used to protect the map `topologyClients`
and replace the map with a `SyncMap`.
2023-01-19 07:08:18 +08:00
positiveblue
0a4f062e22
routing: fix race condition in TestUpdatePaymentState
The test cases in `TestUpdatePaymentState` run in parallel. One of the
parameters is a pointer and the value to the struct it points to gets
modified during the test.

The race condition was introduced in 8d49dfb07e
To test the fix run from the main folder `go test  ./routing/. -race`
before this fix and after.
2023-01-17 14:26:37 -08:00
yyforyongyu
59578d9f1a
routing: add more verbose logs 2023-01-17 07:26:57 +08:00
bitromortac
1dd7a37d4d
routing: apply capacity factor
We multiply the apriori probability with a factor to take capacity into
account:

P *= 1 - 1 / [1 + exp(-(amount - cutoff)/smearing)]

The factor is a function value between 1 (small amount) and 0 (high
amount). The zero limit may not be reached exactly depending on the
smearing and cutoff combination. The function is a logistic function
mirrored about the y-axis. The cutoff determines the amount at which a
significant reduction in probability takes place and the smearing
parameter defines how smooth the transition from 1 to 0 is. Both, the
cutoff and smearing parameters are defined in terms of fixed fractions
of the capacity.
2022-12-12 13:22:29 +01:00
bitromortac
454c115b6e
routing+routerrpc: add capacity in rpcs
FetchPairCapacity is used by the following endpoints to introduce the
capacity for probability calculations:

* QueryProbability
* QueryRoutes
2022-12-12 13:22:29 +01:00
bitromortac
66ffc64776
router: return probability from findPath
The returned probability can then be used in QueryRoutes to not having
to reconstruct the probability.
2022-12-12 13:22:29 +01:00
bitromortac
516e3a8cca
routing: use capacity in pathfinding
Extends the pathfinder with a capacity argument for later usage.

In tests, the inserted testCapacity has no effect, but will be used
later to estimate reduced probabilities from it.
2022-12-12 13:22:28 +01:00
bitromortac
2b6308a61f
routing: implement capacity in getEdge
This commit adds the maximal capacity between two nodes to the unified
edge data. We use MaxHTLC as a replacement if the channel capacity is
not available.

In tests we use larger maxHTLC values to be able to convert to a
non-zero sat capacity.
2022-12-12 13:22:28 +01:00
bitromortac
99273cc5e1
lntypes+routing: add generic Min/Max functions 2022-12-12 13:22:28 +01:00
bitromortac
ce6cadec18
routing: refactor unified edges test
The test for unified edges is refactored into a table-driven test. It
accomodates already a unifier per test for later expansion.
2022-12-12 13:22:28 +01:00
bitromortac
76e711ead0
routing: refactor unified policies to edges
This commit refactors the semantics of unified policies to unified
edges. The main changes are the following renamings:

* unifiedPolicies -> nodeEdgeUnifier
* unifiedPolicy -> edgeUnifier
* unifiedPolicyEdge -> unifiedEdge

Comments and shortened variable names are changed to reflect the new
semantics.
2022-12-12 13:22:26 +01:00
bitromortac
7d29ab905c
routing: return *unifiedPolicyEdge in getPolicy
We encapsulate the capacity inside a unifiedPolicyEdge for later usage.
The meaning of "policy" has changed now, which will be refactored in the
next commmit.
2022-12-12 13:19:29 +01:00
yyforyongyu
8dceb739ff
routing: refactor WaitForDependants to allow detailed logging 2022-12-08 17:57:01 +08:00
yyforyongyu
29c2458831
routing: add method handleNetworkUpdate to process the network update
This commit refactors the `networkHandler` to use the new method
`handleNetworkUpdate`. Because the `select` is called inside a for loop,
which is equivalent of firing goroutine inside range loop, it's possible
that a variable used inside a previous goroutine is referencing the
current one. This is now fixed by making the goroutine taking the params
used for network update.
2022-12-08 17:57:01 +08:00
yyforyongyu
26d1a41926
discovery+routing: add more logs to reveal channel update flow 2022-12-08 17:57:01 +08:00
yyforyongyu
8d49dfb07e
routing: stop tracking totalAmount in paymentLifecycle
This commit removes the field `totalAmount` from `paymentLifecycle` and
only reads it from the channeldb payment.
2022-12-07 18:38:01 +08:00
yyforyongyu
e3bc4f4cc9
htlcswitch+routing: rename GetPaymentResult to GetAttemptResult
This commit renames the method `GetPaymentResult` to be
`GetAttemptResult` to avoid potential confusion and to address the
one-to-many relationship between a payment and its attempts.
2022-12-07 18:38:01 +08:00
yyforyongyu
d1611c999a
routing: rename Fail to FailPayment
This commit renames the method `Fail` to be `FailPayment` to explicitly
address its purpose.
2022-12-07 18:38:01 +08:00
yyforyongyu
2fd4c1e318
channeldb+routing: fix format 2022-12-07 18:38:01 +08:00
Joost Jager
4c8ea29336
lnwire: allow longer failure messages
This fixes an incompatibility where lnd enforces a strict 256 byte
failure message, where as the spec sets this only as the recommended
length.
2022-12-02 14:27:59 +01:00
andreihod
3ed0e8ee96
lint: remove unnecessary leading newline 2022-11-11 04:23:55 -03:00
andreihod
befa1b7cf0
routing: Fix possible infinite loop on first hop misleading hint
Add ignore condition to additional edges that connect to self. These
edges are already known and avoiding these hints protect the payment
from malformed channel ids which could lead to infinite loop.

Fixes lightningnetwork#6169.

Co-authored-by: lsunsi <lsunsi@pm.me>
2022-11-11 04:23:55 -03:00
habibitcoin
0b1e881d18
scripted-diff: replace ⛰ emoji with $ [skip ci]
-BEGIN VERIFY SCRIPT-
sed -i 's/⛰/$/g' $(git grep -l '⛰')
-END VERIFY SCRIPT-
2022-10-28 12:06:49 -04:00
eugene
64b608bce0
routing: check pubkey when applying channel update 2022-10-27 03:09:02 +08:00
Eng Zer Jun
ff3f477ebf
routing: replace defer cleanup with t.Cleanup
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2022-10-13 17:47:04 +08:00
Jesse de Wit
0266ab77ab
routing+routerrpc: test stream cancellation
Test stream cancellation of the TrackPayments rpc call. In order to achieve
this, ControlTowerSubscriber is converted to an interface, to avoid trying to
close a null channel when closing the subscription. By returning a mock
implementation of the ControlTowerSubscriber in the test that problem is
avoided.
2022-09-10 21:53:01 +02:00
Jesse de Wit
e65f020348
routing: add SubscribeAllPayments to control tower
Add a method 'SubscribeAllPayments' to the control tower, in order to be able to
subscribe to any payment, rather than subscribing to a specific payment hash.
2022-09-08 10:48:34 +02:00
Eng Zer Jun
b5a626be78
routing: use T.TempDir to create temporary test directory
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2022-08-24 09:03:05 +08:00
yyforyongyu
39ac4ca92c
routing: fix unit test for SendToRoute
This commit removes the old multi shards test for `SendToRoute` as the
method doesn't support sending MPP. The original test passed due to a
flawed mocking method, where the mockers bypassed the public interfaces
to maintain their internal state, which caused a non-exsiting situation
that a temp error wouldn't fail the payment. A new unit test is added to
demonstrate the actual case.
2022-07-15 19:03:12 +08:00
yyforyongyu
d9915723dd
routing: add unit test for SendToRouteSkipTempErr 2022-07-15 19:03:12 +08:00
yyforyongyu
e99c63c804
routing: add SendToRouteSkipTempErr to skip temp error failure
This commit adds a new method `SendToRouteSkipTempErr` that skips
failing the payment unless a terminal error occurred. This is
accomplished by demoting the original `SendToRoute` to a private method
and creating two new methods on top of it to minimize code change.
2022-07-15 19:03:12 +08:00
Carsten Otto
c6fffeb1c2
router: fix typos 2022-07-15 19:03:12 +08:00
eugene
1aa9626606
server+funding: allow scid-alias, zero-conf chantypes, scid-alias
feature-bit channels

This allows opening zero-conf chan-type, scid-alias chan-type, and
scid-alias feature-bit channels. scid-alias chan-type channels are
required to be private. Two paths are available for opening a zero-conf
channel:

* explicit chan-type negotiation
* LDK carve-out where chan-types are not used, LND is on the
  receiving end, and a ChannelAcceptor is used to enable zero-conf

When a zero-conf channel is negotiated, the funding manager:
* sends a FundingLocked with an alias
* waits for a FundingLocked from the remote peer
* calls addToRouterGraph to persist the channel using our alias in
  the graph. The peer's alias is used to send them a ChannelUpdate.
* wait for six confirmations. If public, the alias edge in the
  graph is deleted and replaced (not atomically) with the confirmed
  edge. Our policy is also read-and-replaced, but the counterparty's
  policy won't exist until they send it to us.

When a scid-alias-feature channel is negotiated, the funding manager:
* sends a FundingLocked with an alias:
* calls addToRouterGraph, sends ChannelUpdate with the confirmed SCID
  since it exists.
* when six confirmations occurs, the edge is deleted and re-inserted
  since the peer may have sent us an alias ChannelUpdate that we are
  storing in the graph.

Since it is possible for a user to toggle the scid-alias-feature-bit
to on while channels exist in the funding manager, care has been taken
to ensure that an alias is ALWAYS sent in the funding_locked message
if this happens.
2022-07-07 17:10:28 -04:00
eugene
59fea192b7
server+routing: pass isAlias to router
This allows the router to determine what is and isn't an alias from
lnd's definition of an alias. Any ChannelAnnouncement that has an
alias ShortChannelID field is not verified on-chain. To prevent a
DoS vector from existing, the gossiper ensures that only the local
lnd node can send its ChannelAnnouncements to the router with an
alias ShortChannelID.
2022-07-07 17:10:28 -04:00
Oliver Gugger
37578a6b6d
routing: fix formatting
This commit fixes a formatting issue in the router. The commit is in
this PR to demonstrate how the .editorconfig settings also affect the
way GitHub displays the code diff.
2022-07-06 13:33:02 +02:00
Tommy Volk
2dd11ed249 channeldb+routing: htlcs are pruned on settle 2022-07-03 21:04:34 +00:00
Tommy Volk
8291e8a170 multi: add keep-failed-payment-attempts flag 2022-07-03 21:04:27 +00:00
Tommy Volk
9a10c80bcb multi: move many t.Fatalf calls to require.NoError 2022-06-17 04:26:55 +00:00