Skip to content

Commit

Permalink
rpcserver, chanbackup: save CloseTx in chanbackup
Browse files Browse the repository at this point in the history
  • Loading branch information
starius committed Nov 16, 2023
1 parent 7c98c88 commit 151feee
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 6 deletions.
63 changes: 61 additions & 2 deletions chanbackup/backup.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package chanbackup

import (
"bytes"
"fmt"
"net"

"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/lnwallet"
)

// LiveChannelSource is an interface that allows us to query for the set of
Expand Down Expand Up @@ -53,11 +56,44 @@ func assembleChanBackup(addrSource AddressSource,
return &single, nil
}

func buildCloseTx(targetChan *channeldb.OpenChannel, signer input.Signer) ([]byte, error) {
chanMachine, err := lnwallet.NewLightningChannel(signer, targetChan, nil)
if err != nil {
return nil, fmt.Errorf("lnwallet.NewLightningChannel failed: %w", err)
}
closeSummary, err := chanMachine.GetLocalForceCloseSummary()
if err != nil {
return nil, fmt.Errorf("GetLocalForceCloseSummary failed: %w", err)
}
var txBuf bytes.Buffer
if err := closeSummary.CloseTx.Serialize(&txBuf); err != nil {
return nil, fmt.Errorf("CloseTx.Serialize failed: %w", err)
}
return txBuf.Bytes(), nil
}

type BackupConfig struct {
signer input.Signer
}

type BackupOption func(*BackupConfig)

func WithCloseTx(signer input.Signer) BackupOption {
return func(c *BackupConfig) {
c.signer = signer
}
}

// FetchBackupForChan attempts to create a plaintext static channel backup for
// the target channel identified by its channel point. If we're unable to find
// the target channel, then an error will be returned.
func FetchBackupForChan(chanPoint wire.OutPoint, chanSource LiveChannelSource,
addrSource AddressSource) (*Single, error) {
addrSource AddressSource, options ...BackupOption) (*Single, error) {

var config BackupConfig
for _, opt := range options {
opt(&config)
}

// First, we'll query the channel source to see if the channel is known
// and open within the database.
Expand All @@ -75,13 +111,27 @@ func FetchBackupForChan(chanPoint wire.OutPoint, chanSource LiveChannelSource,
return nil, fmt.Errorf("unable to create chan backup: %v", err)
}

if config.signer != nil {
// Add CloseTx.
closeTx, err := buildCloseTx(targetChan, config.signer)
if err != nil {
return nil, fmt.Errorf("unable to create close tx for ChannelPoint(%v): %w", targetChan, err)
}
staticChanBackup.CloseTx = closeTx
}

return staticChanBackup, nil
}

// FetchStaticChanBackups will return a plaintext static channel back up for
// all known active/open channels within the passed channel source.
func FetchStaticChanBackups(chanSource LiveChannelSource,
addrSource AddressSource) ([]Single, error) {
addrSource AddressSource, options ...BackupOption) ([]Single, error) {

var config BackupConfig
for _, opt := range options {
opt(&config)
}

// First, we'll query the backup source for information concerning all
// currently open and available channels.
Expand All @@ -100,6 +150,15 @@ func FetchStaticChanBackups(chanSource LiveChannelSource,
return nil, err
}

if config.signer != nil {
// Add CloseTx.
closeTx, err := buildCloseTx(openChan, config.signer)
if err != nil {
return nil, fmt.Errorf("unable to create close tx for ChannelPoint(%v): %w", openChan, err)
}
chanBackup.CloseTx = closeTx
}

staticChanBackups = append(staticChanBackups, *chanBackup)
}

Expand Down
27 changes: 23 additions & 4 deletions chanbackup/pubsub.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/keychain"
)

