lnd/routing
Olaoluwa Osuntokun 08dc442b68 routing: run a payment batch on a virtual-time scheduler
In this commit, we turn the attempt loop into a state machine and put a
deterministic event loop in front of it, so that the sender can have
several of its own payments in the air at once.

The loop is NOT goroutines, and the reasons are concrete. SimGraph has no
locking on balances or on the holds map. The traffic rng is a single
stream whose draw order IS the exogenous process. The attribution
degrader consumes a fixed number of draws per attempt precisely so that
two routers face the same sequence. Real parallelism would destroy all
three, and with them the reproducibility every sealed tier depends on.

So each live payment carries a next-event timestamp, and the scheduler
picks the earliest, breaking ties by scenario index, advances the clock
to it, runs the background traffic owed for the interval, and executes
exactly one step: one RequestRoute, or one dispatch and one
ReportAttempt. A payment splits between those two because the window
between choosing a route and hearing what happened to it is the only
window two of the sender's payments can share.

One payment is a batch of one on the same loop, so the sequential
behavior the concurrent path has to reproduce is the behavior it
actually reproduces rather than a second implementation of it. The gap
between payments is measured from the moment the slot freed, which is
what makes max_in_flight one identical to the loop it replaces: 256
paired whole-output runs across the sealed hard, ood and corpus-mix
tiers and regenerated default, hard, drift, split and atomic corpora,
both arms, zero diffs, plus 132 mainnet runs compared as aggregate sets
because of stage B's finding 4.

Two things follow from running the traffic per interval rather than per
payment, and both are deliberate. A concurrent batch clears in less
virtual time and therefore churns the network for less of it. And the
whole window fills at once, since every slot is free when the batch
starts, so the first max_in_flight payments plan against the same
balances.

SimBalanceRefresher is the optional half of the contract: a router that
wants to be told its own outbound liquidity moved under it can be, and
router_accepts_balance_refresh says who asked. No router in this program
does, which is exp-016's lesson applied before the fact rather than
after it.

