From 72b76fe982361156bb3a3ba57315ec514655e63b Mon Sep 17 00:00:00 2001 From: Dmytro Piatkivskyi Date: Wed, 18 Sep 2024 08:19:29 +0300 Subject: [PATCH] Wallet sync fixed (#31) * address import logged * address import printed * sets ChangeAddressKey even when import unsuccessful * sets ChangeAddressKey even when import unsuccessful * fix * address able to be debugged * accounts * reverts "address able to be debugged" * imports to default acc * imports to default acc + addrType=adtChain * adds change address to External adds * import returns address even if duplicate * sync after wallet initialized * sync after wallet initialized reverted, hardcoded address * hardcoded address fixed * filters imported addresses only * filters imported addresses only, fix * introduces GetWalletAddresses * puts back startWalletRPCServices * removes ChangeAddress from wallet * PR comments handled --------- Co-authored-by: dpiatkivskyi --- run/btcwallet.go | 7 ++++++- waddrmgr/db.go | 14 ++++++++------ waddrmgr/scoped_manager.go | 3 ++- wallet/frost_signing_test.go | 2 +- wallet/import_btc_addr.go | 17 +++++++---------- wallet/wallet.go | 21 ++++++++++++--------- 6 files changed, 36 insertions(+), 28 deletions(-) diff --git a/run/btcwallet.go b/run/btcwallet.go index fea1c20734..9a79856a14 100644 --- a/run/btcwallet.go +++ b/run/btcwallet.go @@ -179,10 +179,15 @@ func doInit(config *BtcwalletConfig) (*wallet.Wallet, error) { return nil, err } - changeAddressKey, err := w.GenerateKeyFromEthAddressAndImport(ethChangeAddr) + changeAddressKey, changeAddress, err := w.GenerateKeyFromEthAddressAndImport(ethChangeAddr) if err != nil && !strings.Contains(err.Error(), "already exists") { return nil, fmt.Errorf("cannot import change address: %w", err) } + log.Infof("Change address: %s", changeAddress) + + if changeAddressKey == nil { + return nil, fmt.Errorf("change key is nil") + } w.ChangeAddressKey = changeAddressKey } diff --git a/waddrmgr/db.go b/waddrmgr/db.go index 63b897660f..d47fbecd3d 100644 --- a/waddrmgr/db.go +++ b/waddrmgr/db.go @@ -2398,9 +2398,10 @@ func putBirthday(ns walletdb.ReadWriteBucket, t time.Time) error { // FetchBirthdayBlock retrieves the birthday block from the database. // // The block is serialized as follows: -// [0:4] block height -// [4:36] block hash -// [36:44] block timestamp +// +// [0:4] block height +// [4:36] block hash +// [36:44] block timestamp func FetchBirthdayBlock(ns walletdb.ReadBucket) (BlockStamp, error) { var block BlockStamp @@ -2438,9 +2439,10 @@ func DeleteBirthdayBlock(ns walletdb.ReadWriteBucket) error { // PutBirthdayBlock stores the provided birthday block to the database. // // The block is serialized as follows: -// [0:4] block height -// [4:36] block hash -// [36:44] block timestamp +// +// [0:4] block height +// [4:36] block hash +// [36:44] block timestamp // // NOTE: This does not alter the birthday block verification state. func PutBirthdayBlock(ns walletdb.ReadWriteBucket, block BlockStamp) error { diff --git a/waddrmgr/scoped_manager.go b/waddrmgr/scoped_manager.go index be85a232bf..cff48b6f0c 100644 --- a/waddrmgr/scoped_manager.go +++ b/waddrmgr/scoped_manager.go @@ -4,6 +4,7 @@ import ( "crypto/sha256" "encoding/binary" "fmt" + "strings" "sync" "github.com/btcsuite/btcd/btcec/v2" @@ -1971,7 +1972,7 @@ func (s *ScopedKeyManager) ImportPublicKey(ns walletdb.ReadWriteBucket, err := s.importPublicKey( ns, serializedPubKey, nil, s.addrSchema.ExternalAddrType, bs, ) - if err != nil { + if err != nil && !strings.Contains(err.Error(), "already exists") { return nil, err } diff --git a/wallet/frost_signing_test.go b/wallet/frost_signing_test.go index 2606842244..c27ab566a4 100644 --- a/wallet/frost_signing_test.go +++ b/wallet/frost_signing_test.go @@ -36,7 +36,7 @@ func TestFrostSigning(t *testing.T) { err = w.Unlock([]byte("world"), time.After(10*time.Minute)) require.NoError(t, err) - pubKey, err := w.GenerateKeyFromEthAddressAndImport("0x7b3f4f4b3cCf7f3fDf3f3f3f3f3f3f3f3f3f3f3f") + pubKey, _, err := w.GenerateKeyFromEthAddressAndImport("0x7b3f4f4b3cCf7f3fDf3f3f3f3f3f3f3f3f3f3f3f") require.NoError(t, err) p2shAddr, err := txscript.PayToTaprootScript(pubKey) diff --git a/wallet/import_btc_addr.go b/wallet/import_btc_addr.go index 0429262b64..e57e8b5abc 100644 --- a/wallet/import_btc_addr.go +++ b/wallet/import_btc_addr.go @@ -11,7 +11,7 @@ import ( func (w *Wallet) GenerateAndImportKeyWithCheck(btcAddr, ethAddr string) (*btcec.PublicKey, error) { - key, importedAddress, err := w.generateKeyFromEthAddressAndImport(ethAddr) + key, importedAddress, err := w.GenerateKeyFromEthAddressAndImport(ethAddr) if err != nil { return nil, err } @@ -27,12 +27,7 @@ func (w *Wallet) GenerateAndImportKeyWithCheck(btcAddr, ethAddr string) (*btcec. return key, nil } -func (w *Wallet) GenerateKeyFromEthAddressAndImport(ethAddr string) (*btcec.PublicKey, error) { - key, _, err := w.generateKeyFromEthAddressAndImport(ethAddr) - return key, err -} - -func (w *Wallet) generateKeyFromEthAddressAndImport(ethAddr string) (*btcec.PublicKey, waddrmgr.ManagedAddress, error) { +func (w *Wallet) GenerateKeyFromEthAddressAndImport(ethAddr string) (*btcec.PublicKey, waddrmgr.ManagedAddress, error) { lc, err := w.lcFromEthAddr(ethAddr) if err != nil { @@ -42,18 +37,20 @@ func (w *Wallet) generateKeyFromEthAddressAndImport(ethAddr string) (*btcec.Publ pubKey := lc.GetCombinedPubKey() importedAddress, err := w.ImportPublicKeyReturnAddress(pubKey, waddrmgr.TaprootPubKey) if err != nil { - return nil, nil, err + return pubKey, importedAddress, err } if importedAddress == nil { - return nil, nil, fmt.Errorf("imported address is nil") + return pubKey, nil, fmt.Errorf("imported address is nil") } err = w.AddressMapStorage.SetEthAddress(importedAddress.Address().EncodeAddress(), ethAddr) if err != nil { - return nil, nil, err + return pubKey, nil, err } + log.Infof("Imported address %s with eth address %s", importedAddress.Address().EncodeAddress(), ethAddr) + return pubKey, importedAddress, nil } diff --git a/wallet/wallet.go b/wallet/wallet.go index c102680d00..6bee70d706 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -865,7 +865,7 @@ expandHorizons: // construct the filter blocks request. The request includes the range // of blocks we intend to scan, in addition to the scope-index -> addr // map for all internal and external branches. - filterReq := newFilterBlocksRequest(batch, scopedMgrs, recoveryState) + filterReq := newFilterBlocksRequest(w, batch, scopedMgrs, recoveryState) // Initiate the filter blocks request using our chain backend. If an // error occurs, we are unable to proceed with the recovery. @@ -1031,9 +1031,7 @@ func internalKeyPath(index uint32) waddrmgr.DerivationPath { // newFilterBlocksRequest constructs FilterBlocksRequests using our current // block range, scoped managers, and recovery state. -func newFilterBlocksRequest(batch []wtxmgr.BlockMeta, - scopedMgrs map[waddrmgr.KeyScope]*waddrmgr.ScopedKeyManager, - recoveryState *RecoveryState) *chain.FilterBlocksRequest { +func newFilterBlocksRequest(w *Wallet, batch []wtxmgr.BlockMeta, scopedMgrs map[waddrmgr.KeyScope]*waddrmgr.ScopedKeyManager, recoveryState *RecoveryState) *chain.FilterBlocksRequest { filterReq := &chain.FilterBlocksRequest{ Blocks: batch, @@ -1046,13 +1044,18 @@ func newFilterBlocksRequest(batch []wtxmgr.BlockMeta, // sets belong to all currently tracked scopes. for scope := range scopedMgrs { scopeState := recoveryState.StateForScope(scope) - for index, addr := range scopeState.ExternalBranch.Addrs() { - scopedIndex := waddrmgr.ScopedIndex{ - Scope: scope, - Index: index, + + addresses, err := w.AccountAddresses(waddrmgr.ImportedAddrAccount) + if err == nil { + for index, addr := range addresses { + scopedIndex := waddrmgr.ScopedIndex{ + Scope: scope, + Index: uint32(index), + } + filterReq.ExternalAddrs[scopedIndex] = addr } - filterReq.ExternalAddrs[scopedIndex] = addr } + for index, addr := range scopeState.InternalBranch.Addrs() { scopedIndex := waddrmgr.ScopedIndex{ Scope: scope,