Expand Down Expand Up @@ -93,6 +94,9 @@ type SubSwapper struct {
// multi backup.
keyRing keychain.KeyRing

// signer is used to sign CloseTx.
signer input.Signer

Swapper

quit chan struct{}
Expand All @@ -104,7 +108,13 @@ type SubSwapper struct {
// updates, pack a multi backup, and swap the current best backup from its
// storage location.
func NewSubSwapper(startingChans []Single, chanNotifier ChannelNotifier,
keyRing keychain.KeyRing, backupSwapper Swapper) (*SubSwapper, error) {
keyRing keychain.KeyRing, backupSwapper Swapper,
options ...BackupOption) (*SubSwapper, error) {

var config BackupConfig
for _, opt := range options {
opt(&config)
}

// First, we'll subscribe to the latest set of channel updates given
// the set of channels we already know of.
Expand All @@ -128,6 +138,7 @@ func NewSubSwapper(startingChans []Single, chanNotifier ChannelNotifier,
backupState: backupState,
chanEvents: chanEvents,
keyRing: keyRing,
signer: config.signer,
Swapper: backupSwapper,
quit: make(chan struct{}),
}, nil
Expand Down Expand Up @@ -266,9 +277,17 @@ func (s *SubSwapper) backupUpdater() {
log.Debugf("Adding channel %v to backup state",
newChan.FundingOutpoint)

s.backupState[newChan.FundingOutpoint] = NewSingle(
newChan.OpenChannel, newChan.Addrs,
)
single := NewSingle(newChan.OpenChannel, newChan.Addrs)
if s.signer != nil {
// Add CloseTx.
closeTx, err := buildCloseTx(newChan.OpenChannel, s.signer)
if err != nil {
log.Errorf("unable to create close tx for ChannelPoint(%v): %v", newChan.OpenChannel, err)
} else {
single.CloseTx = closeTx
}
}
s.backupState[newChan.FundingOutpoint] = single
}

// For all closed channels, we'll remove the prior
Expand Down
3 changes: 3 additions & 0 deletions rpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -7195,6 +7195,7 @@ func (r *rpcServer) ExportChannelBackup(ctx context.Context,
// unknown, then we'll return an error
unpackedBackup, err := chanbackup.FetchBackupForChan(
chanPoint, r.server.chanStateDB, r.server.addrSource,
chanbackup.WithCloseTx(r.server.cc.Signer),
)
if err != nil {
return nil, err
Expand Down Expand Up @@ -7365,6 +7366,7 @@ func (r *rpcServer) ExportAllChannelBackups(ctx context.Context,
// channels from disk.
allUnpackedBackups, err := chanbackup.FetchStaticChanBackups(
r.server.chanStateDB, r.server.addrSource,
chanbackup.WithCloseTx(r.server.cc.Signer),
)
if err != nil {
return nil, fmt.Errorf("unable to fetch all static chan "+
Expand Down Expand Up @@ -7494,6 +7496,7 @@ func (r *rpcServer) SubscribeChannelBackups(req *lnrpc.ChannelBackupSubscription
// backups from disk.
chanBackups, err := chanbackup.FetchStaticChanBackups(
r.server.chanStateDB, r.server.addrSource,
chanbackup.WithCloseTx(r.server.cc.Signer),
)
if err != nil {
return fmt.Errorf("unable to fetch all "+
Expand Down
2 changes: 2 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -1465,12 +1465,14 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
backupFile := chanbackup.NewMultiFile(cfg.BackupFilePath)
startingChans, err := chanbackup.FetchStaticChanBackups(
s.chanStateDB, s.addrSource,
chanbackup.WithCloseTx(s.cc.Signer),
)
if err != nil {
return nil, err
}
s.chanSubSwapper, err = chanbackup.NewSubSwapper(
startingChans, chanNotifier, s.cc.KeyRing, backupFile,
chanbackup.WithCloseTx(s.cc.Signer),
)
if err != nil {
return nil, err
Expand Down

0 comments on commit 151feee

Please sign in to comment.