remove legacy store #34

Merged
roylee17 merged 1 commit from roylee/remove-legacy-store into master 2022-09-20 00:56:15 +02:00
8 changed files with 9 additions and 4719 deletions

View file

@ -21,7 +21,6 @@ import (
"github.com/lbryio/lbcd/version" "github.com/lbryio/lbcd/version"
btcutil "github.com/lbryio/lbcutil" btcutil "github.com/lbryio/lbcutil"
"github.com/lbryio/lbcwallet/internal/cfgutil" "github.com/lbryio/lbcwallet/internal/cfgutil"
"github.com/lbryio/lbcwallet/internal/legacy/keystore"
"github.com/lbryio/lbcwallet/netparams" "github.com/lbryio/lbcwallet/netparams"
"github.com/lbryio/lbcwallet/wallet" "github.com/lbryio/lbcwallet/wallet"
) )
@ -527,22 +526,6 @@ func loadConfig() (*config, []string, error) {
// Created successfully, so exit now with success. // Created successfully, so exit now with success.
os.Exit(0) os.Exit(0)
} else if !dbFileExists && !cfg.NoInitialLoad {
keystorePath := filepath.Join(netDir, keystore.Filename)
keystoreExists, err := cfgutil.FileExists(keystorePath)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return nil, nil, err
}
if !keystoreExists {
err = fmt.Errorf("the wallet does not exist, run with " +
"the --create option to initialize and create it")
} else {
err = fmt.Errorf("the wallet is in legacy format, run " +
"with the --create option to import it")
}
fmt.Fprintln(os.Stderr, err)
return nil, nil, err
} }
localhostListeners := map[string]struct{}{ localhostListeners := map[string]struct{}{

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,18 +0,0 @@
// Copyright (c) 2013-2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
//go:build !windows && !plan9
// +build !windows,!plan9
package rename
import (
"os"
)
// Atomic provides an atomic file rename. newpath is replaced if it
// already exists.
func Atomic(oldpath, newpath string) error {
return os.Rename(oldpath, newpath)
}

View file

@ -1,71 +0,0 @@
// The following is adapted from goleveldb
// (https://github.com/syndtr/goleveldb) under the following license:
//
// Copyright 2012 Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package rename
import (
"syscall"
"unsafe"
)
var (
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
procMoveFileExW = modkernel32.NewProc("MoveFileExW")
)
const (
_MOVEFILE_REPLACE_EXISTING = 1
)
func moveFileEx(from *uint16, to *uint16, flags uint32) error {
r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3,
uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)),
uintptr(flags))
if r1 == 0 {
if e1 != 0 {
return error(e1)
} else {
return syscall.EINVAL
}
}
return nil
}
// Atomic provides an atomic file rename. newpath is replaced if it
// already exists.
func Atomic(oldpath, newpath string) error {
from, err := syscall.UTF16PtrFromString(oldpath)
if err != nil {
return err
}
to, err := syscall.UTF16PtrFromString(newpath)
if err != nil {
return err
}
return moveFileEx(from, to, _MOVEFILE_REPLACE_EXISTING)
}

View file

