-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wallet Recovery #1005
Wallet Recovery #1005
Conversation
8ea431b
to
12d7fbe
Compare
Hey @cfromknecht, thanks for your work! Is this PR ready for testing? I'd like to try it. I have deleted a wallet and recovered it from the seed, but, of course, it didn't recover the funds. I'm ready to pull and compile this, how can I trigger the rescanning process? Or should I delete my wallet and restore again? (Using bitcoind, lnd currently @ master) |
0ecf7be
to
d99607c
Compare
Hey @zavan, yep this should be ready to start testing! Please note, this will only recover on-chain funds, so nothing regarding previous channels will be restored. I recommend restoring to a fresh directory, don't want to mangle any data you have currently. When doing Then, wait for the node to finish syncing and you should see your total balance. If the node crashes during recovery (or you kill the process), you should be able to restart the recovery by passing a non-zero Let me know how it goes :) |
FWIW, the recovery will probably take the longest when using the bitcoind backend. Currently, the logic fetches block in-order without prefetching. I have some prefetching code for btcwallet to speed that up. However, the complexity was upped a good bit because of it, so I'm gonna hold that off until a follow up PR. |
chainregistry.go
Outdated
// beginning of the bitcoin blockchain in case this wallet has yet to be | ||
// created. If the wallet has already been created, this value will be | ||
// ignored. | ||
if walletConfig.Birthday.IsZero() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would appreciate some feedback on the correct behavior here. Other alternatives seem to be using time.Now()
or just not do anything as it should be ignored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why just not keep it Zero
?
lnd.go
Outdated
@@ -832,12 +850,21 @@ func genMacaroons(ctx context.Context, svc *macaroons.Service, | |||
return nil | |||
} | |||
|
|||
type WalletInitParams struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add godoc comments
lnd_test.go
Outdated
AddrTypeNestedPubkeyHash = lnrpc.NewAddressRequest_NESTED_PUBKEY_HASH | ||
) | ||
|
||
// testOnchainFundRecovery |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fill in godoc comment
lntest/harness.go
Outdated
return node, nil | ||
} | ||
|
||
func (n *NetworkHarness) RegisterNode(node *HarnessNode) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add godoc comment
d99607c
to
2e01efc
Compare
privateWalletPw, publicWalletPw, err = waitForWalletPassword( | ||
cfg.RPCListeners, cfg.RESTListeners, serverOpts, proxyOpts, | ||
tlsConf, macaroonService, | ||
walletInitParams, err := waitForWalletPassword( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what will happen if --noencryptwallet
is specified? Atm I don't think we even give users a seed (hence they won't be able to recover the funds), but this is not very intuitive. We should probably let a user run with --noencryptwallet
and recover from a seed, or deprecate --noencryptwallet
(at least on mainnet).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah we don't have rescans for unencrypted wallets, because the users don't have seeds.
currently the recovery window is initialized as 0, and can only be set when --noencryptwallet
is not provided, so it will just sync as normal
cmd/lncli/commands.go
Outdated
if err != nil { | ||
fmt.Println("Unable to parse recovery "+ | ||
"window: %v", err) | ||
goto readRecoveryWindow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
continue
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
cmd/lncli/commands.go
Outdated
|
||
if len(answer) == 0 { | ||
recoveryWindow = defaultRecoveryWindow | ||
break readRecoveryWindow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just break
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
cmd/lncli/commands.go
Outdated
} | ||
|
||
recoveryWindow = int32(lookAhead) | ||
break readRecoveryWindow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
break
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
cmd/lncli/commands.go
Outdated
Flags: []cli.Flag{ | ||
cli.IntFlag{ | ||
Name: "recovery_window", | ||
Usage: "address lookahead for rescan", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not very clear if this will trigger a new rescan (from genesis?) if specified
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the wording to say that it will resume recovery and expand on how to properly set the value.
i guess it'd be worth also noting that this won't do anything if you're already synced, and that it's meant to be used to recover/restore onchain funds?
chainregistry.go
Outdated
// beginning of the bitcoin blockchain in case this wallet has yet to be | ||
// created. If the wallet has already been created, this value will be | ||
// ignored. | ||
if walletConfig.Birthday.IsZero() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why just not keep it Zero
?
82428f3
to
a8a077a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excited to finally get this in! Performed an initial review sweep, and didn't find anything fundemental. Will now move on to testing live with a few seeds from mainnet and testnet to ensure all funds are properly recovered.
} | ||
|
||
// Assert *HarnessNode implements the lnrpc.LightningClient interface. | ||
var _ lnrpc.LightningClient = (*HarnessNode)(nil) | ||
var _ lnrpc.WalletUnlockerClient = (*HarnessNode)(nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Needs rebase in order to trigger a fresh travis run on top of the latest changes. |
51cf084
to
6a9d641
Compare
args := ctx.Args() | ||
|
||
// Parse the optional recovery window if it is specified. By default, | ||
// the recovery window will be 0, indicating no lookahead should be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some places it says it should be non-zero, here it says it can be zero. What's correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Recovery window of 0 indicates no-lookahead, and no recovery will be attempted. 0 is a valid parameter, unless the user is actually trying to attempting to recover funds
lnd_test.go
Outdated
// First, create a new node with strong passphrase and grab the mnemonic | ||
// used for key derivation. This will bring up Carol with an empty | ||
// wallet, and such that she is synced up. | ||
password := []byte("topkek9000") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
password leak
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lol, didn't mean to expose you ;)
After latest rebase, tested again on multiple seeds on testnet, confirmed that all funds were recovered in full! Also confirmed that if the daemon is killed mid recovery, then a start with |
b06ac03
to
d9a9916
Compare
PR has been rebased on master and includes latest btcwallet updates and unit tests for 1-in-1-out spends. |
Still has a proto conflict. |
With the btcwallet PR merged, this should also update the dep files during rebase as well. |
b8c00fa
to
0c93cd4
Compare
PR has been rebased with latest btcwallet merge! Will ping when green |
0c93cd4
to
1ae3d4f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
⚡️⚡️LGTM ⚡️⚡️
Adds wallet recovery to lnd! These changes enable aezeeds with funds to be restored into a fresh instance, and recover any on-chain balance. Most of the rescan logic is implemented in Roasbeef/btcwallet#22, this PR involves most of the scaffolding to recovery configuration options into the wallet itself. I've added an integration test to test the recovery procedure using btcd, and I have manually tested bitcoind and neutrino.
Fixes #900