From 458ac32146b03a532c9998e28eaa83ebbcb7d13d Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Thu, 2 Feb 2023 11:40:33 +0200 Subject: [PATCH] multi: build retribution info in TowerClient Since the TowerClient now has a callback that it can use to retrieve the retribution for a certain channel and commit height, let it use this call back instead of requiring the info to be passed to it through BackupState. --- htlcswitch/interfaces.go | 8 ++------ htlcswitch/link.go | 22 ++++------------------ watchtower/wtclient/client.go | 26 ++++++++++++++++---------- watchtower/wtclient/client_test.go | 7 +++---- 4 files changed, 25 insertions(+), 38 deletions(-) diff --git a/htlcswitch/interfaces.go b/htlcswitch/interfaces.go index d24f48193..32d80ac11 100644 --- a/htlcswitch/interfaces.go +++ b/htlcswitch/interfaces.go @@ -7,7 +7,6 @@ import ( "github.com/lightningnetwork/lnd/invoices" "github.com/lightningnetwork/lnd/lnpeer" "github.com/lightningnetwork/lnd/lntypes" - "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwallet/chainfee" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/record" @@ -255,11 +254,8 @@ type TowerClient interface { // state. If the method returns nil, the backup is guaranteed to be // successful unless the tower is unavailable and client is force quit, // or the justice transaction would create dust outputs when trying to - // abide by the negotiated policy. If the channel we're trying to back - // up doesn't have a tweak for the remote party's output, then - // isTweakless should be true. - BackupState(*lnwire.ChannelID, *lnwallet.BreachRetribution, - channeldb.ChannelType) error + // abide by the negotiated policy. + BackupState(chanID *lnwire.ChannelID, stateNum uint64) error } // InterceptableHtlcForwarder is the interface to set the interceptor diff --git a/htlcswitch/link.go b/htlcswitch/link.go index d2dfc20ab..4c1745f0c 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -2022,11 +2022,6 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) { // We've received a revocation from the remote chain, if valid, // this moves the remote chain forward, and expands our // revocation window. - // - // Before advancing our remote chain, we will record the - // current commit tx, which is used by the TowerClient to - // create backups. - oldCommitTx := l.channel.State().RemoteCommitment.CommitTx // We now process the message and advance our remote commit // chain. @@ -2063,24 +2058,15 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) { // create a backup for the current state. if l.cfg.TowerClient != nil { state := l.channel.State() - breachInfo, err := lnwallet.NewBreachRetribution( - state, state.RemoteCommitment.CommitHeight-1, 0, - // OldCommitTx is the breaching tx at height-1. - oldCommitTx, - ) - if err != nil { - l.fail(LinkFailureError{code: ErrInternalError}, - "failed to load breach info: %v", err) - return - } - chanID := l.ChanID() + err = l.cfg.TowerClient.BackupState( - &chanID, breachInfo, state.ChanType, + &chanID, state.RemoteCommitment.CommitHeight-1, ) if err != nil { l.fail(LinkFailureError{code: ErrInternalError}, - "unable to queue breach backup: %v", err) + "unable to queue breach backup: %v", + err) return } } diff --git a/watchtower/wtclient/client.go b/watchtower/wtclient/client.go index 315ac06b8..5373edb66 100644 --- a/watchtower/wtclient/client.go +++ b/watchtower/wtclient/client.go @@ -136,11 +136,8 @@ type Client interface { // state. If the method returns nil, the backup is guaranteed to be // successful unless the client is force quit, or the justice // transaction would create dust outputs when trying to abide by the - // negotiated policy. If the channel we're trying to back up doesn't - // have a tweak for the remote party's output, then isTweakless should - // be true. - BackupState(*lnwire.ChannelID, *lnwallet.BreachRetribution, - channeldb.ChannelType) error + // negotiated policy. + BackupState(chanID *lnwire.ChannelID, stateNum uint64) error // Start initializes the watchtower client, allowing it process requests // to backup revoked channel states. @@ -805,32 +802,41 @@ func (c *TowerClient) RegisterChannel(chanID lnwire.ChannelID) error { // - breached outputs contain too little value to sweep at the target sweep // fee rate. func (c *TowerClient) BackupState(chanID *lnwire.ChannelID, - breachInfo *lnwallet.BreachRetribution, - chanType channeldb.ChannelType) error { + stateNum uint64) error { // Retrieve the cached sweep pkscript used for this channel. c.backupMu.Lock() summary, ok := c.summaries[*chanID] if !ok { c.backupMu.Unlock() + return ErrUnregisteredChannel } // Ignore backups that have already been presented to the client. height, ok := c.chanCommitHeights[*chanID] - if ok && breachInfo.RevokedStateNum <= height { + if ok && stateNum <= height { c.backupMu.Unlock() c.log.Debugf("Ignoring duplicate backup for chanid=%v at "+ - "height=%d", chanID, breachInfo.RevokedStateNum) + "height=%d", chanID, stateNum) + return nil } // This backup has a higher commit height than any known backup for this // channel. We'll update our tip so that we won't accept it again if the // link flaps. - c.chanCommitHeights[*chanID] = breachInfo.RevokedStateNum + c.chanCommitHeights[*chanID] = stateNum c.backupMu.Unlock() + // Fetch the breach retribution info and channel type. + breachInfo, chanType, err := c.cfg.BuildBreachRetribution( + *chanID, stateNum, + ) + if err != nil { + return err + } + task := newBackupTask( chanID, breachInfo, summary.SweepPkScript, chanType, ) diff --git a/watchtower/wtclient/client_test.go b/watchtower/wtclient/client_test.go index 37300f66a..718a902db 100644 --- a/watchtower/wtclient/client_test.go +++ b/watchtower/wtclient/client_test.go @@ -731,10 +731,9 @@ func (h *testHarness) backupState(id, i uint64, expErr error) { _, retribution := h.channel(id).getState(i) chanID := chanIDFromInt(id) - err := h.client.BackupState( - &chanID, retribution, channeldb.SingleFunderBit, - ) - require.ErrorIs(h.t, err, expErr) + + err := h.client.BackupState(&chanID, retribution.RevokedStateNum) + require.ErrorIs(h.t, expErr, err) } // sendPayments instructs the channel identified by id to send amt to the remote