17089 Commits

Author SHA1 Message Date
Olaoluwa Osuntokun
57229e3a62 lntest+itest: extend CloseChannelAssertPending
In this commit, we extend `CloseChannelAssertPending` with new args that
returns the raw close status update (as we have more things we'd like to
assert), and also allows us to pass in a custom fee rate.
2024-08-16 16:16:08 -07:00
Olaoluwa Osuntokun
39aa949a75 lntest: fix error message in WaitForChannelCloseEvent
Resp is always nil, so we actually need to log event.Update here.
2024-08-16 16:15:27 -07:00
Olaoluwa Osuntokun
5546edccf6 lnd: register protofsm logger 2024-08-16 16:15:27 -07:00
Olaoluwa Osuntokun
45428eae03 peer+rpc: set new rbf coop close rbf update fields 2024-08-16 16:15:27 -07:00
Olaoluwa Osuntokun
9776d5c362 lnrpc: add fee rate and local close bool to PendingUpdate
This'll allow us to notify the caller each time a new coop close
transaction with a higher fee rate is signed.
2024-08-16 16:15:22 -07:00
Olaoluwa Osuntokun
a03cd75db6 peer: attempt to unregister endpoint before registering
If we hit an error, we want to wipe the state machine state, which also
includes removing the old endpoint.
2024-08-16 16:12:17 -07:00
Olaoluwa Osuntokun
d06cb88c20 peer: make activeChanCloses a SyncMap
This fixes some existing race conditions, as the `finalizeChanClosure`
function was being called from outside the main event loop.
2024-08-16 16:11:45 -07:00
Olaoluwa Osuntokun
37e00e9563 lnwallet: remove the isClosed check for coop close
With the new RBF based close, we'll actually close the same channel multiple times, so this check isn't required any longer.
2024-08-16 16:10:18 -07:00
Olaoluwa Osuntokun
abf2249203 lnwallet/chancloser: ignore spurious channel flushed events
If we go to close while the channel is already flushed, we might get an extra event, so we can safely ignore it and do a self state transition.
2024-08-16 16:10:18 -07:00
Olaoluwa Osuntokun
93684ec9b7 lnwallet/chancloser: add fee rate to ClosePending
This'll be useful to communicate what the new fee rate is to an RPC caller.
2024-08-16 16:10:18 -07:00
Olaoluwa Osuntokun
a3e74415bf protofsm: don't return error on broadcast fail
We don't return an error on broadcast fail as the broadcast might have failed due to insufficient fees, or inability to be replaced, which may happen when one side attempts to unnecessarily bump their coop close fee.
2024-08-16 16:10:18 -07:00
Olaoluwa Osuntokun
231275faee itest: update async coop close itests to also use new rbf flow 2024-08-16 16:10:18 -07:00
Olaoluwa Osuntokun
a68b78d12c server: thread through new NoRbfCoopClose option
For now, we disallow the option to be used with the taproot chans
option, as the new flow hasn't yet been updated for nonce usage.
2024-08-16 16:10:12 -07:00
Olaoluwa Osuntokun
5fac5a6e0b lncfg: add new protocol option - RbfCoopClose 2024-08-16 16:09:32 -07:00
Olaoluwa Osuntokun
7feb3bdf83 feature: add new NoRbfCoopClose option 2024-08-16 16:09:30 -07:00
Olaoluwa Osuntokun
3cb45b5bcc peer: conditionally create rbf coop close fsm based on feature bits
In this commit, we fully integrate the new RBF close state machine into
the peer.

For the restart case after shutdown, we can short circuit the existing
logic as the new FSM will handle retransmitting the shutdown message
itself, and doesn't need to delegate that duty to the link.

Unlike the existing state machine, we're able to restart the flow to
sign a coop close with a new higher fee rate. In this case, we can now
send multiple updates to the RPC caller, one for each newly singed coop
close transaction.

To implement the async flush case, we'll launch a new goroutine to wait
until the state machine reaches the `ChannelFlushing` state, then we'll
register the hook. We don't do this at start up, as otherwise the
channel may _already_ be flushed, triggering an invalid state
transition.
2024-08-16 16:08:27 -07:00
Olaoluwa Osuntokun
0961d05810 peer: create ErrorReporter implementation for rbf-fsm 2024-08-16 16:05:19 -07:00
Olaoluwa Osuntokun
60eac1cd0d peer: add message summaries for ClosingSig+ClosingComplete 2024-08-16 16:03:45 -07:00
Olaoluwa Osuntokun
7714994d09 peer: conditionally create new RBF chan closer 2024-08-16 16:03:45 -07:00
Olaoluwa Osuntokun
5a41487775 peer: add new composite chanCloserFsm type
In this commit, we add a new composite chanCloserFsm type. This'll allow
us to store a single value that might be a negotiator or and rbf-er.

