github.com/pokt-network/tendermint@v0.32.11-0.20230426215212-59310158d3e9/types/part_set_test.go (about)

     1  package types
     2  
     3  import (
     4  	"io/ioutil"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  
    10  	"github.com/tendermint/tendermint/crypto/merkle"
    11  	tmrand "github.com/tendermint/tendermint/libs/rand"
    12  )
    13  
    14  const (
    15  	testPartSize = 65536 // 64KB ...  4096 // 4KB
    16  )
    17  
    18  func TestBasicPartSet(t *testing.T) {
    19  	// Construct random data of size partSize * 100
    20  	data := tmrand.Bytes(testPartSize * 100)
    21  	partSet := NewPartSetFromData(data, testPartSize)
    22  
    23  	assert.NotEmpty(t, partSet.Hash())
    24  	assert.Equal(t, 100, partSet.Total())
    25  	assert.Equal(t, 100, partSet.BitArray().Size())
    26  	assert.True(t, partSet.HashesTo(partSet.Hash()))
    27  	assert.True(t, partSet.IsComplete())
    28  	assert.Equal(t, 100, partSet.Count())
    29  
    30  	// Test adding parts to a new partSet.
    31  	partSet2 := NewPartSetFromHeader(partSet.Header())
    32  
    33  	assert.True(t, partSet2.HasHeader(partSet.Header()))
    34  	for i := 0; i < partSet.Total(); i++ {
    35  		part := partSet.GetPart(i)
    36  		//t.Logf("\n%v", part)
    37  		added, err := partSet2.AddPart(part)
    38  		if !added || err != nil {
    39  			t.Errorf("failed to add part %v, error: %v", i, err)
    40  		}
    41  	}
    42  	// adding part with invalid index
    43  	added, err := partSet2.AddPart(&Part{Index: 10000})
    44  	assert.False(t, added)
    45  	assert.Error(t, err)
    46  	// adding existing part
    47  	added, err = partSet2.AddPart(partSet2.GetPart(0))
    48  	assert.False(t, added)
    49  	assert.Nil(t, err)
    50  
    51  	assert.Equal(t, partSet.Hash(), partSet2.Hash())
    52  	assert.Equal(t, 100, partSet2.Total())
    53  	assert.True(t, partSet2.IsComplete())
    54  
    55  	// Reconstruct data, assert that they are equal.
    56  	data2Reader := partSet2.GetReader()
    57  	data2, err := ioutil.ReadAll(data2Reader)
    58  	require.NoError(t, err)
    59  
    60  	assert.Equal(t, data, data2)
    61  }
    62  
    63  func TestWrongProof(t *testing.T) {
    64  	// Construct random data of size partSize * 100
    65  	data := tmrand.Bytes(testPartSize * 100)
    66  	partSet := NewPartSetFromData(data, testPartSize)
    67  
    68  	// Test adding a part with wrong data.
    69  	partSet2 := NewPartSetFromHeader(partSet.Header())
    70  
    71  	// Test adding a part with wrong trail.
    72  	part := partSet.GetPart(0)
    73  	part.Proof.Aunts[0][0] += byte(0x01)
    74  	added, err := partSet2.AddPart(part)
    75  	if added || err == nil {
    76  		t.Errorf("expected to fail adding a part with bad trail.")
    77  	}
    78  
    79  	// Test adding a part with wrong bytes.
    80  	part = partSet.GetPart(1)
    81  	part.Bytes[0] += byte(0x01)
    82  	added, err = partSet2.AddPart(part)
    83  	if added || err == nil {
    84  		t.Errorf("expected to fail adding a part with bad bytes.")
    85  	}
    86  }
    87  
    88  func TestPartSetHeaderValidateBasic(t *testing.T) {
    89  	testCases := []struct {
    90  		testName              string
    91  		malleatePartSetHeader func(*PartSetHeader)
    92  		expectErr             bool
    93  	}{
    94  		{"Good PartSet", func(psHeader *PartSetHeader) {}, false},
    95  		{"Negative Total", func(psHeader *PartSetHeader) { psHeader.Total = -2 }, true},
    96  		{"Invalid Hash", func(psHeader *PartSetHeader) { psHeader.Hash = make([]byte, 1) }, true},
    97  	}
    98  	for _, tc := range testCases {
    99  		tc := tc
   100  		t.Run(tc.testName, func(t *testing.T) {
   101  			data := tmrand.Bytes(testPartSize * 100)
   102  			ps := NewPartSetFromData(data, testPartSize)
   103  			psHeader := ps.Header()
   104  			tc.malleatePartSetHeader(&psHeader)
   105  			assert.Equal(t, tc.expectErr, psHeader.ValidateBasic() != nil, "Validate Basic had an unexpected result")
   106  		})
   107  	}
   108  }
   109  
   110  func TestPartValidateBasic(t *testing.T) {
   111  	testCases := []struct {
   112  		testName     string
   113  		malleatePart func(*Part)
   114  		expectErr    bool
   115  	}{
   116  		{"Good Part", func(pt *Part) {}, false},
   117  		{"Negative index", func(pt *Part) { pt.Index = -1 }, true},
   118  		{"Too big part", func(pt *Part) { pt.Bytes = make([]byte, BlockPartSizeBytes+1) }, true},
   119  		{"Too big proof", func(pt *Part) {
   120  			pt.Proof = merkle.SimpleProof{
   121  				Total:    1,
   122  				Index:    1,
   123  				LeafHash: make([]byte, 1024*1024),
   124  			}
   125  		}, true},
   126  	}
   127  
   128  	for _, tc := range testCases {
   129  		tc := tc
   130  		t.Run(tc.testName, func(t *testing.T) {
   131  			data := tmrand.Bytes(testPartSize * 100)
   132  			ps := NewPartSetFromData(data, testPartSize)
   133  			part := ps.GetPart(0)
   134  			tc.malleatePart(part)
   135  			assert.Equal(t, tc.expectErr, part.ValidateBasic() != nil, "Validate Basic had an unexpected result")
   136  		})
   137  	}
   138  }
   139  
   140  func TestParSetHeaderProtoBuf(t *testing.T) {
   141  	testCases := []struct {
   142  		msg     string
   143  		ps1     *PartSetHeader
   144  		expPass bool
   145  	}{
   146  		{"success empty", &PartSetHeader{}, true},
   147  		{"success",
   148  			&PartSetHeader{Total: 1, Hash: []byte("hash")}, true},
   149  	}
   150  
   151  	for _, tc := range testCases {
   152  		protoBlockID := tc.ps1.ToProto()
   153  
   154  		psh, err := PartSetHeaderFromProto(&protoBlockID)
   155  		if tc.expPass {
   156  			require.Equal(t, tc.ps1, psh, tc.msg)
   157  		} else {
   158  			require.Error(t, err, tc.msg)
   159  		}
   160  	}
   161  }