Skip to content

Commit 83ceca6

Browse files
committed
refactor(blockstream): improve error handling and calculations
1 parent 54da296 commit 83ceca6

File tree

1 file changed

+26
-17
lines changed

1 file changed

+26
-17
lines changed

internal/btcrpc/blockstream/blockstream.go

+26-17
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import (
88
"regexp"
99
"strconv"
1010
"strings"
11+
"time"
12+
13+
"github.com/pkg/errors"
1114

1215
"github.com/dwarvesf/icy-backend/internal/model"
1316
"github.com/dwarvesf/icy-backend/internal/utils/config"
@@ -118,6 +121,7 @@ func (c *blockstream) GetUTXOs(address string) ([]UTXO, error) {
118121
}
119122

120123
return utxos, nil
124+
121125
}
122126

123127
func (c *blockstream) GetBTCBalance(address string) (*model.Web3BigInt, error) {
@@ -128,49 +132,54 @@ func (c *blockstream) GetBTCBalance(address string) (*model.Web3BigInt, error) {
128132
for attempt := 1; attempt <= maxRetries; attempt++ {
129133
resp, err := c.client.Get(url)
130134
if err != nil {
131-
lastErr = err
132-
c.logger.Error("[getBTCBalance][client.Get]", map[string]string{
133-
"error": err.Error(),
135+
lastErr = errors.Wrap(err, "failed to fetch BTC balance")
136+
c.logger.Error("[GetBTCBalance][client.Get]", map[string]string{
137+
"error": lastErr.Error(),
134138
"attempt": strconv.Itoa(attempt),
135139
})
140+
time.Sleep(time.Duration(attempt) * time.Second) // Exponential backoff
136141
continue
137142
}
138143

144+
// Ensure response body is closed properly
145+
defer resp.Body.Close()
146+
139147
if resp.StatusCode != http.StatusOK {
140-
lastErr = err
141-
c.logger.Error("[getBTCBalance][client.Get]", map[string]string{
142-
"error": "unexpected status code",
148+
lastErr = fmt.Errorf("unexpected status code: %d", resp.StatusCode)
149+
c.logger.Error("[GetBTCBalance][client.Get]", map[string]string{
150+
"error": lastErr.Error(),
143151
"attempt": strconv.Itoa(attempt),
144152
})
145-
resp.Body.Close()
153+
time.Sleep(time.Duration(attempt) * time.Second)
146154
continue
147155
}
148156

149157
body, err := io.ReadAll(resp.Body)
150-
resp.Body.Close()
151158
if err != nil {
152-
lastErr = err
153-
c.logger.Error("[getBTCBalance][io.ReadAll]", map[string]string{
154-
"error": err.Error(),
159+
lastErr = errors.Wrap(err, "failed to read response body")
160+
c.logger.Error("[GetBTCBalance][io.ReadAll]", map[string]string{
161+
"error": lastErr.Error(),
155162
"attempt": strconv.Itoa(attempt),
156163
})
157164
continue
158165
}
159166

160-
var response *GetBalanceResponse
167+
var response GetBalanceResponse
161168
err = json.Unmarshal(body, &response)
162169
if err != nil {
163-
lastErr = err
164-
c.logger.Error("[getBTCBalance][json.Unmarshal]", map[string]string{
165-
"error": err.Error(),
170+
lastErr = errors.Wrap(err, "failed to parse JSON response")
171+
c.logger.Error("[GetBTCBalance][json.Unmarshal]", map[string]string{
172+
"error": lastErr.Error(),
166173
"attempt": strconv.Itoa(attempt),
167174
})
168175
continue
169176
}
170177

178+
// Correct balance calculation
179+
balanceSats := response.ChainStats.FundedTxoSum - response.ChainStats.SpentTxoSum
171180
return &model.Web3BigInt{
172-
Value: strconv.Itoa(response.ChainStats.FundedTxoSum),
173-
Decimal: 10,
181+
Value: strconv.FormatInt(int64(balanceSats), 10),
182+
Decimal: 8, // BTC has 8 decimal places
174183
}, nil
175184
}
176185

0 commit comments

Comments
 (0)