github.com/ethersphere/bee/v2@v2.2.0/pkg/replicas/replica_test.go (about)

     1  // Copyright 2023 The Swarm Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // replicas_test just contains helper functions to verify dispersion and replication
     6  package replicas_test
     7  
     8  import (
     9  	"context"
    10  	"errors"
    11  	"fmt"
    12  
    13  	"github.com/ethersphere/bee/v2/pkg/file/redundancy"
    14  	"github.com/ethersphere/bee/v2/pkg/soc"
    15  	"github.com/ethersphere/bee/v2/pkg/storage"
    16  	"github.com/ethersphere/bee/v2/pkg/swarm"
    17  )
    18  
    19  // dispersed verifies that a set of addresses are maximally dispersed without repetition
    20  func dispersed(level redundancy.Level, ch swarm.Chunk, addrs []swarm.Address) error {
    21  	nhoods := make(map[byte]bool)
    22  
    23  	for _, addr := range addrs {
    24  		if len(addr.Bytes()) != swarm.HashSize {
    25  			return errors.New("corrupt data: invalid address length")
    26  		}
    27  		nh := addr.Bytes()[0] >> (8 - int(level))
    28  		if nhoods[nh] {
    29  			return errors.New("not dispersed enough: duplicate neighbourhood")
    30  		}
    31  		nhoods[nh] = true
    32  	}
    33  	if len(nhoods) != len(addrs) {
    34  		return fmt.Errorf("not dispersed enough: unexpected number of neighbourhood covered: want %v. got %v", len(addrs), len(nhoods))
    35  	}
    36  
    37  	return nil
    38  }
    39  
    40  // replicated verifies that the replica chunks are indeed replicas
    41  // of the original chunk wrapped in soc
    42  func replicated(store storage.ChunkStore, ch swarm.Chunk, addrs []swarm.Address) error {
    43  	ctx := context.Background()
    44  	for _, addr := range addrs {
    45  		chunk, err := store.Get(ctx, addr)
    46  		if err != nil {
    47  			return err
    48  		}
    49  
    50  		sch, err := soc.FromChunk(chunk)
    51  		if err != nil {
    52  			return err
    53  		}
    54  		if !sch.WrappedChunk().Equal(ch) {
    55  			return errors.New("invalid replica: does not wrap original content addressed chunk")
    56  		}
    57  	}
    58  	return nil
    59  }