Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
Signed-off-by: Philemon Ukane <[email protected]>
  • Loading branch information
ukane-philemon committed Dec 22, 2023
1 parent 25d80b5 commit b907c46
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 152 deletions.
14 changes: 9 additions & 5 deletions dexc/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@ const (
// CustomDexWalletType is a keyword that identifies a custom Cryptopower
// wallet used by the DEX client.
CustomDexWalletType = "cryptopowerwallet"
// DexWalletIDConfigKey is the key that holds the wallet ID value in the
// WalletIDConfigKey is the key that holds the wallet ID value in the
// settings map used to connect an existing Cryptopower wallet to the DEX
// client.
DexWalletIDConfigKey = "walletid"
// DexDcrWalletAccountNameConfigKey is the key that holds the wallet account
// values in the settings map used to connect an existing dcr wallet to the
WalletIDConfigKey = "walletid"
// WalletAccountNameConfigKey is the key that holds the wallet account name
// in the settings map used to connect an existing Cryptopower wallet to the
// DEX client.
DexDcrWalletAccountNameConfigKey = "account"
WalletAccountNameConfigKey = "account"
// WalletAccountNumberConfigKey is the key that holds the wallet account
// number in the settings map used to connect an existing Cryptopower wallet
// to the DEX client.
WalletAccountNumberConfigKey = "accountnumber"
)

// DEXClient represents the Decred DEX client and embeds *core.Core.
Expand Down
118 changes: 84 additions & 34 deletions libwallet/assets/btc/dex-wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,58 @@ import (
dexbtc "decred.org/dcrdex/client/asset/btc"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/btcutil/gcs"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcwallet/chain"
"github.com/btcsuite/btcwallet/waddrmgr"
"github.com/btcsuite/btcwallet/wallet"
"github.com/btcsuite/btcwallet/wallet/txauthor"
"github.com/btcsuite/btcwallet/wtxmgr"
"github.com/lightninglabs/neutrino"
"github.com/lightninglabs/neutrino/headerfs"
)

// DEXWallet wraps *wallet.Wallet and implements dexbtc.BTCWallet.
type DEXWallet struct {
*wallet.Wallet // Implements most of dexbtc.BTCWallet
asset *Asset
*wallet.Wallet
acct dexbtc.XCWalletAccount
spvService *btcChainService
}

var _ dexbtc.BTCWallet = (*DEXWallet)(nil)

