Skip to content

Commit 412c512

Browse files
committed
test: ensure db errors work
1 parent 2fb7fbd commit 412c512

File tree

2 files changed

+69
-4
lines changed

2 files changed

+69
-4
lines changed

x/sync/merkledb_client.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"google.golang.org/protobuf/proto"
1515

1616
"github.com/ava-labs/avalanchego/ids"
17+
"github.com/ava-labs/avalanchego/utils"
1718
"github.com/ava-labs/avalanchego/utils/maybe"
1819
"github.com/ava-labs/avalanchego/utils/set"
1920
"github.com/ava-labs/avalanchego/x/merkledb"
@@ -40,7 +41,7 @@ type merkleDBSyncClient struct {
4041
db DB
4142
config *ClientConfig
4243
tokenSize int
43-
err error
44+
err *utils.Atomic[error]
4445
errorOnce sync.Once
4546
}
4647

@@ -57,16 +58,17 @@ func NewClient(db DB, config *ClientConfig) (*merkleDBSyncClient, error) {
5758
db: db,
5859
config: config,
5960
tokenSize: merkledb.BranchFactorToTokenSize[config.BranchFactor],
61+
err: utils.NewAtomic[error](nil),
6062
}, nil
6163
}
6264

6365
func (c *merkleDBSyncClient) Error() error {
64-
return c.err
66+
return c.err.Get()
6567
}
6668

6769
func (c *merkleDBSyncClient) setError(err error) {
6870
c.errorOnce.Do(func() {
69-
c.err = err
71+
c.err.Set(err)
7072
})
7173
}
7274

x/sync/sync_test.go

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package sync
66
import (
77
"bytes"
88
"context"
9+
"errors"
910
"math/rand"
1011
"slices"
1112
"testing"
@@ -23,7 +24,12 @@ import (
2324
"github.com/ava-labs/avalanchego/x/merkledb"
2425
)
2526

26-
var _ p2p.Handler = (*waitingHandler)(nil)
27+
var (
28+
_ p2p.Handler = (*waitingHandler)(nil)
29+
30+
// Used to simulate a corrupted DB
31+
errorFoo = errors.New("mock error")
32+
)
2733

2834
func Test_Creation(t *testing.T) {
2935
require := require.New(t)
@@ -657,6 +663,63 @@ func Test_Sync_UpdateSyncTarget(t *testing.T) {
657663
require.Equal(1, m.unprocessedWork.Len())
658664
}
659665

666+
func Test_Sync_DBError(t *testing.T) {
667+
require := require.New(t)
668+
669+
now := time.Now().UnixNano()
670+
r := rand.New(rand.NewSource(now)) // #nosec G404
671+
dbToSync, err := generateTrie(t, r, maxKeyValuesLimit)
672+
require.NoError(err)
673+
syncRoot, err := dbToSync.GetMerkleRoot(context.Background())
674+
require.NoError(err)
675+
676+
db, err := merkledb.New(
677+
context.Background(),
678+
memdb.New(),
679+
newDefaultDBConfig(),
680+
)
681+
require.NoError(err)
682+
683+
// This client DB will return an error when it tries to commit a range proof.
684+
badDB := &badMerkleDB{MerkleDB: db}
685+
686+
proofClient, err := NewClient(badDB, &ClientConfig{
687+
BranchFactor: merkledb.BranchFactor16,
688+
})
689+
require.NoError(err)
690+
691+
ctx := context.Background()
692+
syncer, err := NewManager(ManagerConfig{
693+
ProofClient: proofClient,
694+
RangeProofClient: p2ptest.NewSelfClient(t, ctx, ids.EmptyNodeID, NewGetRangeProofHandler(dbToSync)),
695+
ChangeProofClient: p2ptest.NewSelfClient(t, ctx, ids.EmptyNodeID, NewGetChangeProofHandler(dbToSync)),
696+
TargetRoot: syncRoot,
697+
SimultaneousWorkLimit: 5,
698+
Log: logging.NoLog{},
699+
}, prometheus.NewRegistry())
700+
require.NoError(err)
701+
require.NotNil(syncer)
702+
require.NoError(syncer.Start(context.Background()))
703+
err = syncer.Wait(context.Background())
704+
require.ErrorIs(err, errorFoo)
705+
}
706+
707+
var _ DB = (*badMerkleDB)(nil)
708+
709+
type badMerkleDB struct {
710+
merkledb.MerkleDB
711+
}
712+
713+
func (*badMerkleDB) CommitRangeProof(
714+
_ context.Context,
715+
_ maybe.Maybe[[]byte],
716+
_ maybe.Maybe[[]byte],
717+
_ *merkledb.RangeProof,
718+
) error {
719+
// Simulate a bad response by returning an error.
720+
return errorFoo
721+
}
722+
660723
func generateTrie(t *testing.T, r *rand.Rand, count int) (merkledb.MerkleDB, error) {
661724
return generateTrieWithMinKeyLen(t, r, count, 0)
662725
}

0 commit comments

Comments
 (0)