From e9466bebc5a9ddeddf92d267182ff085cd6925d0 Mon Sep 17 00:00:00 2001 From: Steven Polley Date: Tue, 30 Sep 2025 23:02:07 -0600 Subject: [PATCH] pass errors up rather than logging directly --- providers/bitcoinElectrum/bitcoin.go | 22 ++++++---------------- providers/bitcoinElectrum/providerImpl.go | 18 ++++++------------ 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/providers/bitcoinElectrum/bitcoin.go b/providers/bitcoinElectrum/bitcoin.go index 366a274..96f2081 100644 --- a/providers/bitcoinElectrum/bitcoin.go +++ b/providers/bitcoinElectrum/bitcoin.go @@ -3,7 +3,7 @@ package bitcoinElectrum import ( "crypto/sha256" "encoding/hex" - "log" + "fmt" "sync/atomic" "github.com/btcsuite/btcd/btcutil" @@ -43,13 +43,10 @@ func addressToScriptHash(address btcutil.Address) (string, error) { } // Scans a derivation branch (m/0 or m/1) for balances until the gap limit is reached. -func scanBranch(masterKey *hdkeychain.ExtendedKey, branch uint32, gapLimit int, spvServer string) int64 { - log.Printf("Scanning branch m/%d/k...", branch) - +func scanBranch(masterKey *hdkeychain.ExtendedKey, branch uint32, gapLimit int, spvServer string) (int64, error) { branchKey, err := masterKey.Derive(branch) if err != nil { - log.Printf("Error deriving branch %d: %v", branch, err) - return 0 + return 0, fmt.Errorf("error deriving branch %d: %v", branch, err) } var branchTotalBalance int64 @@ -57,35 +54,28 @@ func scanBranch(masterKey *hdkeychain.ExtendedKey, branch uint32, gapLimit int, for i := uint32(0); ; i++ { if unusedAddressCount >= gapLimit { - log.Printf("Gap limit of %d reached on branch m/%d. Stopping scan.", gapLimit, branch) break } // 3. Derive child address address, err := deriveAddress(branchKey, i) if err != nil { - log.Printf("Could not derive address at index %d on branch %d: %v", i, branch, err) - continue + return 0, fmt.Errorf("could not derive address at index %d on branch %d: %v", i, branch, err) } // 4. Get balance from Electrum server balance, err := getAddressBalance(spvServer, address) if err != nil { - log.Printf("Error getting balance for %s: %v", address.EncodeAddress(), err) - // On error, we can't know if it's used, so we continue scanning. - unusedAddressCount = 0 - continue + return 0, fmt.Errorf("error getting balance for %s: %v", address.EncodeAddress(), err) } total := balance.Result.Confirmed + balance.Result.Unconfirmed if total > 0 { - log.Printf("Found balance for m/%d/%d (%s): %.8f BTC", branch, i, address.EncodeAddress(), btcutil.Amount(total).ToBTC()) atomic.AddInt64(&branchTotalBalance, total) unusedAddressCount = 0 // Reset gap counter on finding a used address } else { - log.Printf("No balance for m/%d/%d (%s)", branch, i, address.EncodeAddress()) unusedAddressCount++ } } - return branchTotalBalance + return branchTotalBalance, nil } diff --git a/providers/bitcoinElectrum/providerImpl.go b/providers/bitcoinElectrum/providerImpl.go index 61228c2..50fe6fe 100644 --- a/providers/bitcoinElectrum/providerImpl.go +++ b/providers/bitcoinElectrum/providerImpl.go @@ -3,8 +3,6 @@ package bitcoinElectrum import ( "fmt" "os" - "sync" - "sync/atomic" "github.com/btcsuite/btcd/btcutil/hdkeychain" ) @@ -27,7 +25,7 @@ func (p *Provider) Configure() error { p.ynabAccountID = os.Getenv("bitcoin_ynab_account") p.spvServer = os.Getenv("bitcoin_spv_server") p.coinGeckoApiKey = os.Getenv("bitcoin_coingecko_api_key") - p.gapLimit = 20 + p.gapLimit = 10 if zpub == "" || p.ynabAccountID == "" || p.spvServer == "" || p.coinGeckoApiKey == "" { return fmt.Errorf("this account provider is not configured") } @@ -43,21 +41,17 @@ func (p *Provider) Configure() error { // Returns slices of account balances and mapped YNAB account IDs, along with an error func (p *Provider) GetBalances() ([]int, []string, error) { var totalSats int64 - var wg sync.WaitGroup // branch 0 = regular // branch 1 = change addresses for _, branch := range []uint32{0, 1} { - wg.Add(1) - go func(branch uint32) { - defer wg.Done() - branchSats := scanBranch(p.masterKey, branch, p.gapLimit, p.spvServer) - atomic.AddInt64(&branchSats, totalSats) - }(branch) + branchSats, err := scanBranch(p.masterKey, branch, p.gapLimit, p.spvServer) + if err != nil { + return nil, nil, fmt.Errorf("failed to scan branch '%v': %v", branch, err) + } + totalSats += branchSats } - wg.Wait() - cad, err := convertBTCToCAD(totalSats, p.coinGeckoApiKey) if err != nil { return nil, nil, fmt.Errorf("failed to convert sats to CAD: %v", err)