From 92a2ba163e3399a171488182804abf013aeab110 Mon Sep 17 00:00:00 2001 From: Conner Fromknecht Date: Mon, 26 Mar 2018 14:15:04 -0700 Subject: [PATCH] cmd/lncli/commands: ask for recovery window after restore seed --- cmd/lncli/commands.go | 64 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/cmd/lncli/commands.go b/cmd/lncli/commands.go index 4a1f3297..53abbc7c 100644 --- a/cmd/lncli/commands.go +++ b/cmd/lncli/commands.go @@ -35,6 +35,8 @@ import ( // TODO(roasbeef): expose all fee conf targets +const defaultRecoveryWindow int32 = 250 + func printJSON(resp interface{}) { b, err := json.Marshal(resp) if err != nil { @@ -1132,6 +1134,7 @@ mnemonicCheck: var ( cipherSeedMnemonic []string aezeedPass []byte + recoveryWindow int32 ) if hasMnemonic { // We'll now prompt the user to enter in their 24-word @@ -1170,7 +1173,37 @@ mnemonicCheck: aezeedPass = []byte(passphrase) - fmt.Println() + for { + fmt.Println() + fmt.Printf("Input an optional address look-ahead "+ + "used to scan for used keys (default %d): ", + defaultRecoveryWindow) + + reader := bufio.NewReader(os.Stdin) + answer, err := reader.ReadString('\n') + if err != nil { + return err + } + + fmt.Println() + + answer = strings.TrimSpace(answer) + + if len(answer) == 0 { + recoveryWindow = defaultRecoveryWindow + break + } + + lookAhead, err := strconv.Atoi(answer) + if err != nil { + fmt.Println("Unable to parse recovery "+ + "window: %v", err) + continue + } + + recoveryWindow = int32(lookAhead) + break + } } else { // Otherwise, if the user doesn't have a mnemonic that they // want to use, we'll generate a fresh one with the GenSeed @@ -1247,6 +1280,7 @@ mnemonicCheck: WalletPassword: pw1, CipherSeedMnemonic: cipherSeedMnemonic, AezeedPassphrase: aezeedPass, + RecoveryWindow: recoveryWindow, } if _, err := client.InitWallet(ctxb, req); err != nil { return err @@ -1265,6 +1299,16 @@ var unlockCommand = cli.Command{ able to carry out its duties. An exception is if a user is running with --noencryptwallet, then a default passphrase will be used. `, + Flags: []cli.Flag{ + cli.IntFlag{ + Name: "recovery_window", + Usage: "address lookahead to resume recovery rescan, " + + "value should be non-zero -- To recover all " + + "funds, this should be greater than the " + + "maximum number of consecutive, unused " + + "addresses ever generated by the wallet.", + }, + }, Action: actionDecorator(unlock), } @@ -1280,8 +1324,26 @@ func unlock(ctx *cli.Context) error { } fmt.Println() + 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 + // used. + var recoveryWindow int32 + switch { + case ctx.IsSet("recovery_window"): + recoveryWindow = int32(ctx.Int64("recovery_window")) + case args.Present(): + window, err := strconv.ParseInt(args.First(), 10, 64) + if err != nil { + return err + } + recoveryWindow = int32(window) + } + req := &lnrpc.UnlockWalletRequest{ WalletPassword: pw, + RecoveryWindow: recoveryWindow, } _, err = client.UnlockWallet(ctxb, req) if err != nil {