From 5c6973699496b17f47fce05d0bddd201445feea4 Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Fri, 17 Oct 2014 01:01:59 -0700 Subject: [PATCH] Add PartSet test. --- consensus/part_set.go | 22 +++++++++++ consensus/part_set_test.go | 79 +++++++++++++++++++++++++++++++++++++- merkle/util.go | 4 +- merkle/util_test.go | 35 +++++++++++++++++ 4 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 merkle/util_test.go diff --git a/consensus/part_set.go b/consensus/part_set.go index a7724795..036ea8a3 100644 --- a/consensus/part_set.go +++ b/consensus/part_set.go @@ -4,7 +4,9 @@ import ( "bytes" "crypto/sha256" "errors" + "fmt" "io" + "strings" "sync" . "github.com/tendermint/tendermint/binary" @@ -59,6 +61,26 @@ func (pt *Part) Hash() []byte { } } +func (pt *Part) String() string { + return pt.StringWithIndent("") +} + +func (pt *Part) StringWithIndent(indent string) string { + trailStrings := make([]string, len(pt.Trail)) + for i, hash := range pt.Trail { + trailStrings[i] = fmt.Sprintf("%X", hash) + } + return fmt.Sprintf(`Part{ +%s Index: %v +%s Trail: +%s %v +%s}`, + indent, pt.Index, + indent, + indent, strings.Join(trailStrings, "\n"+indent+" "), + indent) +} + //------------------------------------- type PartSet struct { diff --git a/consensus/part_set_test.go b/consensus/part_set_test.go index ce766088..7e7ad8b2 100644 --- a/consensus/part_set_test.go +++ b/consensus/part_set_test.go @@ -1,9 +1,86 @@ package consensus import ( + "bytes" + "io/ioutil" "testing" + + . "github.com/tendermint/tendermint/common" ) func TestBasicPartSet(t *testing.T) { - // XXX this is fun! + + // Construct random data of size partSize * 100 + data := RandBytes(partSize * 100) + + partSet := NewPartSetFromData(data) + if len(partSet.RootHash()) == 0 { + t.Error("Expected to get rootHash") + } + if partSet.Total() != 100 { + t.Errorf("Expected to get 100 parts, but got %v", partSet.Total()) + } + if !partSet.IsComplete() { + t.Errorf("PartSet should be complete") + } + + // Test adding parts to a new partSet. + partSet2 := NewPartSetFromMetadata(partSet.Total(), partSet.RootHash()) + + for i := uint16(0); i < partSet.Total(); i++ { + part := partSet.GetPart(i) + //t.Logf("\n%v", part) + added, err := partSet2.AddPart(part) + if !added || err != nil { + t.Errorf("Failed to add part %v, error: %v", i, err) + } + } + + if !bytes.Equal(partSet.RootHash(), partSet2.RootHash()) { + t.Error("Expected to get same rootHash") + } + if partSet2.Total() != 100 { + t.Errorf("Expected to get 100 parts, but got %v", partSet2.Total()) + } + if !partSet2.IsComplete() { + t.Errorf("Reconstructed PartSet should be complete") + } + + // Reconstruct data, assert that they are equal. + data2Reader := partSet2.GetReader() + data2, err := ioutil.ReadAll(data2Reader) + if err != nil { + t.Errorf("Error reading data2Reader: %v", err) + } + if !bytes.Equal(data, data2) { + t.Errorf("Got wrong data.") + } + +} + +func TestWrongTrail(t *testing.T) { + + // Construct random data of size partSize * 100 + data := RandBytes(partSize * 100) + partSet := NewPartSetFromData(data) + + // Test adding a part with wrong data. + partSet2 := NewPartSetFromMetadata(partSet.Total(), partSet.RootHash()) + + // Test adding a part with wrong trail. + part := partSet.GetPart(0) + part.Trail[0][0] += byte(0x01) + added, err := partSet2.AddPart(part) + if added || err == nil { + t.Errorf("Expected to fail adding a part with bad trail.") + } + + // Test adding a part with wrong bytes. + part = partSet.GetPart(1) + part.Bytes[0] += byte(0x01) + added, err = partSet2.AddPart(part) + if added || err == nil { + t.Errorf("Expected to fail adding a part with bad bytes.") + } + } diff --git a/merkle/util.go b/merkle/util.go index 56f808e2..ab32740b 100644 --- a/merkle/util.go +++ b/merkle/util.go @@ -190,7 +190,7 @@ func HashTrailForIndex(hashTree [][]byte, index int) [][]byte { trail = append(trail, hashTree[next]) index = (index + next) / 2 - offset += stride + offset += stride / 2 stride *= 2 } @@ -216,7 +216,7 @@ func VerifyHashTrailForIndex(index int, leafHash []byte, trail [][]byte, rootHas tempHash = HashFromTwoHashes(trail[i], tempHash) } index = (index + next) / 2 - offset += stride + offset += stride / 2 stride *= 2 } diff --git a/merkle/util_test.go b/merkle/util_test.go new file mode 100644 index 00000000..a23ba67a --- /dev/null +++ b/merkle/util_test.go @@ -0,0 +1,35 @@ +package merkle + +import ( + . "github.com/tendermint/tendermint/common" + + "testing" +) + +// TODO: Actually test. All this does is help debug. +// consensus/part_set tests some of this functionality. +func TestHashTreeMerkleTrail(t *testing.T) { + + numHashes := 5 + + // Make some fake "hashes". + hashes := make([][]byte, numHashes) + for i := 0; i < numHashes; i++ { + hashes[i] = RandBytes(32) + t.Logf("hash %v\t%X\n", i, hashes[i]) + } + + hashTree := HashTreeFromHashes(hashes) + for i := 0; i < len(hashTree); i++ { + t.Logf("tree %v\t%X\n", i, hashTree[i]) + } + + for i := 0; i < numHashes; i++ { + t.Logf("trail %v\n", i) + trail := HashTrailForIndex(hashTree, i) + for j := 0; j < len(trail); j++ { + t.Logf("index: %v, hash: %X\n", j, trail[j]) + } + } + +}