Skip to content

Commit

Permalink
fix: add check for invalid chunk and add test
Browse files Browse the repository at this point in the history
  • Loading branch information
Alok Nerurkar committed Apr 7, 2022
1 parent 18f18cc commit d0a7759
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
7 changes: 4 additions & 3 deletions pkg/netstore/netstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ type store struct {
}

var (
ErrRecoveryAttempt = errors.New("failed to retrieve chunk, recovery initiated")
ErrRecoveryAttempt = errors.New("failed to retrieve chunk, recovery initiated")
errInvalidLocalChunk = errors.New("invalid chunk found locally")
)

// New returns a new NetStore that wraps a given Storer.
Expand All @@ -66,13 +67,13 @@ func (s *store) Get(ctx context.Context, mode storage.ModeGet, addr swarm.Addres
// this would ensure it is retrieved again from network and added back with
// the correct data
if !cac.Valid(ch) && !soc.Valid(ch) {
err = errors.New("invalid chunk")
err = errInvalidLocalChunk
ch = nil
s.logger.Warning("netstore: got invalid chunk from localstore, falling back to retrieval")
}
}
if err != nil {
if errors.Is(err, storage.ErrNotFound) {
if errors.Is(err, storage.ErrNotFound) || errors.Is(err, errInvalidLocalChunk) {
// request from network
ch, err = s.retrieval.RetrieveChunk(ctx, addr, true)
if err != nil {
Expand Down
46 changes: 46 additions & 0 deletions pkg/netstore/netstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,52 @@ func TestNetstoreNoRetrieval(t *testing.T) {
}
}

func TestInvalidChunkNetstoreRetrieval(t *testing.T) {
retrieve, store, nstore := newRetrievingNetstore(t, nil, noopValidStamp)

invalidChunk := swarm.NewChunk(testChunk.Address(), []byte("deadbeef"))
// store invalid chunk, i.e. hash doesnt match the data to simulate corruption
_, err := store.Put(context.Background(), storage.ModePutUpload, invalidChunk)
if err != nil {
t.Fatal(err)
}

addr := testChunk.Address()
_, err = nstore.Get(context.Background(), storage.ModeGetRequest, addr)
if err != nil {
t.Fatal(err)
}
if !retrieve.called {
t.Fatal("retrieve request not issued")
}
if retrieve.callCount != 1 {
t.Fatalf("call count %d", retrieve.callCount)
}
if !retrieve.addr.Equal(addr) {
t.Fatalf("addresses not equal. got %s want %s", retrieve.addr, addr)
}

// store should have the chunk once the background PUT is complete
d := waitAndGetChunk(t, store, addr, storage.ModeGetRequest)

if !bytes.Equal(d.Data(), testChunk.Data()) {
t.Fatal("chunk data not equal to expected data")
}

// check that the second call does not result in another retrieve request
d, err = nstore.Get(context.Background(), storage.ModeGetRequest, addr)
if err != nil {
t.Fatal(err)
}

if retrieve.callCount != 1 {
t.Fatalf("call count %d", retrieve.callCount)
}
if !bytes.Equal(d.Data(), testChunk.Data()) {
t.Fatal("chunk data not equal to expected data")
}
}

func TestRecovery(t *testing.T) {
callbackWasCalled := make(chan bool, 1)
rec := &mockRecovery{
Expand Down

0 comments on commit d0a7759

Please sign in to comment.