lnd/cmd
Olaoluwa Osuntokun 4fe4032b70 routing: serve observations, not weights
exp-012 could not price a warm cache. Every arm it could build bought
its knowledge with payments, and payments drain the corridors they
teach about, so the drain arm paid in depletion and the restore arm
paid in staleness. A served cache costs its consumer nothing because
it arrives over an API, and nothing in the simulator could express
that. --import-weights can: beliefs from a file, no payments sent.

The design decision is what gets served. Neither side's internal
representation is servable -- mission control keeps a decaying penalty
history keyed by the observer, the evolved routers keep an interval
with an evidence count -- but both are derivable from a stream of
(from, to, chan_id, amount, success, time). So the API serves
OBSERVATIONS. Serving weights would force every consumer into the
server's probability model; serving observations lets each consumer
build its own, which is the difference between an API only lnd can
use and one a competing design can.

Both consumers are fed from that one stream. lnd's half goes through
MissionControl.ImportHistory, which already ships, so the serving
proposal needs no new consumer machinery on lnd's side. The candidate
half is a new optional interface, and its being optional is itself a
finding: no champion evolved so far implements it, because nothing
ever asked them to. import_router_accepts is reported alongside the
counts so that an ineffective import stays distinguishable from an
undelivered one.

Local channels are excluded by default, which is exp-012 part 4's
measured rule rather than a guess: observations about remote pairs
transfer between vantages, but every payment a node sends crosses one
of its own channels, so importing stale claims about those poisons the
first hop of everything and tripled lnd's attempt count. --import-local
reproduces that deliberately.

Two things surfaced while wiring it up. ImportHistory must NOT be
forced: importSnapshot applies a success entry for every pair, so a
pair we only observed failing carries a zero-amount success, and under
force setLastPairResult rewrites the failure amount to successAmt+1 --
a 750k msat failure lands as a 1 msat failure. Unforced also gives the
right semantics for a served cache, which should never overwrite
fresher local knowledge. And route.Vertex marshals as a 33-element
byte array, which is not a reasonable wire shape for something
standing in for an API payload, so observations carry hex pubkeys.
2026-07-26 22:55:22 -07:00
..
commands lncli: add wallet submitpackage command 2026-06-30 11:07:52 -07:00
lncli cmd/lncli: move commands and export 2024-08-23 10:57:59 +02:00
lnd multi: extract wallet initialization 2021-10-08 12:13:15 +02:00
routesim routing: serve observations, not weights 2026-07-26 22:55:22 -07:00