mirror of
https://github.com/ZmnSCPxj/clboss.git
synced 2026-08-16 13:00:59 +02:00
In a circular rebalance the destination is ourselves, so a NODE-level onion failure (failcode & 0x2000) at the closing hop is attributed to erring_node == self. accumulate_failure_feedback's node-level branch called disable_node( erring_node) unconditionally, so it disabled OUR OWN node in the persistent clboss-xrebalance layer. askrene then treats every one of our channels as a disabled source -- getroutes fails with 205 "source has disabled N of N channels, leaving capacity only 0msat" -- and because disabled_nodes never ages, every subsequent rebalance is locked out permanently (fee budget is irrelevant). Observed on prod1: one end-of-route node failure took out all 73 source channels at once. Guard the node-level branch: if erring_node == self_id, return without disabling. Mirrors the self-loop guard FundsMover already has on the clboss layer. A node-level failure blamed on us (we are the paying destination, so we would accept) is a mis-attribution anyway and nothing about our own node should be disabled. Recovery for an already-poisoned layer (no askrene un-disable-node exists): askrene-remove-layer clboss-xrebalance ; askrene-create-layer clboss-xrebalance true Logging/behavior otherwise unchanged. |
||
|---|---|---|
| .. | ||
| Mod | ||
| ModG | ||
| Msg | ||
| concurrent.cpp | ||
| concurrent.hpp | ||
| JsonInput.cpp | ||
| JsonInput.hpp | ||
| log.cpp | ||
| log.hpp | ||
| Main.cpp | ||
| Main.hpp | ||
| open_rpc_socket.cpp | ||
| open_rpc_socket.hpp | ||
| random_engine.cpp | ||
| random_engine.hpp | ||
| Shutdown.hpp | ||
| Signer.cpp | ||
| Signer.hpp | ||