Skip to content

Commit 2e36a48

Browse files
authored
Merge pull request #430 from SiaFoundation/nate/prevent-panic
Prevent price pin failure from crashing node
2 parents 29be3ab + ad69b44 commit 2e36a48

File tree

4 files changed

+44
-1
lines changed

4 files changed

+44
-1
lines changed

cmd/hostd/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ func main() {
396396
defer cancel()
397397

398398
if _, err := ex.SiacoinExchangeRate(ctx, "usd"); err != nil {
399-
log.Fatal("failed to get exchange rate", zap.Error(err))
399+
log.Error("failed to get exchange rate. explorer features may not work correctly", zap.Error(err))
400400
}
401401
}
402402

cmd/hostd/node.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ func newNode(ctx context.Context, walletKey types.PrivateKey, ex *explorer.Explo
187187
var pm *pin.Manager
188188
if !cfg.Explorer.Disable {
189189
pm, err = pin.NewManager(
190+
pin.WithAlerts(am),
190191
pin.WithStore(db),
191192
pin.WithSettings(sr),
192193
pin.WithExchangeRateRetriever(ex),

host/settings/pin/options.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ func WithLogger(log *zap.Logger) Option {
1616
}
1717
}
1818

19+
// WithAlerts sets the alerts manager for the pinner to register alerts with.
20+
func WithAlerts(a Alerts) Option {
21+
return func(m *Manager) {
22+
m.alerts = a
23+
}
24+
}
25+
1926
// WithFrequency sets the frequency at which the manager updates the host's
2027
// settings based on the current exchange rate.
2128
func WithFrequency(frequency time.Duration) Option {

host/settings/pin/pin.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@ import (
99

1010
"github.com/shopspring/decimal"
1111
"go.sia.tech/core/types"
12+
"go.sia.tech/hostd/alerts"
1213
"go.sia.tech/hostd/host/settings"
1314
"go.uber.org/zap"
15+
"lukechampine.com/frand"
1416
)
1517

18+
var pinAlertID = frand.Entropy256()
19+
1620
type (
1721
// A Pin is a pinned price in an external currency.
1822
Pin struct {
@@ -44,6 +48,12 @@ type (
4448
MaxCollateral Pin `json:"maxCollateral"`
4549
}
4650

51+
// Alerts registers global alerts.
52+
Alerts interface {
53+
Register(alerts.Alert)
54+
Dismiss(...types.Hash256)
55+
}
56+
4757
// A SettingsManager updates and retrieves the host's settings.
4858
SettingsManager interface {
4959
Settings() settings.Settings
@@ -67,6 +77,7 @@ type (
6777
Manager struct {
6878
log *zap.Logger
6979
store Store
80+
alerts Alerts
7081
explorer ExchangeRateRetriever
7182
sm SettingsManager
7283

@@ -99,6 +110,26 @@ func averageRate(rates []decimal.Decimal) decimal.Decimal {
99110
return sum.Div(decimal.NewFromInt(int64(len(rates))))
100111
}
101112

113+
func (m *Manager) registerPinFailureAlert(err error) {
114+
if m.alerts != nil && err != nil {
115+
m.alerts.Register(alerts.Alert{
116+
ID: pinAlertID,
117+
Severity: alerts.SeverityError,
118+
Message: "failed to update prices",
119+
Timestamp: time.Now(),
120+
Data: map[string]interface{}{
121+
"error": err.Error(),
122+
},
123+
})
124+
}
125+
}
126+
127+
func (m *Manager) dismissPinFailureAlert() {
128+
if m.alerts != nil {
129+
m.alerts.Dismiss(pinAlertID)
130+
}
131+
}
132+
102133
func (m *Manager) updatePrices(ctx context.Context, force bool) error {
103134
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
104135
defer cancel()
@@ -227,6 +258,7 @@ func (m *Manager) Run(ctx context.Context) error {
227258

228259
// update prices immediately
229260
if err := m.updatePrices(ctx, true); err != nil {
261+
m.registerPinFailureAlert(err)
230262
m.log.Error("failed to update prices", zap.Error(err))
231263
}
232264

@@ -237,6 +269,9 @@ func (m *Manager) Run(ctx context.Context) error {
237269
case <-t.C:
238270
if err := m.updatePrices(ctx, false); err != nil {
239271
m.log.Error("failed to update prices", zap.Error(err))
272+
m.registerPinFailureAlert(err)
273+
} else {
274+
m.dismissPinFailureAlert()
240275
}
241276
}
242277
}

0 commit comments

Comments
 (0)