It has been reported that on Windows, the current file swap process
doesn't properly work since we still have the file open when we try to
rename it. In order to fix this, we'll now close the file _before_ we
rename it.
In this commit, we make a series of changes to ensure that we'll be able
to properly survive restarts if we crash right after we call
MarkChannelClosed. In order to ensure we can survive restarts, we'll now
long the confirmed CommitSet to disk right before we close the channel.
Upon restart, we'll read these from disk so we can pick up where we left
over.
Additionally, we also will now consult the legacy chain actions if it
turns out that the channel has been closed, but we don't have a
confCommitSet written to disk. This will only be the case for nodes that
had pending close channels before this commitment.
In this commit, we add storage to the Briefcase for reading/writing a
confirmed CommitSet. This will be used in follow up commits to ensure
that we're able to survive restarts after we mark a channel as pending
closed. Along the way, we also re-add the FetchChainActions struct as
legacy nodes will need this storage.
Since we no longer have up to date chain actions on disk, we'll use the
HTLC sets in memory which contain the necessary information we need to
in order to obtain the HTLC amounts.
In this commit, we change the behavior of the channel arb to no longer
write chain actions to disk. Instead, using the new CommitSet struct,
we'll replay our set of prior actions based on what actually got into
the chain. As a result, we no longer need to write the chain actions at
all, instead they're reconstructed at run time to determine decisions,
and before any commitments are broadcast in order to determine if we
need to go to chain at all.
In this commit, we add a new `checkLocalChainActions` method. This
method differs from the existing `checkChainActions` method in that it's
only concerned with actions we should take on chain for our local state
based on the local _and_ remote state. This change ensures that we'll
now to go to chain order to cancel an HTLC that was on the remote
party's commitment transaction, but not our own.
In this commit, we fix a lingering TOOD statement in the channel arb.
Before this commitment, we would simply wipe our our local HTLC set of
the HTLC set that was on the remote commitment transaction on force
close. This was incorrect as if our commitment transaction had an HTLC
that the remote commitment didn't, then we would fail to cancel that
back, and cause both channels to time out on chain.
In order to remedy this, we introduce a new `HtlcSetKey` struct to track
all 3 possible in-flight set of HTLCs: ours, theirs, and their pending.
We also we start to tack on additional data to all the unilateral close
messages we send to subscribers. This new data is the CommitSet, or the
set of valid commitments at channel closure time. This new information
will be used by the channel arb in an upcoming commit to ensure it will
cancel back HTLCs in the case of split commitment state.
Finally, we start to thread through an optional *CommitSet to the
advanceState method. This additional information will give the channel
arb addition information it needs to ensure it properly cancels back
HTLCs that are about to time out or may time out depending on which
commitment is played.
Within the htlcswitch pakage, we modify the `SignNextCommitment` method
to return the new set of pending HTLCs for the remote party's commitment
transaction and `ReceiveRevocation` to return the latest set of
commitment transactions on the remote party's commitment as well. This
is a preparatory change which is part of a larger change to address a
lingering TODO in the cnct.
Additionally, rather than just send of the set of HTLCs after the we
revoke, we'll also send of the set of HTLCs after the remote party
revokes, and we create a pending commitment state for it.
TestRouterPaymentStateMachine tests that the router interacts as
expected with the ControlTower during a payment lifecycle, such that it
payment attempts are not sent twice to the switch, and results are
handled after a restart.