@ -18,7 +18,6 @@ import (
"time" "time"
"github.com/lbryio/lbcutil/hdkeychain" "github.com/lbryio/lbcutil/hdkeychain"
"github.com/lbryio/lbcwallet/internal/legacy/keystore"
"golang.org/x/crypto/ssh/terminal" "golang.org/x/crypto/ssh/terminal"
) )
@ -192,47 +191,14 @@ func birthday(reader *bufio.Reader) (time.Time, error) {
return promptUnixTimestamp(reader, prompt, "0") return promptUnixTimestamp(reader, prompt, "0")
} }
// PrivatePass prompts the user for a private passphrase with varying behavior // PrivatePass prompts the user for a private passphrase. The user is prompted
// depending on whether the passed legacy keystore exists. When it does, the // for a new private passphrase. All prompts are repeated until the user
// user is prompted for the existing passphrase which is then used to unlock it. // enters a valid response.
// On the other hand, when the legacy keystore is nil, the user is prompted for func PrivatePass(reader *bufio.Reader) ([]byte, error) {
// a new private passphrase. All prompts are repeated until the user enters a
// valid response.
func PrivatePass(reader *bufio.Reader, legacyKeyStore *keystore.Store) ([]byte, error) {
// When there is not an existing legacy wallet, simply prompt the user
// for a new private passphase and return it.
if legacyKeyStore == nil {
return promptPass(reader, "Enter the private "+ return promptPass(reader, "Enter the private "+
"passphrase for your new wallet", true) "passphrase for your new wallet", true)
} }
// At this point, there is an existing legacy wallet, so prompt the user
// for the existing private passphrase and ensure it properly unlocks
// the legacy wallet so all of the addresses can later be imported.
fmt.Println("You have an existing legacy wallet. All addresses from " +
"your existing legacy wallet will be imported into the new " +
"wallet format.")
for {
privPass, err := promptPass(reader, "Enter the private "+
"passphrase for your existing wallet", false)
if err != nil {
return nil, err
}
// Keep prompting the user until the passphrase is correct.
if err := legacyKeyStore.Unlock(privPass); err != nil {
if err == keystore.ErrWrongPassphrase {
fmt.Println(err)
continue
}
return nil, err
}
return privPass, nil
}
}
// PublicPass prompts the user whether they want to add an additional layer of // PublicPass prompts the user whether they want to add an additional layer of
// encryption to the wallet. When the user answers yes and there is already a // encryption to the wallet. When the user answers yes and there is already a
// public passphrase provided via the passed config, it prompts them whether or // public passphrase provided via the passed config, it prompts them whether or

View file

