Skip to content

Commit 5fb041b

Browse files
PLEX-1843: add node balances to beholder (#280)
* PLEX-1843: add node balances to beholder * dmytro's fix * bump
1 parent d5c9f7f commit 5fb041b

File tree

5 files changed

+37
-21
lines changed

5 files changed

+37
-21
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ require (
3232
github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20250827130336-5922343458be
3333
github.com/smartcontractkit/chainlink-framework/capabilities v0.0.0-20250818175541-3389ac08a563
3434
github.com/smartcontractkit/chainlink-framework/chains v0.0.0-20250717121125-2350c82883e2
35-
github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20250717121125-2350c82883e2
35+
github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20251020150604-8ab84f7bad1a
3636
github.com/smartcontractkit/chainlink-framework/multinode v0.0.0-20250729142306-508e798f6a5d
3737
github.com/smartcontractkit/chainlink-protos/svr v1.1.0
3838
github.com/smartcontractkit/chainlink-tron/relayer v0.0.11-0.20250815105909-75499abc4335

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -630,8 +630,8 @@ github.com/smartcontractkit/chainlink-framework/capabilities v0.0.0-202508181755
630630
github.com/smartcontractkit/chainlink-framework/capabilities v0.0.0-20250818175541-3389ac08a563/go.mod h1:jP5mrOLFEYZZkl7EiCHRRIMSSHCQsYypm1OZSus//iI=
631631
github.com/smartcontractkit/chainlink-framework/chains v0.0.0-20250717121125-2350c82883e2 h1:JU1JUrkzdAUHsOYdS9DENPkJfmrxweFRPRSztad6oPM=
632632
github.com/smartcontractkit/chainlink-framework/chains v0.0.0-20250717121125-2350c82883e2/go.mod h1:+pRGfDej1r7cHMs1dYmuyPuOZzYB9Q+PKu0FvZOYlmw=
633-
github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20250717121125-2350c82883e2 h1:ysZjKH+BpWlQhF93kr/Lc668UlCvT9NjfcsGdZT19I8=
634-
github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20250717121125-2350c82883e2/go.mod h1:jo+cUqNcHwN8IF7SInQNXDZ8qzBsyMpnLdYbDswviFc=
633+
github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20251020150604-8ab84f7bad1a h1:pr0VFI7AWlDVJBEkcvzXWd97V8w8QMNjRdfPVa/IQLk=
634+
github.com/smartcontractkit/chainlink-framework/metrics v0.0.0-20251020150604-8ab84f7bad1a/go.mod h1:jo+cUqNcHwN8IF7SInQNXDZ8qzBsyMpnLdYbDswviFc=
635635
github.com/smartcontractkit/chainlink-framework/multinode v0.0.0-20250729142306-508e798f6a5d h1:pTYIcsWHTMG5fAcbRUA8Qk5yscXKdSpopQ0DUEOjPik=
636636
github.com/smartcontractkit/chainlink-framework/multinode v0.0.0-20250729142306-508e798f6a5d/go.mod h1:2JTBNp3FlRdO/nHc4dsc9bfxxMClMO1Qt8sLJgtreBY=
637637
github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20250911124514-5874cc6d62b2 h1:1/KdO5AbUr3CmpLjMPuJXPo2wHMbfB8mldKLsg7D4M8=

pkg/chains/legacyevm/chain.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,10 @@ func newChain(cfg *config.ChainScoped, nodes []*toml.Node, opts ChainRelayOpts,
282282

283283
var balanceMonitor monitor.BalanceMonitor
284284
if opts.ChainConfigs.RPCEnabled() && cfg.EVM().BalanceMonitor().Enabled() {
285-
balanceMonitor = monitor.NewBalanceMonitor(cl, opts.KeyStore, l)
285+
balanceMonitor, err = monitor.NewBalanceMonitor(cl, opts.KeyStore, l)
286+
if err != nil {
287+
return nil, fmt.Errorf("failed to create balance monitor for chain with ID %s: %w", chainID, err)
288+
}
286289
headBroadcaster.Subscribe(balanceMonitor)
287290
}
288291

pkg/monitor/balance.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ type (
3939

4040
ethClient evmclient.Client
4141
chainIDStr string
42+
balanceMetrics metrics.GenericBalanceMetrics
4243
ethKeyStore keys.AddressLister
4344
ethBalances map[common.Address]*assets.Eth
4445
ethBalancesMtx sync.RWMutex
@@ -51,20 +52,26 @@ type (
5152
var _ BalanceMonitor = (*balanceMonitor)(nil)
5253

5354
// NewBalanceMonitor returns a new balanceMonitor
54-
func NewBalanceMonitor(ethClient evmclient.Client, ethKeyStore keys.AddressLister, lggr logger.Logger) *balanceMonitor {
55+
func NewBalanceMonitor(ethClient evmclient.Client, ethKeyStore keys.AddressLister, lggr logger.Logger) (*balanceMonitor, error) {
56+
balanceMetrics, err := metrics.NewGenericBalanceMetrics(metrics.EVM, ethClient.ConfiguredChainID().String())
57+
if err != nil {
58+
return nil, fmt.Errorf("failed to create balance metrics: %w", err)
59+
}
60+
5561
bm := &balanceMonitor{
56-
ethClient: ethClient,
57-
chainIDStr: ethClient.ConfiguredChainID().String(),
58-
ethKeyStore: ethKeyStore,
59-
ethBalances: make(map[common.Address]*assets.Eth),
62+
ethClient: ethClient,
63+
chainIDStr: ethClient.ConfiguredChainID().String(),
64+
balanceMetrics: balanceMetrics,
65+
ethKeyStore: ethKeyStore,
66+
ethBalances: make(map[common.Address]*assets.Eth),
6067
}
6168
bm.Service, bm.eng = services.Config{
6269
Name: "BalanceMonitor",
6370
Start: bm.start,
6471
Close: bm.close,
6572
}.NewServiceEngine(lggr)
6673
bm.sleeperTask = utils.NewSleeperTaskCtx(&worker{bm: bm})
67-
return bm
74+
return bm, nil
6875
}
6976

7077
func (bm *balanceMonitor) start(ctx context.Context) error {
@@ -87,8 +94,8 @@ func (bm *balanceMonitor) OnNewLongestChain(_ context.Context, _ *evmtypes.Head)
8794
}
8895
}
8996

90-
func (bm *balanceMonitor) updateBalance(ethBal assets.Eth, address common.Address) {
91-
bm.promUpdateEthBalance(&ethBal, address)
97+
func (bm *balanceMonitor) updateBalance(ctx context.Context, ethBal assets.Eth, address common.Address) {
98+
bm.updateBalanceMetrics(ctx, &ethBal, address)
9299

93100
bm.ethBalancesMtx.Lock()
94101
oldBal := bm.ethBalances[address]
@@ -126,15 +133,15 @@ var promETHBalance = promauto.NewGaugeVec(
126133
[]string{"account", "evmChainID"},
127134
)
128135

129-
func (bm *balanceMonitor) promUpdateEthBalance(balance *assets.Eth, from common.Address) {
136+
func (bm *balanceMonitor) updateBalanceMetrics(ctx context.Context, balance *assets.Eth, from common.Address) {
130137
balanceFloat, err := ApproximateFloat64(balance)
131138

132139
if err != nil {
133140
bm.eng.Error(fmt.Errorf("updatePrometheusEthBalance: %w", err))
134141
return
135142
}
136143

137-
metrics.NodeBalance.WithLabelValues(from.Hex(), bm.chainIDStr, metrics.EVM).Set(balanceFloat)
144+
bm.balanceMetrics.RecordNodeBalance(ctx, from.Hex(), balanceFloat)
138145
// TODO: Remove deprecated metric
139146
promETHBalance.WithLabelValues(from.Hex(), bm.chainIDStr).Set(balanceFloat)
140147
}
@@ -179,7 +186,7 @@ func (w *worker) checkAccountBalance(ctx context.Context, address common.Address
179186
)
180187
} else {
181188
ethBal := assets.Eth(*bal)
182-
w.bm.updateBalance(ethBal, address)
189+
w.bm.updateBalance(ctx, ethBal, address)
183190
}
184191
}
185192

pkg/monitor/balance_test.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ func TestBalanceMonitor_Start(t *testing.T) {
3939
ethKeyStore := keystest.Addresses{k0Addr, k1Addr}
4040
ethClient := newEthClientMock(t)
4141

42-
bm := monitor.NewBalanceMonitor(ethClient, ethKeyStore, logger.Test(t))
42+
bm, err := monitor.NewBalanceMonitor(ethClient, ethKeyStore, logger.Test(t))
43+
require.NoError(t, err)
4344

4445
k0bal := big.NewInt(42)
4546
k1bal := big.NewInt(43)
@@ -64,7 +65,8 @@ func TestBalanceMonitor_Start(t *testing.T) {
6465
ethKeyStore := keystest.Addresses{k0Addr}
6566
ethClient := newEthClientMock(t)
6667

67-
bm := monitor.NewBalanceMonitor(ethClient, ethKeyStore, logger.Test(t))
68+
bm, err := monitor.NewBalanceMonitor(ethClient, ethKeyStore, logger.Test(t))
69+
require.NoError(t, err)
6870
k0bal := big.NewInt(42)
6971

7072
ethClient.On("BalanceAt", mock.Anything, k0Addr, nilBigInt).Once().Return(k0bal, nil)
@@ -81,7 +83,8 @@ func TestBalanceMonitor_Start(t *testing.T) {
8183
ethKeyStore := keystest.Addresses{k0Addr}
8284
ethClient := newEthClientMock(t)
8385

84-
bm := monitor.NewBalanceMonitor(ethClient, ethKeyStore, logger.Test(t))
86+
bm, err := monitor.NewBalanceMonitor(ethClient, ethKeyStore, logger.Test(t))
87+
require.NoError(t, err)
8588
ctxCancelledAwaiter := testutils.NewAwaiter()
8689

8790
ethClient.On("BalanceAt", mock.Anything, k0Addr, nilBigInt).Once().Run(func(args mock.Arguments) {
@@ -108,7 +111,8 @@ func TestBalanceMonitor_Start(t *testing.T) {
108111
ethKeyStore := keystest.Addresses{k0Addr}
109112
ethClient := newEthClientMock(t)
110113

111-
bm := monitor.NewBalanceMonitor(ethClient, ethKeyStore, logger.Test(t))
114+
bm, err := monitor.NewBalanceMonitor(ethClient, ethKeyStore, logger.Test(t))
115+
require.NoError(t, err)
112116

113117
ethClient.On("BalanceAt", mock.Anything, k0Addr, nilBigInt).
114118
Once().
@@ -131,7 +135,8 @@ func TestBalanceMonitor_OnNewLongestChain_UpdatesBalance(t *testing.T) {
131135
ethKeyStore := keystest.Addresses{k0Addr, k1Addr}
132136
ethClient := newEthClientMock(t)
133137

134-
bm := monitor.NewBalanceMonitor(ethClient, ethKeyStore, logger.Test(t))
138+
bm, err := monitor.NewBalanceMonitor(ethClient, ethKeyStore, logger.Test(t))
139+
require.NoError(t, err)
135140
k0bal := big.NewInt(42)
136141
// Deliberately larger than a 64 bit unsigned integer to test overflow
137142
k1bal := big.NewInt(0)
@@ -177,7 +182,8 @@ func TestBalanceMonitor_FewerRPCCallsWhenBehind(t *testing.T) {
177182
ethKeyStore := keystest.Addresses{testutils.NewAddress()}
178183
ethClient := newEthClientMock(t)
179184

180-
bm := monitor.NewBalanceMonitor(ethClient, ethKeyStore, logger.Test(t))
185+
bm, err := monitor.NewBalanceMonitor(ethClient, ethKeyStore, logger.Test(t))
186+
require.NoError(t, err)
181187
ethClient.On("BalanceAt", mock.Anything, mock.Anything, mock.Anything).
182188
Once().
183189
Return(big.NewInt(1), nil)

0 commit comments

Comments
 (0)