self_contention_failures is the number the stage exists to produce, and
it is causal rather than coincidental. The runner reads the failing
edge's true balance and reservation at the moment of the failure and
asks whether the edge would have carried the amount with the siblings'
share removed. Without atomic mpp nothing reserves anything, so the
counter is structurally zero and that tier is the free control.
2026-07-28 00:47:51 -07:00
..
blindedpath chanstate: use channel types in interfaces 2026-07-07 07:18:56 -03:00
chainview multi: fix lint findings from btcd v2 migration 2026-06-24 11:57:10 -07:00
localchans chanstate: use channel types in local chans 2026-07-07 07:18:58 -03:00
route Merge pull request #10789 from bitromortac/2604-bolt12-1a 2026-06-15 22:10:31 -03:00
shards multi: Fix typos [skip ci] 2022-01-24 12:19:02 +02:00
testdata routing: add private key attribute in router test 2021-06-23 18:13:02 +08:00
additional_edge.go multi+refactor: move models package to graph/db 2024-11-28 13:34:33 +02:00
additional_edge_test.go lint: remove redundant loop var copies in test files 2026-06-03 15:32:45 -03:00
bandwidth.go graph/db: thread context through ForEachNodeDirectedChannel 2026-02-25 15:33:34 +02:00
bandwidth_test.go multi: upgrade to btcd v2 modules 2026-06-24 10:58:36 -07:00
blinding.go routing: improve lasthoppaylaod size calculation 2024-12-10 19:05:49 +01:00
blinding_test.go lint: remove redundant loop var copies in test files 2026-06-03 15:32:45 -03:00
control_tower.go routing: fix log output line 2026-03-19 19:30:13 +01:00
control_tower_test.go multi: move failed attempt cfg option to the router subsytem 2026-02-25 08:02:26 +01:00
graph.go multi: upgrade to btcd v2 modules 2026-06-24 10:58:36 -07:00
heap.go routing: add inbound fee support to pathfinding 2024-03-31 18:12:28 +02:00
heap_test.go routing: optimize path finding structures 2019-10-24 21:38:07 -03:00
integrated_routing_context_test.go multi: skip range check in pathfinder and switch for custom htlc payments 2025-08-06 09:37:08 +02:00
integrated_routing_test.go multi: upgrade to btcd v2 modules 2026-06-24 10:58:36 -07:00
log.go multi: start updating various loggers to use the new v2 type 2024-10-22 17:03:55 +02:00
missioncontrol.go routing: the distillation patch, one live fix and one measured negative 2026-07-27 11:48:24 -07:00
missioncontrol_state.go routing: separate MissionControl from MissionControlManager 2024-10-01 14:06:50 +02:00
missioncontrol_state_test.go multi: formatting and comment fixes 2022-02-10 11:02:02 +01:00
missioncontrol_store.go routing: allow misson control manager to startup despite errors 2025-12-02 20:38:55 +01:00
missioncontrol_store_test.go lint: remove redundant loop var copies in test files 2026-06-03 15:32:45 -03:00
missioncontrol_test.go multi: update walletdb package 2025-04-09 18:47:53 +02:00
mock_graph_test.go multi: upgrade to btcd v2 modules 2026-06-24 10:58:36 -07:00
mock_test.go multi: upgrade to btcd v2 modules 2026-06-24 10:58:36 -07:00
nodepair.go routing: extended DirectedNodePair functionality 2019-08-13 18:45:06 +02:00
patch_config.go routing: the distillation patch, one live fix and one measured negative 2026-07-27 11:48:24 -07:00
patch_config_test.go routing: the distillation patch, one live fix and one measured negative 2026-07-27 11:48:24 -07:00
pathfind.go routing: the distillation patch, one live fix and one measured negative 2026-07-27 11:48:24 -07:00
pathfind_test.go multi: upgrade to btcd v2 modules 2026-06-24 10:58:36 -07:00
payment_lifecycle.go lint: enable copyloopvar and remove redundant loop var copies in non-test files 2026-06-03 15:32:46 -03:00
payment_lifecycle_test.go lint: remove redundant loop var copies in test files 2026-06-03 15:32:45 -03:00
payment_session.go routing: the distillation patch, one live fix and one measured negative 2026-07-27 11:48:24 -07:00
payment_session_source.go models: simplify models.Node 2025-11-12 22:54:04 +08:00
payment_session_test.go lint: remove redundant loop var copies in test files 2026-06-03 15:32:45 -03:00
probability_apriori.go multi: upgrade to btcd v2 modules 2026-06-24 10:58:36 -07:00
probability_apriori_test.go multi: upgrade to btcd v2 modules 2026-06-24 10:58:36 -07:00
probability_bimodal.go multi: upgrade to btcd v2 modules 2026-06-24 10:58:36 -07:00
probability_bimodal_test.go lint: remove redundant loop var copies in test files 2026-06-03 15:32:45 -03:00
probability_estimator.go multi: upgrade to btcd v2 modules 2026-06-24 10:58:36 -07:00
probability_estimator_test.go routing: add probability benchmarks 2023-02-14 13:34:25 +01:00
README.md scripted-diff: replace ⛰ emoji with $ [skip ci] 2022-10-28 12:06:49 -04:00
result_interpretation.go routing: the distillation patch, one live fix and one measured negative 2026-07-27 11:48:24 -07:00
result_interpretation_test.go routing: the distillation patch, one live fix and one measured negative 2026-07-27 11:48:24 -07:00
router.go multi: upgrade to btcd v2 modules 2026-06-24 10:58:36 -07:00
router_test.go multi: upgrade to btcd v2 modules 2026-06-24 10:58:36 -07:00
setup_test.go channeldb/test: test with postgres 2021-10-29 10:54:44 +02:00
sim_atomic_test.go routing: record which channel a hold reserves 2026-07-28 00:32:59 -07:00
sim_attribution.go routing+routesim: degrade the failure attribution channel 2026-07-27 00:54:37 -07:00
sim_attribution_test.go routing: price lnd's own path finding against the budget 2026-07-28 00:15:43 -07:00
sim_concurrency.go routing: run a payment batch on a virtual-time scheduler 2026-07-28 00:47:51 -07:00
sim_concurrency_test.go routing: run a payment batch on a virtual-time scheduler 2026-07-28 00:47:51 -07:00
sim_corridors_test.go routing: add corridors topology for MPP splitting pressure 2026-07-24 21:15:08 -07:00
sim_fee_limit.go routing: refuse a route the payment cannot afford 2026-07-28 00:15:43 -07:00
sim_fee_limit_test.go routing: price lnd's own path finding against the budget 2026-07-28 00:15:43 -07:00
sim_graph.go routing: record which channel a hold reserves 2026-07-28 00:32:59 -07:00
sim_htlc_limits.go routing: enforce the sender's own htlc limits under the stage A flag 2026-07-27 22:32:12 -07:00
sim_htlc_limits_test.go routing: draw min and max htlc from the mainnet marginals 2026-07-27 22:32:12 -07:00
sim_inbound_fees.go routing: draw inbound fees from the mainnet marginals 2026-07-27 23:31:21 -07:00
sim_inbound_fees_test.go routing: draw inbound fees from the mainnet marginals 2026-07-27 23:31:21 -07:00
sim_liquidity.go routing: parameterize the liquidity generator families 2026-07-27 00:07:05 -07:00
sim_liquidity_test.go routing: parameterize the liquidity generator families 2026-07-27 00:07:05 -07:00
sim_load.go routing: carry the inbound fee every real policy announces 2026-07-27 23:31:21 -07:00
sim_load_test.go routing: carry the inbound fee every real policy announces 2026-07-27 23:31:21 -07:00
sim_policy_test.go routing: enforce the sender's own htlc limits under the stage A flag 2026-07-27 22:32:12 -07:00
sim_router.go routing: run a payment batch on a virtual-time scheduler 2026-07-28 00:47:51 -07:00
sim_run.go routing: run a payment batch on a virtual-time scheduler 2026-07-28 00:47:51 -07:00
sim_test.go routing: add in-process Lightning payment simulator 2026-07-24 12:16:23 -07:00
sim_topology.go routing: add corridors topology for MPP splitting pressure 2026-07-24 21:15:08 -07:00
sim_traffic.go routing: teach the traffic engine what an inbound fee costs 2026-07-27 23:31:21 -07:00
sim_traffic_test.go routing: teach the traffic engine what an inbound fee costs 2026-07-27 23:31:21 -07:00
sim_warmup_test.go routing+routesim: add an unscored warmup phase for exp-012 2026-07-26 02:27:00 -07:00
sim_weights.go routing: price lnd's own path finding against the budget 2026-07-28 00:15:43 -07:00
sim_weights_test.go routing: serve observations, not weights 2026-07-26 22:55:22 -07:00
unified_edges.go multi: upgrade to btcd v2 modules 2026-06-24 10:58:36 -07:00
unified_edges_test.go multi: upgrade to btcd v2 modules 2026-06-24 10:58:36 -07:00

routing

Build Status MIT licensed GoDoc

The routing package implements authentication+validation of channel announcements, pruning of the channel graph, path finding within the network, sending outgoing payments into the network and synchronizing new peers to our channel graph state.

Installation and Updating

$  go get -u github.com/lightningnetwork/lnd/routing