Skip to content

Commit

Permalink
add AccountInfo() method to BTCWallet and implement for BTC clones
Browse files Browse the repository at this point in the history
Signed-off-by: Philemon Ukane <[email protected]>
  • Loading branch information
ukane-philemon committed Jan 7, 2024
1 parent ce88f63 commit d7a5488
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 53 deletions.
18 changes: 14 additions & 4 deletions client/asset/bch/spv.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -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 {
Expand Down
20 changes: 1 addition & 19 deletions client/asset/btc/btc.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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),
Expand Down
1 change: 0 additions & 1 deletion client/asset/btc/btc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down
9 changes: 9 additions & 0 deletions client/asset/btc/spv.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
7 changes: 7 additions & 0 deletions client/asset/btc/spv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
30 changes: 15 additions & 15 deletions client/asset/btc/spv_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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)
Expand All @@ -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 {
Expand Down Expand Up @@ -250,8 +251,6 @@ type spvWallet struct {
cfg *WalletConfig
wallet BTCWallet
cl SPVService
acctNum uint32
acctName string
dir string
decodeAddr dexbtc.AddressDecoder

Expand Down Expand Up @@ -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)
}
Expand All @@ -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
}
Expand All @@ -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
}
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion client/asset/dcr/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 7 additions & 7 deletions client/asset/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion client/asset/ltc/ltc.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 15 additions & 5 deletions client/asset/ltc/spv.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit d7a5488

Please sign in to comment.