In a follow up commit, we'll use this to conditionally create the new
rbf closer.
2024-08-16 16:03:43 -07:00
Olaoluwa Osuntokun
a89784a7fb peer: add initial awareness of new rbf coop closer
In this commit, we use the interfaces we created in the prior commit to
make a new method capable of spinning up the new rbf coop closer.
2024-08-16 15:43:03 -07:00
Olaoluwa Osuntokun
c3331e5f5b peer: make a DaemonAdapter impl for lnd
Similar to the last commit, in this commit, we make a daemon adapter
impl for lnd. We'll use this for any future protofsm based state
machine.
2024-08-16 15:43:03 -07:00
Olaoluwa Osuntokun
d17d951c9f peer: add an implementation of chancloser.ChanObserver
In this commit, we add an implementation of a new interface the rbf coop
state machine needs. We take care to accept interfaces everywhere, to
make this easier to test, and decouple from the concrete types we'll end
up using elsewhere.
2024-08-16 15:43:03 -07:00
Olaoluwa Osuntokun
bf8df499ea htlcswitch: change LinkDirection to be a type alias
In this commit, we change LinkDirection to be a type alias. This makes
creating wrapper structs/interfaces easier, as we don't need to leak
htlcswitch.LinkDirection, instead we can accept a bool.
2024-08-16 15:43:03 -07:00
Olaoluwa Osuntokun
f81bf5feca peer: move existing chan closer init logic to new method
In the next commit, we'll start checking feature bits to decide how to
init the chan closer.

In the future, we can move the current chan closer handling logic into
an `MsgEndpoint`, which'll allow us to get rid of the explicit chan
closer map and direct handling.
2024-08-16 15:43:00 -07:00
Olaoluwa Osuntokun
49888b4fe7 feature: set optional bit for rbf-coop close by default 2024-08-16 15:28:18 -07:00
Olaoluwa Osuntokun
c7a09418a0 lnwire: add feature bits for new rbf coop close 2024-08-16 15:21:10 -07:00
Olaoluwa Osuntokun
a4852de69e lnwallet/chancloser: add unit tests for new rbf coop close 2024-08-16 15:17:31 -07:00
Olaoluwa Osuntokun
dcc4d8ea1d lnwallet/chancloser: create a MsgMapper for the protofsm rbf close
This'll allow us to treat the state machine as a MsgEndpoint, and have
the readHandler in the peer automatically send new messages to it.
2024-08-16 15:17:31 -07:00
Olaoluwa Osuntokun
a6e37466e2 lnwallet/chancloser: add state transitions for new protofsm rbf closer
In this commit, we add the state transitions for the new protofsm based
RBF chan closer. The underlying protocol is a new asymmetric co-op close
process, wherein either side can initiate a chan closer, and use their
settled funds to pay for fees within the channel.
2024-08-16 15:17:31 -07:00
Olaoluwa Osuntokun
7afdccecbb lnwallet: add ability to specify custom sequence for co-op close tx
In this commit, we add the ability to specify a custom sequence for a
co-op close tx. This'll come in handy later as the new co-op close
process allows a party to set a custom sequence.
2024-08-16 15:05:56 -07:00
Olaoluwa Osuntokun
a10245ee33 lnwallet/chancloser: add states for new protofsm rbf closer
In this commit, we add the initial set of states for the new protofsm
based rbf chan closer. A diagram outlining the new states and their
transitions can be found here:
https://gist.github.com/Roasbeef/acc4ff51b9dff127230228a05553cdfe.

Unlike the existing co-op close process, this co-op close can be
restarted at anytime if either side sends a shutdown message. From
there, we'll each obtain a new RBF'd version that can be re-broadcasted.

This commit creates the set of states, along with the environment that
our state machine will use to drive itself forward.
2024-08-16 15:05:56 -07:00
Olaoluwa Osuntokun
06c691e753 protofsm: allow multiple internal events to be emitted
In this commit, we update the execution logic to allow multiple internal
events to be emitted. This is useful to handle potential out of order
state transitions, as they can be cached, then emitted once the relevant
pre-conditions have been met.
2024-08-16 14:59:47 -07:00
Olaoluwa Osuntokun
8816b357ef protofsm: add SpendMapper to craft custom spend events
In this commit, we add the SpendMapper which allows callers to create
custom spent events. Before this commit, the caller would be able to
have an event sent to them in the case a spend happens, but that event
wouldn't have any of the relevant spend details.

With this new addition, the caller can specify how to take a generic
spend event, and transform it into the state machine specific spend
event.
2024-08-16 14:59:47 -07:00
Olaoluwa Osuntokun
383e192b4e protofsm: add CustomPollInterval for mocking purposes
Adding this makes a state machine easier to unit test, as the caller can
specify a custom polling interval.
2024-08-16 14:59:47 -07:00
Olaoluwa Osuntokun
12e9e07d9f protofsm: add ErrorReporter interface
We'll use this to be able to signal to a caller that a critical error
occurred during the state transition.
2024-08-16 14:59:47 -07:00
Olaoluwa Osuntokun
cd26a48526 protofsm: add logging 2024-08-16 14:59:47 -07:00
Olaoluwa Osuntokun
edaa465556 protofsm: add a Name() method to the env
This'll be used later to uniquely identify state machines for
routing/dispatch purposes.
2024-08-16 14:59:47 -07:00
Olaoluwa Osuntokun
e8fbe2de26 protofsm: add ability for state machine to consume wire msgs
In this commit, we add the ability for the state machine to consume wire
messages. This'll allow the creation of a new generic message router
that takes the place of the current peer `readHandler` in an upcoming
commit.
2024-08-16 14:59:47 -07:00
Olaoluwa Osuntokun
75dffff1eb protofsm: convert state machine args into config 2024-08-16 14:59:47 -07:00
Olaoluwa Osuntokun
633b73df8f protofsm: add optional daemon event on init
In this commit, we add an optional daemon event that can be specified to
dispatch during init. This is useful for instances where before we
start, we want to make sure we have a registered spend/conf notification
before normal operation starts.

