Separate keystore directory per multiacc

This commit provides `MigrateKeyStoreDir` method which moves multiacc's
keys from a common keystore directory to multiacc specific directory.
This commit is contained in:
Roman Volosovskyi 2020-06-22 15:03:28 +03:00
parent 157f20a7c8
commit 6d5a93287b
No known key found for this signature in database
GPG Key ID: 0238A4B5ECEE70DE
5 changed files with 117 additions and 1 deletions

View File

@ -1 +1 @@
0.55.0
0.55.1

View File

@ -417,3 +417,58 @@ func (m *Manager) unlockExtendedKey(address, password string) (*SelectedExtKey,
return selectedExtendedKey, nil
}
func (m *Manager) MigrateKeyStoreDir(oldDir, newDir string, addresses []string) error {
paths := []string{}
addressesMap := map[string]struct{}{}
for _, address := range addresses {
addressesMap[address] = struct{}{}
}
checkFile := func(path string, fileInfo os.FileInfo) error {
if fileInfo.IsDir() || filepath.Dir(path) != oldDir {
return nil
}
rawKeyFile, err := ioutil.ReadFile(path)
if err != nil {
return fmt.Errorf("invalid account key file: %v", err)
}
var accountKey struct {
Address string `json:"address"`
}
if err := json.Unmarshal(rawKeyFile, &accountKey); err != nil {
return fmt.Errorf("failed to read key file: %s", err)
}
address := types.HexToAddress("0x" + accountKey.Address).Hex()
if _, ok := addressesMap[address]; ok {
paths = append(paths, path)
}
return nil
}
err := filepath.Walk(oldDir, func(path string, fileInfo os.FileInfo, err error) error {
if err != nil {
return err
}
return checkFile(path, fileInfo)
})
if err != nil {
return fmt.Errorf("cannot traverse key store folder: %v", err)
}
for _, path := range paths {
_, fileName := filepath.Split(path)
newPath := filepath.Join(newDir, fileName)
err := os.Rename(path, newPath)
if err != nil {
return err
}
}
return nil
}

View File

@ -330,3 +330,21 @@ func (s *ManagerTestSuite) testAddressToDecryptedAccount(wallet, password string
s.Equal(acc.Address, key.Address)
}
}
func (s *ManagerTestSuite) TestMigrateKeyStoreDir() {
oldKeyDir := s.keydir
newKeyDir := filepath.Join(oldKeyDir, "new_dir")
err := os.Mkdir(newKeyDir, 0777)
s.Require().NoError(err)
files, _ := ioutil.ReadDir(newKeyDir)
s.Equal(0, len(files))
address := types.HexToAddress(s.walletAddress).Hex()
addresses := []string{address}
err = s.accManager.MigrateKeyStoreDir(oldKeyDir, newKeyDir, addresses)
s.Require().NoError(err)
files, _ = ioutil.ReadDir(newKeyDir)
s.Equal(1, len(files))
}

View File

@ -305,6 +305,33 @@ func (b *GethStatusBackend) startNodeWithAccount(acc multiaccounts.Account, pass
return nil
}
func (b *GethStatusBackend) MigrateKeyStoreDir(acc multiaccounts.Account, password, oldDir, newDir string) error {
err := b.ensureAppDBOpened(acc, password)
if err != nil {
return err
}
accountDB := accounts.NewDB(b.appDB)
accounts, err := accountDB.GetAccounts()
if err != nil {
return err
}
settings, err := accountDB.GetSettings()
if err != nil {
return err
}
addresses := []string{settings.EIP1581Address.Hex(), settings.WalletRootAddress.Hex()}
for _, account := range accounts {
addresses = append(addresses, account.Address.Hex())
}
err = b.accountManager.MigrateKeyStoreDir(oldDir, newDir, addresses)
if err != nil {
return err
}
return nil
}
func (b *GethStatusBackend) StartNodeWithAccount(acc multiaccounts.Account, password string) error {
err := b.startNodeWithAccount(acc, password)
if err != nil {

View File

@ -271,6 +271,22 @@ func VerifyAccountPassword(keyStoreDir, address, password string) string {
return makeJSONResponse(err)
}
// MigrateKeyStoreDir migrates key files to a new directory
func MigrateKeyStoreDir(accountData, password, oldDir, newDir string) string {
var account multiaccounts.Account
err := json.Unmarshal([]byte(accountData), &account)
if err != nil {
return makeJSONResponse(err)
}
err = statusBackend.MigrateKeyStoreDir(account, password, oldDir, newDir)
if err != nil {
return makeJSONResponse(err)
}
return makeJSONResponse(nil)
}
// Login loads a key file (for a given address), tries to decrypt it using the password,
// to verify ownership if verified, purges all the previous identities from Whisper,
// and injects verified key as shh identity.