Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* [4561](https://github.com/zeta-chain/node/pull/4561) - add signet to BTC client `resolveParams` to fix e2e `unknown chain params` error
* [4569](https://github.com/zeta-chain/node/pull/4569) - tighten MtA proof bounds in tss-lib to fix Alpha-Rays / TSSHOCK vulnerability
* [4597](https://github.com/zeta-chain/node/pull/4597) - respect `DisableTssBlockScan` in Bitcoin observer to align inbound observation behavior with EVM observer
* [4644](https://github.com/zeta-chain/node/pull/4644) - return early in Bitcoin observer `refreshPendingNonce` when the pending nonces query fails, instead of dereferencing a nil pointer

### Tests

Expand Down
1 change: 1 addition & 0 deletions zetaclient/chains/bitcoin/observer/outbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ func (ob *Observer) refreshPendingNonce(ctx context.Context) {
p, err := ob.ZetaRepo().GetPendingNonces(ctx)
if err != nil {
logger.Error().Err(err).Send()
return
}

// increase pending nonce if lagged behind
Expand Down
65 changes: 65 additions & 0 deletions zetaclient/chains/bitcoin/observer/utxos_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package observer

import (
"context"
"errors"
"math"
"testing"
"time"
Expand All @@ -24,6 +25,70 @@ func Test_FetchUTXOs(t *testing.T) {
require.Equal(t, len(utxos), ob.TelemetryServer().GetNumberOfUTXOs())
}

func Test_FetchUTXOsPendingNoncesError(t *testing.T) {
// create test observer
ob := newTestSuite(t, chains.BitcoinMainnet)
ob.setPendingNonce(3)

tssAddress, err := ob.TSS().PubKey().AddressBTC(ob.Chain().ChainId)
require.NoError(t, err)
utxos := getTestUTXOs(tssAddress.EncodeAddress())

// zetacore fails to return the pending nonces
ob.zetacore.On("GetPendingNoncesByChain", mock.Anything, mock.Anything).
Return(observertypes.PendingNonces{}, errors.New("failed to get pending nonces"))
ob.client.On("ListUnspentMinMaxAddresses", mock.Anything, mock.Anything, mock.Anything, mock.Anything).
Return(utxos, nil)

// should neither panic nor fail, and UTXOs should still be fetched
err = ob.FetchUTXOs(context.Background())
require.NoError(t, err)
require.Equal(t, len(utxos), ob.TelemetryServer().GetNumberOfUTXOs())

// pending nonce should be left untouched
require.Equal(t, uint64(3), ob.GetPendingNonce())
}

func Test_RefreshPendingNonce(t *testing.T) {
tests := []struct {
name string
pendingNonce uint64
nonces observertypes.PendingNonces
err error
expectedNonce uint64
}{
{
name: "should increase pending nonce if lagged behind",
pendingNonce: 3,
nonces: observertypes.PendingNonces{NonceLow: 5, NonceHigh: 8},
expectedNonce: 5,
},
{
name: "should not decrease pending nonce",
pendingNonce: 7,
nonces: observertypes.PendingNonces{NonceLow: 5, NonceHigh: 8},
expectedNonce: 7,
},
{
name: "should keep pending nonce if GetPendingNoncesByChain fails",
pendingNonce: 3,
err: errors.New("failed to get pending nonces"),
expectedNonce: 3,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ob := newTestSuite(t, chains.BitcoinMainnet)
ob.setPendingNonce(tt.pendingNonce)
ob.zetacore.On("GetPendingNoncesByChain", mock.Anything, mock.Anything).Return(tt.nonces, tt.err)

ob.refreshPendingNonce(context.Background())
require.Equal(t, tt.expectedNonce, ob.GetPendingNonce())
})
}
}

func Test_SelectUTXOs(t *testing.T) {
ctx := context.Background()
dummyTxID := "6e6f71d281146c1fc5c755b35908ee449f26786c84e2ae18f98b268de40b7ec4"
Expand Down
Loading