We also add new unit tests to cover this, and the prior spend/conf event
additions.
2024-08-16 14:59:47 -07:00
Olaoluwa Osuntokun
014efb3272 protofsm: add daemon events for spend+conf registration 2024-08-16 14:59:47 -07:00
Olaoluwa Osuntokun
a0178bf873 protofsm: add new package for driving generic protocol FSMs
In this PR, we create a new package, `protofsm` which is intended to
abstract away from something we've done dozens of time in the daemon:
create a new event-drive protocol FSM. One example of this is the co-op
close state machine, and also the channel state machine itself.

This packages picks out the common themes of:

  * clear states and transitions between them
  * calling out to special daemon adapters for I/O such as transaction
    broadcast or sending a message to a peer
  * cleaning up after state machine execution
  * notifying relevant callers of updates to the state machine

The goal of this PR, is that devs can now implement a state machine
based off of this primary interface:
```go
// State defines an abstract state along, namely its state transition function
// that takes as input an event and an environment, and returns a state
// transition (next state, and set of events to emit). As state can also either
// be terminal, or not, a terminal event causes state execution to halt.
type State[Event any, Env Environment] interface {
	// ProcessEvent takes an event and an environment, and returns a new
	// state transition. This will be iteratively called until either a
	// terminal state is reached, or no further internal events are
	// emitted.
	ProcessEvent(event Event, env Env) (*StateTransition[Event, Env], error)

	// IsTerminal returns true if this state is terminal, and false otherwise.
	IsTerminal() bool
}
```

With their focus being _only_ on each state transition, rather than all
the boiler plate involved (processing new events, advancing to
completion, doing I/O, etc, etc).

Instead, they just make their states, then create the state machine
given the starting state and env. The only other custom component needed
is something capable of mapping wire messages or other events from the
"outside world" into the domain of the state machine.

The set of types is based on a pseudo sum type system wherein you
declare an interface, make the sole method private, then create other
instances based on that interface. This restricts call sites (must pass
in that interface) type, and with some tooling, exhaustive matching can
also be enforced via a linter.

The best way to get a hang of the pattern proposed here is to check out
the tests. They make a mock state machine, and then use the new executor
to drive it to completion. You'll also get a view of how the code will
actually look, with the focus being on the: input event, current state,
and output transition (can also emit events to drive itself forward).
2024-08-16 14:59:47 -07:00
Olaoluwa Osuntokun
8ac184a911
Merge pull request #8520 from lightningnetwork/peer-msg-router
[2/4] - peer: add new abstract message router
2024-08-16 14:57:44 -07:00
Olaoluwa Osuntokun
7c24e33614
Merge pull request #8996 from ProofOfKeags/dual
[MICRO]: lntypes: Add Dual[A] primitive type
2024-08-16 14:47:39 -07:00
Keagan McClelland
34f7c31dc8
lntypes: Add Dual[A] primitive type
This commit introduces a new type Dual[A] to make it easier to
manage symmetric configurations or state for lightning channels.
2024-08-15 10:53:18 -07:00
Oliver Gugger
0aced5ce2d
Merge pull request #8857 from MPins/issue-8793
Fixing the current state update when lncli debuglevel and lncli setmccfg are called
2024-08-15 02:33:54 -06:00
Olaoluwa Osuntokun
f09c517bc6 peer: don't stop global msg router
In this commit, we fix a bug that would cause a global message router to
be stopped anytime a peer disconnected. The global msg router only
allows `Start` to be called once, so afterwards, no messages would
properly be routed.
2024-08-14 19:23:02 -07:00
Olaoluwa Osuntokun
b028af1836 multi: make MsgRouter available in the ImplementationCfg
With this commit, we allow the `MsgRouter` to be available in the
`ImplementationCfg`. With this, programs outside of lnd itself are able
to now hook into the message processing flow to direct handle custom
messages, and even normal wire messages.
2024-08-14 19:23:02 -07:00
Olaoluwa Osuntokun
927aa84b5f peer: update readHandler to dispatch to msgRouter if set
Over time with this, we should be able to significantly reduce the size
of the peer.Brontide struct as we only need all those deps as the peer
needs to recognize and handle each incoming wire message itself.
2024-08-14 19:23:02 -07:00