@ -7,8 +7,6 @@ package prompt
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"github.com/lbryio/lbcwallet/internal/legacy/keystore"
) )
func ProvideSeed() ([]byte, error) { func ProvideSeed() ([]byte, error) {
@ -19,7 +17,7 @@ func ProvidePrivPassphrase() ([]byte, error) {
return nil, fmt.Errorf("prompt not supported in WebAssembly") return nil, fmt.Errorf("prompt not supported in WebAssembly")
} }
func PrivatePass(_ *bufio.Reader, _ *keystore.Store) ([]byte, error) { func PrivatePass(_ *bufio.Reader) ([]byte, error) {
return nil, fmt.Errorf("prompt not supported in WebAssembly") return nil, fmt.Errorf("prompt not supported in WebAssembly")
} }

View file

@ -13,10 +13,7 @@ import (
"github.com/lbryio/lbcd/chaincfg" "github.com/lbryio/lbcd/chaincfg"
"github.com/lbryio/lbcd/wire" "github.com/lbryio/lbcd/wire"
btcutil "github.com/lbryio/lbcutil"
"github.com/lbryio/lbcwallet/internal/legacy/keystore"
"github.com/lbryio/lbcwallet/internal/prompt" "github.com/lbryio/lbcwallet/internal/prompt"
"github.com/lbryio/lbcwallet/waddrmgr"
"github.com/lbryio/lbcwallet/wallet" "github.com/lbryio/lbcwallet/wallet"
"github.com/lbryio/lbcwallet/walletdb" "github.com/lbryio/lbcwallet/walletdb"
_ "github.com/lbryio/lbcwallet/walletdb/bdb" _ "github.com/lbryio/lbcwallet/walletdb/bdb"
@ -39,62 +36,6 @@ func networkDir(dataDir string, chainParams *chaincfg.Params) string {
return filepath.Join(dataDir, netname) return filepath.Join(dataDir, netname)
} }
// convertLegacyKeystore converts all of the addresses in the passed legacy
// key store to the new waddrmgr.Manager format. Both the legacy keystore and
// the new manager must be unlocked.
func convertLegacyKeystore(legacyKeyStore *keystore.Store, w *wallet.Wallet) {
netParams := legacyKeyStore.Net()
blockStamp := waddrmgr.BlockStamp{
Height: 0,
Hash: *netParams.GenesisHash,
}
for _, walletAddr := range legacyKeyStore.ActiveAddresses() {
switch addr := walletAddr.(type) {
case keystore.PubKeyAddress:
privKey, err := addr.PrivKey()
if err != nil {
fmt.Printf("WARN: Failed to obtain private key "+
"for address %v: %v\n", addr.Address(),
err)
continue
}
wif, err := btcutil.NewWIF(
privKey, netParams, addr.Compressed(),
)
if err != nil {
fmt.Printf("WARN: Failed to create wallet "+
"import format for address %v: %v\n",
addr.Address(), err)
continue
}
_, err = w.ImportPrivateKey(waddrmgr.KeyScopeBIP0044,
wif, &blockStamp, false)
if err != nil {
fmt.Printf("WARN: Failed to import private "+
"key for address %v: %v\n",
addr.Address(), err)
continue
}
case keystore.ScriptAddress:
_, err := w.ImportP2SHRedeemScript(addr.Script())
if err != nil {
fmt.Printf("WARN: Failed to import "+
"pay-to-script-hash script for "+
"address %v: %v\n", addr.Address(), err)
continue
}
default:
fmt.Printf("WARN: Skipping unrecognized legacy "+
"keystore type: %T\n", addr)
continue
}
}
}
// createWallet prompts the user for information needed to generate a new wallet // createWallet prompts the user for information needed to generate a new wallet
// and generates the wallet accordingly. The new wallet will reside at the // and generates the wallet accordingly. The new wallet will reside at the
// provided path. // provided path.
@ -104,72 +45,13 @@ func createWallet(cfg *config) error {
activeNet.Params, dbDir, true, cfg.DBTimeout, 250, activeNet.Params, dbDir, true, cfg.DBTimeout, 250,
) )
// When there is a legacy keystore, open it now to ensure any errors // Start by prompting for the private passphrase.
// don't end up exiting the process after the user has spent time
// entering a bunch of information.
netDir := networkDir(cfg.AppDataDir.Value, activeNet.Params)
keystorePath := filepath.Join(netDir, keystore.Filename)
var legacyKeyStore *keystore.Store
_, err := os.Stat(keystorePath)
if err != nil && !os.IsNotExist(err) {
// A stat error not due to a non-existent file should be
// returned to the caller.
return err
} else if err == nil {
// Keystore file exists.
legacyKeyStore, err = keystore.OpenDir(netDir)
if err != nil {
return err
}
}
// Start by prompting for the private passphrase. When there is an
// existing keystore, the user will be promped for that passphrase,
// otherwise they will be prompted for a new one.
reader := bufio.NewReader(os.Stdin) reader := bufio.NewReader(os.Stdin)
privPass, err := prompt.PrivatePass(reader, legacyKeyStore) privPass, err := prompt.PrivatePass(reader)
if err != nil { if err != nil {
return err return err
} }
// When there exists a legacy keystore, unlock it now and set up a
// callback to import all keystore keys into the new walletdb
// wallet
if legacyKeyStore != nil {
err = legacyKeyStore.Unlock(privPass)
if err != nil {
return err
}
// Import the addresses in the legacy keystore to the new wallet if
// any exist, locking each wallet again when finished.
loader.RunAfterLoad(func(w *wallet.Wallet) {
defer func() { _ = legacyKeyStore.Lock() }()
fmt.Println("Importing addresses from existing wallet...")
lockChan := make(chan time.Time, 1)
defer func() {
lockChan <- time.Time{}
}()
err := w.Unlock(privPass, lockChan)
if err != nil {
fmt.Printf("ERR: Failed to unlock new wallet "+
"during old wallet key import: %v", err)
return
}
convertLegacyKeystore(legacyKeyStore, w)
// Remove the legacy key store.
err = os.Remove(keystorePath)
if err != nil {
fmt.Printf("WARN: Failed to remove legacy wallet "+
"from'%s'\n", keystorePath)
}
})
}
// Ascertain the public passphrase. This will either be a value // Ascertain the public passphrase. This will either be a value
// specified by the user or the default hard-coded public passphrase if // specified by the user or the default hard-coded public passphrase if
// the user does not want the additional public data encryption. // the user does not want the additional public data encryption.