In this commit, we convert the `JusticeKit` struct to an interface.
Then, we add two implementations of that interface:
1) The `legacyJusticeKit` which implements all the methods of
`JusticeKit`
2) The `anchorJusticKit` which wraps the `legacyJusticeKit` and just
re-implements the `ToRemoteOutputSpendInfo` method since.
In preparation for the next commit which will introduce the `JusticeKit`
interface, here we just move the code related to building the actual
justice kit packet into a separate file.
In this commit a new enum, CommitmentType, is introduced and initially
there are 3 CommitmentTypes: Legacy, LegacyTweakless and Anchor.
Then, various methods are added to `CommitmentType`. This allows us to
remove a bunch of "if-else" chains from the `wtclient` and `lookout`
code. This will also make things easier to extend when a new commitment
type (like Taproot) is added.
This commit is a set-up commit. It extracts the logic from
`MarkEdgeLive` to a helper `markEdgeLive` method so that the logic can
be called from within other kvdb.Update blocks. This will be used in the
next commit.
This commit moves over the last two methods, `RegisterChannel` and
`BackupState` from the `Client` to the `Manager` interface. With this
change, we no longer need to pass around the individual clients around
and now only need to pass the manager around.
To do this change, all the goroutines that handle channel closes,
closable sessions needed to be moved to the Manager and so a large part
of this commit is just moving this code from the TowerClient to the
Manager.
This commit removes the mutex from ClientStats and instead puts that in
clientStats which wraps ClientStats with a mutex. This is so that the
tower client interface can return a ClientStats struct without worrying
about copying a mutex.
Simiarly to the previous commit, this commit moves the RemoveTower
method from the Client to the TowerClientManager interface. The manager
handles any DB related handling. The manager will first attempt to
remove the tower from the in-memory state of each client and then will
attempt to remove the tower from the DB. If the removal from the DB
fails, the manager will re-add the tower to the in-memory state of each
client.
In this commit we move the AddTower method from the Client interface to
the TowerClientManager interface. The wtclientrpc is updated to call the
`AddTower` method of the Manager instead of calling the `AddTower`
method of each individual client. The TowerClient now is also only
concerned with adding a new tower (or new tower address) to its
in-memory state; the tower Manager will handle adding the tower to the
DB.
In this commit, the `Stop` and `Start` methods are removed from the
`Client` interface and instead added to the new `Manager`. Callers now
only need to call the Manager to start or stop the clients instead of
needing to call stop/start on each individual client.
Introduce a wtclient `Manager` which handles tower clients. It indexes
clients by the policy used. The policy field is thus removed from the
`Config` struct which configures the Manager and is instead added to a
new `towerClientCfg` which configures a specific client managed by the
manager. For now, only the `NewClient` method is added to the Manager.
It can be used to construct a new `TowerClient`. The Manager currently
does notthing with the clients added to it.
This commit also adds tests for the DB changes made in the previous
commit since we can now read the new field with the FetchChanInfos
method.
The commit following this one does the backfill migration.
In this commit, a new key, cChanMaxCommitmentHeight, is added to the
channel details bucket. This key will hold the highest commitment number
that the tower has been handed for this channel. In this commit, we
start writing to it in the two places where a backup is first persisted
in the tower client db: 1) CommitUpdate and 2) in the Queue's `addItem`
method. The logic for both 1 & 2 is tested in the next commit which adds
a DB helper that allows us to read the new field.
A follow up commit will do a migration to back-fill the new field.
In processZombieUpdate, the SCID passed to MarkEdgeLive should _not_ be
derived from the ChannelEdgeInfo ChannelID field since this field will
not be populated when GetChannelByID returns a ChannelEdgeInfo along
with an ErrZombieEdge error. So this commit ensures that a usable
SCID is provided to processZombieUpdate.
Let MarkEdgLive return a new ErrNotZombieEdge error if an entry with the
given channel ID cannot be found. In processZombieUpdate, we then
check for this error and log accordingly.
Finally, The LightningNode object is removed from ChannelEdgePolicy.
This is a step towards letting ChannelEdgePolicy reflect exactly the
schema that is on disk.
This is also nice because the `Node` object is not necessarily always
required when the ChannelEdgePolicy is loaded from the DB, so now it
only get's loaded when needed.
In preparation for the next commit which will remove the
`*LightningNode` from the `ChannelEdgePolicy` struct,
`FetchLightningNode` is modified to take in an optional transaction so
that it can be utilised in places where a transaction exists.
To prepare for the `kvdb.Backend` member of `ChannelEdgeInfo` being
removed, the `FetchOtherNode` method is moved from the `ChannelEdgeInfo`
to the `ChannelGraph` struct.
Having a `ForEachChannel` method on the `LightningNode` struct itself
results in a `kvdb.Backend` object needing to be stored within the
LightningNode struct. In this commit, this method is replaced with a
`ForEachNodeChannel` method on the `ChannelGraph` struct will perform
the same function without needing the db pointer to be stored within the
LightningNode. This change, the LightningNode struct more closely
represents the schema on disk.
The existing `ForEachNodeChannel` method on `ChannelGraph` is renamed to
`ForEachNodeDirectedChannel`. It performs a slightly different function
since it's call-back operates on Cached policies.
This commit removes the `Litecoin`, `LtcMode` and `LitecoindMode`
members from the main LND `Config` struct. Since only the bitcoin
blockchain is now supported, this commit also deprecates the
`cfg.Bitcoin.Active` config option.
In this commit, we introduce the concept of a rogue update. An update is
rogue if we need to ACK it but we have already deleted all the data for
the associated channel due to the channel being closed. In this case, we
now no longer error out and instead keep count of how many rogue updates
a session has backed-up.
This commit adds a new test to the tower client to demonstrate a bug
that can happen if a channel is closed while an update for it has yet to
be acked by the tower server. This will be fixed in an upcomming commit.
The watchtower client test framework currently uses a mock version of
the tower client DB. This can lead to bugs if the mock DB works slightly
differently to the actual bbolt DB. So this commit ensures that we only
use the bbolt db for the tower client tests. We also increment the
`waitTime` used in the tests a bit to account for the slightly longer DB
read and write times. Doing this switch resulted in one bug being
caught: we were not removing sessions from the in-memory set on deletion
of the session and so that is fixed here too.
This commit moves the registration of the State server with a REST proxy
into the `RegisterWithRestProxy` method in order to keep all the REST
registrations in one place.
In this commit, the bugs demonstrated in prior commits are fixed. In the
case where an session has persisted a CommittedUpdate and the tower is
being removed, the session will now replay that update on to the main
task pipeline so that it can be backed up using a different session.
Add a new DeleteCommittedUpdate method to the wtdb In preparation for an
upcoming commit that will replay committed updates from one session to
another.
This commit demonstrates that if a session has persisted committed
updates and the client is restarted _after_ these committed updates have
been persisted, then removing the tower will fail.
In this commit, we demonstrate the situation where a client has
persisted CommittedUpdates but has not yet recieved Acks for them from
the tower. If this happens and the client attempts to remove the tower,
it will with the "tower has unacked updates" error.
This commit does a few things:
- First, it gives the sessionQueue access to the TowerClient task
pipeline so that it can replay backup tasks onto the pipeline on Stop.
- Given that the above is done, the ForceQuit functionality of the
sessionQueue and TowerClient can be removed.
- The bug demonstrated in a prior commit is now fixed due to the above
changes.
In preparation for an upcoming commit where multiple threads will have
access to the TowerClient sessionQueueSet, we turn it into a thread safe
struct.
This commit demonstrates a bug. It shows that if backup tasks have been
bound to a session with a tower (ie, the tasks are in the session's
pendingQueue) and then the tower is removed and a new one is added, then
the tasks from the pendingQueue are _not_ replayed to the session with
the new tower. Instead, they are silently lost. This will be fixed in an
upcoming commit.
This commit adds a new watchtower client test to demonstrate that a
client is able to successfully switch to a new tower and continue
backing up updates to that new tower.