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 }