walletunlock: exend the Init and Unlock methods to also return optional SCB's
In this commit, we we extend the Init and Unlock methods to also parse out and return optional SCB instances. With this change, when the user creates their node, if they have an existing seed and also a set of SCBs (either single or multi), they'll be able to recover both their on-chain balance, and also any funds that were settled within their existing channels.
This commit is contained in:
parent
da3625fc02
commit
f0e9a1f753
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/btcsuite/btcd/chaincfg"
|
"github.com/btcsuite/btcd/chaincfg"
|
||||||
"github.com/btcsuite/btcwallet/wallet"
|
"github.com/btcsuite/btcwallet/wallet"
|
||||||
"github.com/lightningnetwork/lnd/aezeed"
|
"github.com/lightningnetwork/lnd/aezeed"
|
||||||
|
"github.com/lightningnetwork/lnd/chanbackup"
|
||||||
"github.com/lightningnetwork/lnd/keychain"
|
"github.com/lightningnetwork/lnd/keychain"
|
||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
@ -17,6 +18,19 @@ import (
|
|||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ChannelsToRecover wraps any set of packed (serialized+encrypted) channel
|
||||||
|
// back ups together. These can be passed in when unlocking the wallet, or
|
||||||
|
// creating a new wallet for the first time with an existing seed.
|
||||||
|
type ChannelsToRecover struct {
|
||||||
|
// PackedMultiChanBackup is an encrypted and serialized multi-channel
|
||||||
|
// backup.
|
||||||
|
PackedMultiChanBackup chanbackup.PackedMulti
|
||||||
|
|
||||||
|
// PackedSingleChanBackups is a series of encrypted and serialized
|
||||||
|
// single-channel backup for one or more channels.
|
||||||
|
PackedSingleChanBackups chanbackup.PackedSingles
|
||||||
|
}
|
||||||
|
|
||||||
// WalletInitMsg is a message sent by the UnlockerService when a user wishes to
|
// WalletInitMsg is a message sent by the UnlockerService when a user wishes to
|
||||||
// set up the internal wallet for the first time. The user MUST provide a
|
// set up the internal wallet for the first time. The user MUST provide a
|
||||||
// passphrase, but is also able to provide their own source of entropy. If
|
// passphrase, but is also able to provide their own source of entropy. If
|
||||||
@ -36,6 +50,10 @@ type WalletInitMsg struct {
|
|||||||
// recovery should be attempted, such as after the wallet's initial
|
// recovery should be attempted, such as after the wallet's initial
|
||||||
// creation.
|
// creation.
|
||||||
RecoveryWindow uint32
|
RecoveryWindow uint32
|
||||||
|
|
||||||
|
// ChanBackups a set of static channel backups that should be received
|
||||||
|
// after the wallet has been initialized.
|
||||||
|
ChanBackups ChannelsToRecover
|
||||||
}
|
}
|
||||||
|
|
||||||
// WalletUnlockMsg is a message sent by the UnlockerService when a user wishes
|
// WalletUnlockMsg is a message sent by the UnlockerService when a user wishes
|
||||||
@ -53,12 +71,16 @@ type WalletUnlockMsg struct {
|
|||||||
// creation, but before any addresses have been created.
|
// creation, but before any addresses have been created.
|
||||||
RecoveryWindow uint32
|
RecoveryWindow uint32
|
||||||
|
|
||||||
// Wallet is the loaded and unlocked Wallet. This is returned
|
// Wallet is the loaded and unlocked Wallet. This is returned through
|
||||||
// through the channel to avoid it being unlocked twice (once to check
|
// the channel to avoid it being unlocked twice (once to check if the
|
||||||
// if the password is correct, here in the WalletUnlocker and again
|
// password is correct, here in the WalletUnlocker and again later when
|
||||||
// later when lnd actually uses it). Because unlocking involves scrypt
|
// lnd actually uses it). Because unlocking involves scrypt which is
|
||||||
// which is resource intensive, we want to avoid doing it twice.
|
// resource intensive, we want to avoid doing it twice.
|
||||||
Wallet *wallet.Wallet
|
Wallet *wallet.Wallet
|
||||||
|
|
||||||
|
// ChanBackups a set of static channel backups that should be received
|
||||||
|
// after the wallet has been unlocked.
|
||||||
|
ChanBackups ChannelsToRecover
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnlockerService implements the WalletUnlocker service used to provide lnd
|
// UnlockerService implements the WalletUnlocker service used to provide lnd
|
||||||
@ -167,6 +189,43 @@ func (u *UnlockerService) GenSeed(ctx context.Context,
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extractChanBackups is a helper function that extracts the set of channel
|
||||||
|
// backups from the proto into a format that we'll pass to higher level
|
||||||
|
// sub-systems.
|
||||||
|
func extractChanBackups(chanBackups *lnrpc.ChanBackupSnapshot) *ChannelsToRecover {
|
||||||
|
// If there aren't any populated channel backups, then we can exit
|
||||||
|
// early as there's nothing to extract.
|
||||||
|
if chanBackups == nil || (chanBackups.SingleChanBackups == nil &&
|
||||||
|
chanBackups.MultiChanBackup == nil) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now that we know there's at least a single back up populated, we'll
|
||||||
|
// extract the multi-chan backup (if it's there).
|
||||||
|
var backups ChannelsToRecover
|
||||||
|
if chanBackups.MultiChanBackup != nil {
|
||||||
|
multiBackup := chanBackups.MultiChanBackup
|
||||||
|
backups.PackedMultiChanBackup = chanbackup.PackedMulti(
|
||||||
|
multiBackup.MultiChanBackup,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if chanBackups.SingleChanBackups == nil {
|
||||||
|
return &backups
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, we can extract all the single chan backups as well.
|
||||||
|
for _, backup := range chanBackups.SingleChanBackups.ChanBackups {
|
||||||
|
singleChanBackup := backup.ChanBackup
|
||||||
|
|
||||||
|
backups.PackedSingleChanBackups = append(
|
||||||
|
backups.PackedSingleChanBackups, singleChanBackup,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &backups
|
||||||
|
}
|
||||||
|
|
||||||
// InitWallet is used when lnd is starting up for the first time to fully
|
// InitWallet is used when lnd is starting up for the first time to fully
|
||||||
// initialize the daemon and its internal wallet. At the very least a wallet
|
// initialize the daemon and its internal wallet. At the very least a wallet
|
||||||
// password must be provided. This will be used to encrypt sensitive material
|
// password must be provided. This will be used to encrypt sensitive material
|
||||||
@ -233,6 +292,13 @@ func (u *UnlockerService) InitWallet(ctx context.Context,
|
|||||||
RecoveryWindow: uint32(recoveryWindow),
|
RecoveryWindow: uint32(recoveryWindow),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Before we return the unlock payload, we'll check if we can extract
|
||||||
|
// any channel backups to pass up to the higher level sub-system.
|
||||||
|
chansToRestore := extractChanBackups(in.ChannelBackups)
|
||||||
|
if chansToRestore != nil {
|
||||||
|
initMsg.ChanBackups = *chansToRestore
|
||||||
|
}
|
||||||
|
|
||||||
u.InitMsgs <- initMsg
|
u.InitMsgs <- initMsg
|
||||||
|
|
||||||
return &lnrpc.InitWalletResponse{}, nil
|
return &lnrpc.InitWalletResponse{}, nil
|
||||||
@ -277,6 +343,13 @@ func (u *UnlockerService) UnlockWallet(ctx context.Context,
|
|||||||
Wallet: unlockedWallet,
|
Wallet: unlockedWallet,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Before we return the unlock payload, we'll check if we can extract
|
||||||
|
// any channel backups to pass up to the higher level sub-system.
|
||||||
|
chansToRestore := extractChanBackups(in.ChannelBackups)
|
||||||
|
if chansToRestore != nil {
|
||||||
|
walletUnlockMsg.ChanBackups = *chansToRestore
|
||||||
|
}
|
||||||
|
|
||||||
// At this point we was able to open the existing wallet with the
|
// At this point we was able to open the existing wallet with the
|
||||||
// provided password. We send the password over the UnlockMsgs
|
// provided password. We send the password over the UnlockMsgs
|
||||||
// channel, such that it can be used by lnd to open the wallet.
|
// channel, such that it can be used by lnd to open the wallet.
|
||||||
|
Loading…
Reference in New Issue
Block a user