github.com/decred/dcrlnd@v0.7.6/chanbackup/backup.go (about)

     1  package chanbackup
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  
     7  	"github.com/decred/dcrd/dcrec/secp256k1/v4"
     8  	"github.com/decred/dcrd/wire"
     9  	"github.com/decred/dcrlnd/channeldb"
    10  	"github.com/decred/dcrlnd/kvdb"
    11  )
    12  
    13  // LiveChannelSource is an interface that allows us to query for the set of
    14  // live channels. A live channel is one that is open, and has not had a
    15  // commitment transaction broadcast.
    16  type LiveChannelSource interface {
    17  	// FetchAllChannels returns all known live channels.
    18  	FetchAllChannels() ([]*channeldb.OpenChannel, error)
    19  
    20  	// FetchChannel attempts to locate a live channel identified by the
    21  	// passed chanPoint. Optionally an existing db tx can be supplied.
    22  	FetchChannel(tx kvdb.RTx, chanPoint wire.OutPoint) (
    23  		*channeldb.OpenChannel, error)
    24  }
    25  
    26  // AddressSource is an interface that allows us to query for the set of
    27  // addresses a node can be connected to.
    28  type AddressSource interface {
    29  	// AddrsForNode returns all known addresses for the target node public
    30  	// key.
    31  	AddrsForNode(nodePub *secp256k1.PublicKey) ([]net.Addr, error)
    32  }
    33  
    34  // assembleChanBackup attempts to assemble a static channel backup for the
    35  // passed open channel. The backup includes all information required to restore
    36  // the channel, as well as addressing information so we can find the peer and
    37  // reconnect to them to initiate the protocol.
    38  func assembleChanBackup(addrSource AddressSource,
    39  	openChan *channeldb.OpenChannel) (*Single, error) {
    40  
    41  	log.Debugf("Crafting backup for ChannelPoint(%v)",
    42  		openChan.FundingOutpoint)
    43  
    44  	// First, we'll query the channel source to obtain all the addresses
    45  	// that are associated with the peer for this channel.
    46  	nodeAddrs, err := addrSource.AddrsForNode(openChan.IdentityPub)
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  
    51  	single := NewSingle(openChan, nodeAddrs)
    52  
    53  	return &single, nil
    54  }
    55  
    56  // FetchBackupForChan attempts to create a plaintext static channel backup for
    57  // the target channel identified by its channel point. If we're unable to find
    58  // the target channel, then an error will be returned.
    59  func FetchBackupForChan(chanPoint wire.OutPoint, chanSource LiveChannelSource,
    60  	addrSource AddressSource) (*Single, error) {
    61  
    62  	// First, we'll query the channel source to see if the channel is known
    63  	// and open within the database.
    64  	targetChan, err := chanSource.FetchChannel(nil, chanPoint)
    65  	if err != nil {
    66  		// If we can't find the channel, then we return with an error,
    67  		// as we have nothing to  backup.
    68  		return nil, fmt.Errorf("unable to find target channel")
    69  	}
    70  
    71  	// Once we have the target channel, we can assemble the backup using
    72  	// the source to obtain any extra information that we may need.
    73  	staticChanBackup, err := assembleChanBackup(addrSource, targetChan)
    74  	if err != nil {
    75  		return nil, fmt.Errorf("unable to create chan backup: %v", err)
    76  	}
    77  
    78  	return staticChanBackup, nil
    79  }
    80  
    81  // FetchStaticChanBackups will return a plaintext static channel back up for
    82  // all known active/open channels within the passed channel source.
    83  func FetchStaticChanBackups(chanSource LiveChannelSource,
    84  	addrSource AddressSource) ([]Single, error) {
    85  
    86  	// First, we'll query the backup source for information concerning all
    87  	// currently open and available channels.
    88  	openChans, err := chanSource.FetchAllChannels()
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  
    93  	// Now that we have all the channels, we'll use the chanSource to
    94  	// obtain any auxiliary information we need to craft a backup for each
    95  	// channel.
    96  	staticChanBackups := make([]Single, 0, len(openChans))
    97  	for _, openChan := range openChans {
    98  		chanBackup, err := assembleChanBackup(addrSource, openChan)
    99  		if err != nil {
   100  			return nil, err
   101  		}
   102  
   103  		staticChanBackups = append(staticChanBackups, *chanBackup)
   104  	}
   105  
   106  	return staticChanBackups, nil
   107  }