package merkle import ( "bytes" . "github.com/tendermint/tendermint/common" . "github.com/tendermint/tendermint/common/test" "fmt" "testing" ) type testItem []byte func (tI testItem) Hash() []byte { return []byte(tI) } func TestSimpleProof(t *testing.T) { numItems := 100 items := make([]Hashable, numItems) for i := 0; i < numItems; i++ { items[i] = testItem(RandBytes(32)) } rootHash := SimpleHashFromHashables(items) proofs := SimpleProofsFromHashables(items) // For each item, check the trail. for i, item := range items { itemHash := item.Hash() proof := proofs[i] // Verify success ok := proof.Verify(itemHash, rootHash) if !ok { t.Errorf("Verification failed for index %v.", i) } // Wrong item index should make it fail proof.Index += 1 { ok = proof.Verify(itemHash, rootHash) if ok { t.Errorf("Expected verification to fail for wrong index %v.", i) } } proof.Index -= 1 // Trail too long should make it fail origInnerHashes := proof.InnerHashes proof.InnerHashes = append(proof.InnerHashes, RandBytes(32)) { ok = proof.Verify(itemHash, rootHash) if ok { t.Errorf("Expected verification to fail for wrong trail length.") } } proof.InnerHashes = origInnerHashes // Trail too short should make it fail proof.InnerHashes = proof.InnerHashes[0 : len(proof.InnerHashes)-1] { ok = proof.Verify(itemHash, rootHash) if ok { t.Errorf("Expected verification to fail for wrong trail length.") } } proof.InnerHashes = origInnerHashes // Mutating the itemHash should make it fail. ok = proof.Verify(MutateByteSlice(itemHash), rootHash) if ok { t.Errorf("Expected verification to fail for mutated leaf hash") } // Mutating the rootHash should make it fail. ok = proof.Verify(itemHash, MutateByteSlice(rootHash)) if ok { t.Errorf("Expected verification to fail for mutated root hash") } } } func TestKVPairs(t *testing.T) { // NOTE: in alphabetical order for convenience. m := map[string]interface{}{} m["bytez"] = []byte("hizz") // 0 m["light"] = "shadow" // 1 m["one"] = 1 // 2 m["one_u64"] = uint64(1) // 3 m["struct"] = struct { // 4 A int B int }{0, 1} kvPairsH := MakeSortedKVPairs(m) // rootHash := SimpleHashFromHashables(kvPairsH) proofs := SimpleProofsFromHashables(kvPairsH) // Some manual tests if !bytes.Equal(proofs[1].LeafHash, KVPair{"light", "shadow"}.Hash()) { t.Errorf("\"light\": proof failed") fmt.Printf("%v\n%X", proofs[0], KVPair{"light", "shadow"}.Hash()) } if !bytes.Equal(proofs[2].LeafHash, KVPair{"one", 1}.Hash()) { t.Errorf("\"one\": proof failed") } if !bytes.Equal(proofs[4].LeafHash, KVPair{"struct", struct { A int B int }{0, 1}}.Hash()) { t.Errorf("\"struct\": proof failed") } }