// NewDEXWallet returns a new *DEXWallet.
func NewDEXWallet(asset *Asset) *DEXWallet {
func NewDEXWallet(acct dexbtc.XCWalletAccount, w *wallet.Wallet, nc *chain.NeutrinoClient) *DEXWallet {
return &DEXWallet{
Wallet: asset.Internal().BTC,
asset: asset,
Wallet: w,
acct: acct,
spvService: &btcChainService{
NeutrinoClient: nc,
},
}
}

// The below methods are not implemented by *wallet.Wallet, so must be
// implemented by the BTCWallet implementation.

func (dw *DEXWallet) Start() (dexbtc.SPVService, error) {
return dw.spvService, nil
}

func (dw *DEXWallet) Birthday() time.Time {
return dw.Manager.Birthday()
}

func (dw *DEXWallet) SyncedTo() waddrmgr.BlockStamp {
return dw.Wallet.Manager.SyncedTo()
}

func (dw *DEXWallet) AccountInfo() dexbtc.XCWalletAccount {
return dw.acct
}

func (dw *DEXWallet) WalletTransaction(txHash *chainhash.Hash) (*wtxmgr.TxDetails, error) {
details, err := wallet.UnstableAPI(dw.Wallet).TxDetails(txHash)
if err != nil {
Expand All @@ -56,10 +80,6 @@ func (dw *DEXWallet) WalletTransaction(txHash *chainhash.Hash) (*wtxmgr.TxDetail
return details, nil
}

func (dw *DEXWallet) SyncedTo() waddrmgr.BlockStamp {
return dw.Wallet.Manager.SyncedTo()
}

func (dw *DEXWallet) SignTx(tx *wire.MsgTx) error {
var prevPkScripts [][]byte
var inputValues []btcutil.Amount
Expand Down Expand Up @@ -104,28 +124,8 @@ func (dw *DEXWallet) BlockNotifications(ctx context.Context) <-chan *dexbtc.Bloc
return ch
}

func (dw *DEXWallet) RescanAsync() error {
return dw.asset.rescanAsync()
}

func (dw *DEXWallet) ForceRescan() {
dw.asset.forceRescan()
}

func (dw *DEXWallet) Start() (dexbtc.SPVService, error) {
return dw.asset.chainClient, nil
}

func (dw *DEXWallet) Reconfigure(*asset.WalletConfig, string) (bool, error) {
return false, errors.New("Reconfigure not supported for Cyptopower btc wallet")
}

func (dw *DEXWallet) Birthday() time.Time {
return dw.Manager.Birthday()
}

func (dw *DEXWallet) Peers() ([]*asset.WalletPeer, error) {
peers := dw.asset.chainClient.CS.Peers()
peers := dw.spvService.CS.Peers()
var walletPeers []*asset.WalletPeer
for i := range peers {
p := peers[i]
Expand All @@ -139,13 +139,63 @@ func (dw *DEXWallet) Peers() ([]*asset.WalletPeer, error) {
}

func (dw *DEXWallet) AddPeer(address string) error {
dw.asset.SetSpecificPeer(address)
return nil
return errors.New("AddPeer not implemented by DEX wallet")
}

func (dw *DEXWallet) RemovePeer(address string) error {
dw.asset.RemoveSpecificPeer(address)
return nil
return errors.New("RemovePeer not implemented by DEX wallet")
}

func (dw *DEXWallet) RescanAsync() error {
return errors.New("RescanAsync not implemented for Cyptopower btc wallet")
}

func (dw *DEXWallet) ForceRescan() {}

func (dw *DEXWallet) Reconfigure(*asset.WalletConfig, string) (bool, error) {
return false, errors.New("Reconfigure not supported for Cyptopower btc wallet")
}

// btcChainService wraps *chain.NeutrinoClient in order to translate the
// neutrino.ServerPeer to the SPVPeer interface type as required by the dex btc
// pkg.
type btcChainService struct {
*chain.NeutrinoClient
}

var _ dexbtc.SPVService = (*btcChainService)(nil)

func (s *btcChainService) Peers() []dexbtc.SPVPeer {
rawPeers := s.CS.Peers()
peers := make([]dexbtc.SPVPeer, 0, len(rawPeers))
for _, p := range rawPeers {
peers = append(peers, p)
}
return peers
}

func (s *btcChainService) AddPeer(addr string) error {
return s.CS.ConnectNode(addr, true)
}

func (s *btcChainService) RemovePeer(addr string) error {
return s.CS.RemoveNodeByAddr(addr)
}

func (s *btcChainService) BestBlock() (*headerfs.BlockStamp, error) {
return s.CS.BestBlock()
}

func (s *btcChainService) GetBlock(blockHash chainhash.Hash, options ...neutrino.QueryOption) (*btcutil.Block, error) {
return s.CS.GetBlock(blockHash, options...)
}

func (s *btcChainService) GetCFilter(blockHash chainhash.Hash, filterType wire.FilterType, options ...neutrino.QueryOption) (*gcs.Filter, error) {
return s.NeutrinoClient.CS.GetCFilter(blockHash, filterType, options...)
}

func (s *btcChainService) Stop() error {
return s.CS.Stop()
}

// secretSource is used to locate keys and redemption scripts while signing a
Expand Down
4 changes: 2 additions & 2 deletions libwallet/assets/btc/rescan.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func (asset *Asset) rescanAsync() error {
}

log.Infof("Synchronizing wallet (%s) with network...", asset.GetWalletName())
asset.Internal().BTC.SynchronizeRPC(asset.chainClient.NeutrinoClient)
asset.Internal().BTC.SynchronizeRPC(asset.chainClient)
return nil
}

Expand Down Expand Up @@ -379,7 +379,7 @@ func (asset *Asset) getblockStamp(height int32) (*waddrmgr.BlockStamp, error) {
return nil, fmt.Errorf("invalid block height provided: Error: %v", err)
}

block, err := asset.chainClient.NeutrinoClient.GetBlock(startHash)
block, err := asset.chainClient.GetBlock(startHash)
if err != nil {
return nil, fmt.Errorf("invalid block hash provided: Error: %v", err)
}
Expand Down
6 changes: 2 additions & 4 deletions libwallet/assets/btc/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,9 +343,7 @@ func (asset *Asset) prepareChain() error {
return err
}

asset.chainClient = &btcChainService{
NeutrinoClient: chain.NewNeutrinoClient(asset.chainParams, chainService),
}
asset.chainClient = chain.NewNeutrinoClient(asset.chainParams, chainService)

return nil
}
Expand Down Expand Up @@ -512,7 +510,7 @@ func (asset *Asset) startSync() error {

log.Infof("Synchronizing wallet (%s) with network...", asset.GetWalletName())
// Initializes the goroutines handling chain notifications, rescan progress and handlers.
asset.Internal().BTC.SynchronizeRPC(asset.chainClient.NeutrinoClient)
asset.Internal().BTC.SynchronizeRPC(asset.chainClient)

select {
// Wait for 5 seconds so that all goroutines initialized in SynchronizeRPC()
Expand Down
94 changes: 21 additions & 73 deletions libwallet/assets/btc/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"sync"
"time"

dexbtc "decred.org/dcrdex/client/asset/btc"
"decred.org/dcrwallet/v3/errors"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/btcsuite/btcd/btcutil"
Expand Down Expand Up @@ -38,7 +37,7 @@ var _ sharedW.Asset = (*Asset)(nil)
type Asset struct {
*sharedW.Wallet

chainClient *btcChainService
chainClient *chain.NeutrinoClient
chainParams *chaincfg.Params
TxAuthoredInfo *TxAuthor

Expand Down Expand Up @@ -74,47 +73,19 @@ const (
defaultDBTimeout = time.Duration(100)
)

// btcChainService wraps *chain.NeutrinoClient in order to translate the
// neutrino.ServerPeer to the SPVPeer interface type as required by the dex btc
// pkg.
type btcChainService struct {
*chain.NeutrinoClient
// neutrinoService is satisfied by *neutrino.ChainService.
type neutrinoService interface {
GetBlockHash(int64) (*chainhash.Hash, error)
BestBlock() (*headerfs.BlockStamp, error)
Peers() []*neutrino.ServerPeer
GetBlockHeight(hash *chainhash.Hash) (int32, error)
GetBlockHeader(*chainhash.Hash) (*wire.BlockHeader, error)
GetCFilter(blockHash chainhash.Hash, filterType wire.FilterType, options ...neutrino.QueryOption) (*gcs.Filter, error)
GetBlock(blockHash chainhash.Hash, options ...neutrino.QueryOption) (*btcutil.Block, error)
Stop() error
}

func (s *btcChainService) Peers() []dexbtc.SPVPeer {
rawPeers := s.CS.Peers()
peers := make([]dexbtc.SPVPeer, 0, len(rawPeers))
for _, p := range rawPeers {
peers = append(peers, p)
}
return peers
}

func (s *btcChainService) AddPeer(addr string) error {
return s.CS.ConnectNode(addr, true)
}

func (s *btcChainService) RemovePeer(addr string) error {
return s.CS.RemoveNodeByAddr(addr)
}

func (s *btcChainService) BestBlock() (*headerfs.BlockStamp, error) {
return s.NeutrinoClient.CS.BestBlock()
}

func (s *btcChainService) GetBlock(blockHash chainhash.Hash, options ...neutrino.QueryOption) (*btcutil.Block, error) {
return s.CS.GetBlock(blockHash, options...)
}

func (s *btcChainService) GetCFilter(blockHash chainhash.Hash, filterType wire.FilterType, options ...neutrino.QueryOption) (*gcs.Filter, error) {
return s.CS.GetCFilter(blockHash, filterType, options...)
}

func (s *btcChainService) Stop() error {
return s.CS.Stop()
}

var _ dexbtc.SPVService = (*btcChainService)(nil)
var _ neutrinoService = (*neutrino.ChainService)(nil)

// CreateNewWallet creates a new wallet for the BTC asset.
func CreateNewWallet(pass *sharedW.AuthInfo, params *sharedW.InitParams) (sharedW.Asset, error) {
Expand Down Expand Up @@ -205,11 +176,11 @@ func CreateWatchOnlyWallet(walletName, extendedPublicKey string, params *sharedW
return btcWallet, nil
}

// RestoreWallet accepts the seed, wallet pass information and the init parameters.
// It validates the network type passed by fetching the chain parameters
// associated with it for the BTC asset. It then generates the BTC loader interface
// that is passed to be used upstream while restoring the wallet in the
// shared wallet implemenation.
// RestoreWallet accepts the seed, wallet pass information and the init
// parameters. It validates the network type passed by fetching the chain
// parameters associated with it for the BTC asset. It then generates the BTC
// loader interface that is passed to be used upstream while restoring the
// wallet in the shared wallet implementation.
// Immediately wallet restore is complete, the function to safely cancel network sync
// is set. There after returning the restored wallet's interface.
func RestoreWallet(seedMnemonic string, pass *sharedW.AuthInfo, params *sharedW.InitParams) (sharedW.Asset, error) {
Expand Down Expand Up @@ -312,6 +283,10 @@ func (asset *Asset) SafelyCancelSync() {
}
}

func (asset *Asset) NeutrinoClient() *chain.NeutrinoClient {
return asset.chainClient
}

// IsSynced returns true if the wallet is synced.
func (asset *Asset) IsSynced() bool {
asset.syncData.mu.RLock()
Expand Down Expand Up @@ -519,33 +494,6 @@ func (asset *Asset) SetSpecificPeer(address string) {
}()
}

func (asset *Asset) RemoveSpecificPeer(address string) {
sep := ";"
knownAddr := asset.ReadStringConfigValueForKey(sharedW.SpvPersistentPeerAddressesConfigKey, "")

addrs1, addrs2, found := strings.Cut(knownAddr, address)
if !found {
return
}

addrs1 = strings.TrimSuffix(addrs1, sep)
addrs2 = strings.TrimPrefix(addrs2, sep)
addrs := addrs1
if addrs1 == "" {
addrs = addrs2
} else if addrs2 != "" {
addrs += sep + addrs2
}

asset.SaveUserConfigValue(sharedW.SpvPersistentPeerAddressesConfigKey, knownAddr)
go func() {
err := asset.reloadChainService()
if err != nil {
log.Error(err)
}
}()
}

// GetExtendedPubKey returns the extended public key of the given account,
// to do that it calls btcwallet's AccountProperties method, using KeyScopeBIP0084
// and the account number. On failure it returns error.
Expand Down
Loading

0 comments on commit b907c46

Please sign in to comment.