Skip to content

Commit

Permalink
use badgerdb on mobile devices (#698)
Browse files Browse the repository at this point in the history
* use badgerdb on mobile devices

* upgrade mobile wallets db to badgerbd

* reload page after clearing db

* add migrate screen

---------

Co-authored-by: bugjt <@bugjt>
  • Loading branch information
dreacot authored Jan 23, 2025
1 parent dde2be2 commit 6c028eb
Show file tree
Hide file tree
Showing 13 changed files with 558 additions and 12 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ require (
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/yeqown/reedsolomon v1.0.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
github.com/zquestz/grab v0.0.0-20190224022517-abcee96e61b1 // indirect
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
golang.org/x/net v0.28.0 // indirect
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,7 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
Expand Down Expand Up @@ -1449,6 +1450,8 @@ github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAx
github.com/shirou/gopsutil v0.0.0-20180427012116-c95755e4bcd7/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU=
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil/v3 v3.21.4/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
Expand Down Expand Up @@ -1612,6 +1615,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/zquestz/grab v0.0.0-20190224022517-abcee96e61b1 h1:1qKTeMTSIEvRIjvVYzgcRp0xVp0eoiRTTiHSncb5gD8=
github.com/zquestz/grab v0.0.0-20190224022517-abcee96e61b1/go.mod h1:bslhAiUxakrA6z6CHmVyvkfpnxx18RJBwVyx2TluJWw=
go.etcd.io/bbolt v1.3.0/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
Expand Down
1 change: 1 addition & 0 deletions libwallet/assets/wallet/asset_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type Asset interface {
DecryptSeed(privatePassphrase string) (string, error)
VerifySeedForWallet(seedMnemonic, privpass string) (bool, error)
ChangePrivatePassphraseForWallet(oldPrivatePassphrase, newPrivatePassphrase string, privatePassphraseType int32) error
GetPrivatePassphraseType() int32

RootDir() string
DataDir() string
Expand Down
1 change: 1 addition & 0 deletions libwallet/assets/wallet/wallet_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const (
DarkModeConfigKey = "dark_mode"
HideTotalBalanceConfigKey = "hideTotalUSDBalance"
IsCEXFirstVisitConfigKey = "is_cex_first_visit"
DBDriverConfigKey = "db_driver"

PassphraseTypePin int32 = 0
PassphraseTypePass int32 = 1
Expand Down
7 changes: 7 additions & 0 deletions libwallet/assets/wallet/wallet_shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,13 @@ func (wallet *Wallet) GetAssetType() utils.AssetType {
return wallet.Type
}

// GetPrivatePassphraseType returns the current wallet's private passphrase type.
func (wallet *Wallet) GetPrivatePassphraseType() int32 {
wallet.mu.RLock()
defer wallet.mu.RUnlock()
return wallet.PrivatePassphraseType
}

// Internal return the upstream wallet of the current asset created in the loader
// package. Since its exported via the interface thus the need to be thread safe.
func (wallet *Wallet) Internal() *loader.LoadedWallets {
Expand Down
16 changes: 16 additions & 0 deletions libwallet/assets_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,3 +296,19 @@ func (mgr *AssetsManager) SetTotalBalanceVisibility(data bool) {
func genKey(prefix, identifier interface{}) string {
return fmt.Sprintf("%v-%v", prefix, identifier)
}

// GetDBDriver returns the saved db driver.
func (mgr *AssetsManager) GetDBDriver() string {
var dbDriver string
mgr.ReadAppConfigValue(sharedW.DBDriverConfigKey, &dbDriver)
if dbDriver == "" {
// return default db driver if no option is stored.
return BoltDB
}
return dbDriver
}

// SetDBDriver sets the db driver.
func (mgr *AssetsManager) SetDBDriver(dbDriver string) {
mgr.SaveAppConfigValue(sharedW.DBDriverConfigKey, dbDriver)
}
74 changes: 71 additions & 3 deletions libwallet/assets_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ const LogFilename = "cryptopower.log"
// assetIdentifier use for listen balance of all wallet changed
const assetIdentifier = "assets_manager"

const BoltDB = "bdb" // Bolt db driver
const BadgerDB = "badgerdb" // Badger db driver

// Assets is a struct that holds all the assets supported by the wallet.
type Assets struct {
DCR struct {
Expand Down Expand Up @@ -78,6 +81,8 @@ type AssetsManager struct {

//TODO: some time need show message for user. Change it if has other solution
toast *notification.Toast

NeedMigrate bool
}

// initializeAssetsFields validate the network provided is valid for all assets before proceeding
Expand Down Expand Up @@ -128,18 +133,49 @@ func initializeAssetsFields(rootDir, dbDriver, logDir string, netType utils.Netw
return mgr, nil
}

func fileExists(filePath string) bool {
_, err := os.Stat(filePath)
if err != nil {
if os.IsNotExist(err) {
return false
}
return false
}
return true
}

// NewAssetsManager creates a new AssetsManager instance.
func NewAssetsManager(rootDir, logDir string, netType utils.NetworkType, dexTestAddr string) (*AssetsManager, error) {
errors.Separator = ":: "
needMigrate := false
isMobile := appos.Current().IsMobile()

dbDriver := BoltDB
if isMobile {
dbDriver = BadgerDB
}

if fileExists(filepath.Join(rootDir, fmt.Sprintf("%s-%s", string(netType), dbDriver))) {
// New db
rootDir = filepath.Join(rootDir, fmt.Sprintf("%s-%s", string(netType), dbDriver))
} else if fileExists(filepath.Join(rootDir, string(netType))) {
// old db
dbDriver = BoltDB
rootDir = filepath.Join(rootDir, string(netType))
needMigrate = isMobile
} else {
// db is not exist, create new
rootDir = filepath.Join(rootDir, fmt.Sprintf("%s-%s", string(netType), dbDriver))

}

// Create a root dir that has the path up the network folder.
rootDir = filepath.Join(rootDir, string(netType))
if err := os.MkdirAll(rootDir, utils.UserFilePerm); err != nil {
return nil, errors.Errorf("failed to create rootDir: %v", err)
}

// validate the network type before proceeding to initialize the othe fields.
dbDriver := "bdb" // TODO: Should be a constant.

mgr, err := initializeAssetsFields(rootDir, dbDriver, logDir, netType, dexTestAddr)
if err != nil {
return nil, err
Expand Down Expand Up @@ -206,13 +242,28 @@ func NewAssetsManager(rootDir, logDir string, netType utils.NetworkType, dexTest
}

mgr.listenForShutdown()

mgr.NeedMigrate = needMigrate
return mgr, nil
}

func (mgr *AssetsManager) RemoveRootDir() error {
err := os.RemoveAll(mgr.params.RootDir)
if err != nil {
return err
}
err = os.RemoveAll(mgr.params.LogDir)
if err != nil {
return err
}
return nil
}

func (mgr *AssetsManager) RootDir() string {
return mgr.params.RootDir
}
func (mgr *AssetsManager) ParamLogDir() string {
return mgr.params.LogDir
}

func (mgr *AssetsManager) SetToast(toast *notification.Toast) {
mgr.toast = toast
Expand Down Expand Up @@ -390,6 +441,15 @@ func (mgr *AssetsManager) LogDir() string {
return filepath.Join(mgr.params.RootDir, logFileName)
}

func (mgr *AssetsManager) DEXTestAddr() string {
return mgr.params.DEXTestAddr
}

// DBDriver returns the db driver in use
func (mgr *AssetsManager) DBDriver() string {
return mgr.params.DbDriver
}

// OpenWallets opens all wallets in the assets manager.
func (mgr *AssetsManager) OpenWallets(startupPassphrase string) error {
for _, wallet := range mgr.AllWallets() {
Expand Down Expand Up @@ -1022,3 +1082,11 @@ func (mgr *AssetsManager) RemoveAssetChange() {
// Remove listener on rate notification
mgr.RateSource.RemoveRateListener(assetIdentifier)
}

func (mgr *AssetsManager) BadgerDB() string {
return BadgerDB
}

func (mgr *AssetsManager) BoltDB() string {
return BoltDB
}
115 changes: 115 additions & 0 deletions libwallet/wallet_migrator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package libwallet

import (
sharedW "github.com/crypto-power/cryptopower/libwallet/assets/wallet"
libutils "github.com/crypto-power/cryptopower/libwallet/utils"
)

type WalletMigrator struct {
wallet sharedW.Asset
privatePassphrase string
seed string
isMigrate bool
}

func NewWalletMigrator(wallet sharedW.Asset) *WalletMigrator {
return &WalletMigrator{
wallet: wallet,
}
}

func (wm *WalletMigrator) GetIsMigrate() bool {
return wm.isMigrate
}

func (wm *WalletMigrator) SetIsMigrate(isMigrate bool) {
wm.isMigrate = isMigrate
}

func (wm *WalletMigrator) GetAssetType() libutils.AssetType {
return wm.wallet.GetAssetType()
}

func (wm *WalletMigrator) GetWalletName() string {
return wm.wallet.GetWalletName()
}

func (wm *WalletMigrator) IsWatchingOnlyWallet() bool {
return wm.wallet.IsWatchingOnlyWallet()
}

func (wm *WalletMigrator) SetPrivatePassphrase(privatePassphrase string) error {
seed, err := wm.wallet.DecryptSeed(privatePassphrase)
if err != nil {
return err
}

wm.privatePassphrase = privatePassphrase
wm.seed = seed
wm.isMigrate = true
return nil
}

func (wm *WalletMigrator) SetSeed(seed string) error {
wm.seed = seed
wm.isMigrate = true
return nil
}

func (wm *WalletMigrator) Migrate(mgr *AssetsManager) error {
if !wm.isMigrate {
return nil
}

if wm.wallet.IsWatchingOnlyWallet() {
return wm.migrateWatchingOnlyWallet(mgr)
}
var err error
switch wm.wallet.GetAssetType() {
case libutils.DCRWalletAsset:
_, err = mgr.RestoreDCRWallet(wm.wallet.GetWalletName(), wm.seed, wm.privatePassphrase, sharedW.WordSeedType(wm.wallet.GetPrivatePassphraseType()), wm.wallet.GetPrivatePassphraseType())
if err != nil {
return err
}

case libutils.BTCWalletAsset:
_, err = mgr.RestoreBTCWallet(wm.wallet.GetWalletName(), wm.seed, wm.privatePassphrase, sharedW.WordSeedType(wm.wallet.GetPrivatePassphraseType()), wm.wallet.GetPrivatePassphraseType())
if err != nil {
return err
}

case libutils.LTCWalletAsset:
_, err = mgr.RestoreLTCWallet(wm.wallet.GetWalletName(), wm.seed, wm.privatePassphrase, sharedW.WordSeedType(wm.wallet.GetPrivatePassphraseType()), wm.wallet.GetPrivatePassphraseType())
if err != nil {
return err
}
}
return nil
}

func (wm *WalletMigrator) migrateWatchingOnlyWallet(mgr *AssetsManager) error {
if !wm.isMigrate {
return nil
}
switch wm.wallet.GetAssetType() {
case libutils.DCRWalletAsset:
_, err := mgr.CreateNewDCRWatchOnlyWallet(wm.wallet.GetWalletName(), wm.seed)
if err != nil {
return err
}

case libutils.BTCWalletAsset:
_, err := mgr.CreateNewBTCWatchOnlyWallet(wm.wallet.GetWalletName(), wm.seed)
if err != nil {
return err
}

case libutils.LTCWalletAsset:
_, err := mgr.CreateNewLTCWatchOnlyWallet(wm.wallet.GetWalletName(), wm.seed)
if err != nil {
return err
}

}
return nil
}
Loading

0 comments on commit 6c028eb

Please sign in to comment.