From d7a54886f062d0916f1f4da64c85f9470246b0bf Mon Sep 17 00:00:00 2001 From: Philemon Ukane Date: Fri, 22 Dec 2023 11:27:05 +0100 Subject: [PATCH] add AccountInfo() method to BTCWallet and implement for BTC clones Signed-off-by: Philemon Ukane --- client/asset/bch/spv.go | 18 ++++++++++++++---- client/asset/btc/btc.go | 20 +------------------- client/asset/btc/btc_test.go | 1 - client/asset/btc/spv.go | 9 +++++++++ client/asset/btc/spv_test.go | 7 +++++++ client/asset/btc/spv_wrapper.go | 30 +++++++++++++++--------------- client/asset/dcr/wallet.go | 2 +- client/asset/interface.go | 14 +++++++------- client/asset/ltc/ltc.go | 2 +- client/asset/ltc/spv.go | 20 +++++++++++++++----- 10 files changed, 70 insertions(+), 53 deletions(-) diff --git a/client/asset/bch/spv.go b/client/asset/bch/spv.go index 69c8a3a79a..d3eaaf1804 100644 --- a/client/asset/bch/spv.go +++ b/client/asset/bch/spv.go @@ -52,10 +52,11 @@ import ( ) const ( - DefaultM uint64 = 784931 // From bchutil. Used for gcs filters. - logDirName = "logs" - neutrinoDBName = "neutrino.db" - defaultAcctNum = 0 + DefaultM uint64 = 784931 // From bchutil. Used for gcs filters. + logDirName = "logs" + neutrinoDBName = "neutrino.db" + defaultAcctNum = 0 + defaultAcctName = "default" ) var ( @@ -270,6 +271,15 @@ func (w *bchSPVWallet) txDetails(txHash *bchchainhash.Hash) (*bchwtxmgr.TxDetail var _ btc.BTCWallet = (*bchSPVWallet)(nil) +// AccountInfo returns the account information of the wallet for use by the +// exchange wallet. +func (w *bchSPVWallet) AccountInfo() btc.XCWalletAccount { + return btc.XCWalletAccount{ + AccountName: defaultAcctName, + AccountNumber: defaultAcctNum, + } +} + func (w *bchSPVWallet) PublishTransaction(btcTx *wire.MsgTx, label string) error { bchTx, err := convertMsgTxToBCH(btcTx) if err != nil { diff --git a/client/asset/btc/btc.go b/client/asset/btc/btc.go index 275a3fe8bd..ac42ea8a33 100644 --- a/client/asset/btc/btc.go +++ b/client/asset/btc/btc.go @@ -669,7 +669,7 @@ var customSPVWalletConstructors = map[string]CustomSPVWalletConstructor{} func RegisterCustomSPVWallet(constructor CustomSPVWalletConstructor, def *asset.WalletDefinition) error { for _, availableWallets := range WalletInfo.AvailableWallets { if def.Type == availableWallets.Type { - return fmt.Errorf("(%q): %w", def.Type, asset.ErrWalletTypeAlreadySupported) + return fmt.Errorf("(%q): %w", def.Type, asset.ErrWalletTypeAlreadyRegistered) } } customSPVWalletConstructors[def.Type] = constructor @@ -1293,27 +1293,9 @@ func OpenSPVWallet(cfg *BTCCloneCFG, walletConstructor BTCWalletConstructor) (*E } btc.txHistoryDB.Store(txHistoryDB) - acctName := defaultAcctName - // Check if an account name was provided via wallet settings. - if configAcctName := cfg.WalletCFG.Settings[WalletAccountNameConfigKey]; configAcctName != "" { - acctName = configAcctName - } - - var acctNumber uint32 = defaultAcctNum - // Check if an account number was provided via wallet settings. - if configAcctNumber := cfg.WalletCFG.Settings[WalletAccountNumberConfigKey]; configAcctNumber != "" { - accountNumber, err := strconv.ParseInt(configAcctNumber, 10, 64) - if err != nil { - return nil, fmt.Errorf("invalid config account number: %w", err) - } - acctNumber = uint32(accountNumber) - } - spvw := &spvWallet{ chainParams: cfg.ChainParams, cfg: walletCfg, - acctNum: acctNumber, - acctName: acctName, dir: filepath.Join(cfg.WalletCFG.DataDir, cfg.ChainParams.Name), txBlocks: make(map[chainhash.Hash]*hashEntry), checkpoints: make(map[OutPoint]*scanCheckpoint), diff --git a/client/asset/btc/btc_test.go b/client/asset/btc/btc_test.go index 9ea90088d6..c5a3d5935a 100644 --- a/client/asset/btc/btc_test.go +++ b/client/asset/btc/btc_test.go @@ -671,7 +671,6 @@ func tNewWallet(segwit bool, walletType string) (*intermediaryWallet, *testData, wallet: &tBtcWallet{data}, cl: neutrinoClient, tipChan: make(chan *BlockVector, 1), - acctNum: 0, txBlocks: data.dbBlockForTx, checkpoints: data.checkpoints, log: cfg.Logger.SubLogger("SPV"), diff --git a/client/asset/btc/spv.go b/client/asset/btc/spv.go index aecaf81a7a..4169e3b892 100644 --- a/client/asset/btc/spv.go +++ b/client/asset/btc/spv.go @@ -121,6 +121,15 @@ func openSPVWallet(dir string, cfg *WalletConfig, return w } +// AccountInfo returns the account information of the wallet for use by the +// exchange wallet. +func (w *btcSPVWallet) AccountInfo() XCWalletAccount { + return XCWalletAccount{ + AccountName: defaultAcctName, + AccountNumber: defaultAcctNum, + } +} + func (w *btcSPVWallet) Birthday() time.Time { return w.birthdayV.Load().(time.Time) } diff --git a/client/asset/btc/spv_test.go b/client/asset/btc/spv_test.go index 7ee690b320..80fe911cf0 100644 --- a/client/asset/btc/spv_test.go +++ b/client/asset/btc/spv_test.go @@ -39,6 +39,13 @@ type tBtcWallet struct { *testData } +func (c *tBtcWallet) AccountInfo() XCWalletAccount { + return XCWalletAccount{ + AccountName: defaultAcctName, + AccountNumber: defaultAcctNum, + } +} + func (c *tBtcWallet) ListSinceBlock(start, end, syncHeight int32) ([]btcjson.ListTransactionsResult, error) { return nil, nil } diff --git a/client/asset/btc/spv_wrapper.go b/client/asset/btc/spv_wrapper.go index 7d52446705..33bff2d719 100644 --- a/client/asset/btc/spv_wrapper.go +++ b/client/asset/btc/spv_wrapper.go @@ -75,13 +75,6 @@ const ( logFileName = "neutrino.log" defaultAcctNum = 0 defaultAcctName = "default" - - // WalletAccountNameConfigKey is used by external custom wallet constructors - // to specify an account name during wallet creation. - WalletAccountNameConfigKey = "walletname" - // WalletAccountNumberConfigKey is used by external custom wallet - // constructors to specify a wallet account number during wallet creation. - WalletAccountNumberConfigKey = "walletaccountnumber" ) var wAddrMgrBkt = []byte("waddrmgr") @@ -109,6 +102,9 @@ type BTCWallet interface { WaitForShutdown() ChainSynced() bool // currently unused AccountProperties(scope waddrmgr.KeyScope, acct uint32) (*waddrmgr.AccountProperties, error) + // AccountInfo returns the account information of the wallet for use by the + // exchange wallet. + AccountInfo() XCWalletAccount // The below methods are not implemented by *wallet.Wallet, so must be // implemented by the BTCWallet implementation. WalletTransaction(txHash *chainhash.Hash) (*wtxmgr.TxDetails, error) @@ -127,6 +123,11 @@ type BTCWallet interface { ListSinceBlock(start, end, syncHeight int32) ([]btcjson.ListTransactionsResult, error) } +type XCWalletAccount struct { + AccountName string + AccountNumber uint32 +} + // BlockNotification is block hash and height delivered by a BTCWallet when it // is finished processing a block. type BlockNotification struct { @@ -250,8 +251,6 @@ type spvWallet struct { cfg *WalletConfig wallet BTCWallet cl SPVService - acctNum uint32 - acctName string dir string decodeAddr dexbtc.AddressDecoder @@ -614,7 +613,8 @@ func (w *spvWallet) listTransactionsSinceBlock(blockHeight int32) ([]btcjson.Lis // balances retrieves a wallet's balance details. func (w *spvWallet) balances() (*GetBalancesResult, error) { // Determine trusted vs untrusted coins with listunspent. - unspents, err := w.wallet.ListUnspent(0, math.MaxInt32, w.acctName) + acctInfo := w.wallet.AccountInfo() + unspents, err := w.wallet.ListUnspent(0, math.MaxInt32, acctInfo.AccountName) if err != nil { return nil, fmt.Errorf("error listing unspent outputs: %w", err) } @@ -628,7 +628,7 @@ func (w *spvWallet) balances() (*GetBalancesResult, error) { } // listunspent does not include immature coinbase outputs or locked outputs. - bals, err := w.wallet.CalculateAccountBalances(w.acctNum, 0 /* confs */) + bals, err := w.wallet.CalculateAccountBalances(acctInfo.AccountNumber, 0 /* confs */) if err != nil { return nil, err } @@ -651,7 +651,7 @@ func (w *spvWallet) balances() (*GetBalancesResult, error) { // listUnspent retrieves list of the wallet's UTXOs. func (w *spvWallet) listUnspent() ([]*ListUnspentResult, error) { - unspents, err := w.wallet.ListUnspent(0, math.MaxInt32, w.acctName) + unspents, err := w.wallet.ListUnspent(0, math.MaxInt32, w.wallet.AccountInfo().AccountName) if err != nil { return nil, err } @@ -730,13 +730,13 @@ func (w *spvWallet) listLockUnspent() ([]*RPCOutpoint, error) { // changeAddress gets a new internal address from the wallet. The address will // be bech32-encoded (P2WPKH). func (w *spvWallet) changeAddress() (btcutil.Address, error) { - return w.wallet.NewChangeAddress(w.acctNum, waddrmgr.KeyScopeBIP0084) + return w.wallet.NewChangeAddress(w.wallet.AccountInfo().AccountNumber, waddrmgr.KeyScopeBIP0084) } // externalAddress gets a new bech32-encoded (P2WPKH) external address from the // wallet. func (w *spvWallet) externalAddress() (btcutil.Address, error) { - return w.wallet.NewAddress(w.acctNum, waddrmgr.KeyScopeBIP0084) + return w.wallet.NewAddress(w.wallet.AccountInfo().AccountNumber, waddrmgr.KeyScopeBIP0084) } // signTx attempts to have the wallet sign the transaction inputs. @@ -1137,7 +1137,7 @@ func copyDir(src, dst string) error { // numDerivedAddresses returns the number of internal and external addresses // that the wallet has derived. func (w *spvWallet) numDerivedAddresses() (internal, external uint32, err error) { - props, err := w.wallet.AccountProperties(waddrmgr.KeyScopeBIP0084, w.acctNum) + props, err := w.wallet.AccountProperties(waddrmgr.KeyScopeBIP0084, w.wallet.AccountInfo().AccountNumber) if err != nil { return 0, 0, err } diff --git a/client/asset/dcr/wallet.go b/client/asset/dcr/wallet.go index def3435cb9..cfe6f7ec6c 100644 --- a/client/asset/dcr/wallet.go +++ b/client/asset/dcr/wallet.go @@ -37,7 +37,7 @@ var customWalletConstructors = map[string]WalletConstructor{} func RegisterCustomWallet(constructor WalletConstructor, def *asset.WalletDefinition) error { for _, availableWallets := range WalletInfo.AvailableWallets { if def.Type == availableWallets.Type { - return fmt.Errorf("(%q): %w", def.Type, asset.ErrWalletTypeAlreadySupported) + return fmt.Errorf("(%q): %w", def.Type, asset.ErrWalletTypeAlreadyRegistered) } } customWalletConstructors[def.Type] = constructor diff --git a/client/asset/interface.go b/client/asset/interface.go index 197b6777bb..33b7c39e7a 100644 --- a/client/asset/interface.go +++ b/client/asset/interface.go @@ -212,13 +212,13 @@ const ( // ErrSwapNotInitiated most likely means that a swap using a contract has // not yet been mined. There is no guarantee that the swap will be mined // in the future. - ErrSwapNotInitiated = dex.ErrorKind("swap not yet initiated") - CoinNotFoundError = dex.ErrorKind("coin not found") - ErrRequestTimeout = dex.ErrorKind("request timeout") - ErrConnectionDown = dex.ErrorKind("wallet not connected") - ErrNotImplemented = dex.ErrorKind("not implemented") - ErrUnsupported = dex.ErrorKind("unsupported") - ErrWalletTypeAlreadySupported = dex.ErrorKind("wallet type already supported") + ErrSwapNotInitiated = dex.ErrorKind("swap not yet initiated") + CoinNotFoundError = dex.ErrorKind("coin not found") + ErrRequestTimeout = dex.ErrorKind("request timeout") + ErrConnectionDown = dex.ErrorKind("wallet not connected") + ErrNotImplemented = dex.ErrorKind("not implemented") + ErrUnsupported = dex.ErrorKind("unsupported") + ErrWalletTypeAlreadyRegistered = dex.ErrorKind("wallet type already registered") // ErrSwapRefunded is returned from ConfirmRedemption when the swap has // been refunded before the user could redeem. ErrSwapRefunded = dex.ErrorKind("swap refunded") diff --git a/client/asset/ltc/ltc.go b/client/asset/ltc/ltc.go index 5153ab2db2..695b1004bb 100644 --- a/client/asset/ltc/ltc.go +++ b/client/asset/ltc/ltc.go @@ -171,7 +171,7 @@ var customSPVWalletConstructors = map[string]btc.CustomSPVWalletConstructor{} func RegisterCustomSPVWallet(constructor btc.CustomSPVWalletConstructor, def *asset.WalletDefinition) error { for _, availableWallets := range WalletInfo.AvailableWallets { if def.Type == availableWallets.Type { - return fmt.Errorf("(%q): %w", def.Type, asset.ErrWalletTypeAlreadySupported) + return fmt.Errorf("(%q): %w", def.Type, asset.ErrWalletTypeAlreadyRegistered) } } customSPVWalletConstructors[def.Type] = constructor diff --git a/client/asset/ltc/spv.go b/client/asset/ltc/spv.go index ffe2f5f049..026f858395 100644 --- a/client/asset/ltc/spv.go +++ b/client/asset/ltc/spv.go @@ -52,11 +52,12 @@ import ( ) const ( - DefaultM uint64 = 784931 // From ltcutil. Used for gcs filters. - logDirName = "logs" - neutrinoDBName = "neutrino.db" - defaultAcctNum = 0 - dbTimeout = 20 * time.Second + DefaultM uint64 = 784931 // From ltcutil. Used for gcs filters. + logDirName = "logs" + neutrinoDBName = "neutrino.db" + defaultAcctNum = 0 + defaultAcctName = "default" + dbTimeout = 20 * time.Second ) var ( @@ -164,6 +165,15 @@ func createSPVWallet(privPass []byte, seed []byte, bday time.Time, walletDir str return nil } +// AccountInfo returns the account information of the wallet for use by the +// exchange wallet. +func (w *ltcSPVWallet) AccountInfo() btc.XCWalletAccount { + return btc.XCWalletAccount{ + AccountName: defaultAcctName, + AccountNumber: defaultAcctNum, + } +} + // walletParams works around a bug in ltcwallet that doesn't recognize // wire.TestNet4 in (*ScopedKeyManager).cloneKeyWithVersion which is called from // AccountProperties. Only do this for the *wallet.Wallet, not the