From fe85196dd634d88d2a672fc907f38d3da2f7a43b Mon Sep 17 00:00:00 2001 From: Oren Date: Sun, 26 Mar 2017 12:00:20 +0300 Subject: [PATCH] Use errors (instead of error codes) --- swarm/storage/binarymerkle.go | 64 +++++++++++------------ swarm/storage/binarymerkle_test.go | 82 +++++++----------------------- 2 files changed, 49 insertions(+), 97 deletions(-) diff --git a/swarm/storage/binarymerkle.go b/swarm/storage/binarymerkle.go index 972dea17cc..edc5e4faaf 100644 --- a/swarm/storage/binarymerkle.go +++ b/swarm/storage/binarymerkle.go @@ -58,9 +58,9 @@ func (t BTree) Root() []byte { // if incorrectly built or modified. // Checks the rep invariants func (t BTree) Validate() error { - count, height, error := t.root.validate() - if error != nil { - return error + count, height, err := t.root.validate() + if err != nil { + return err } if count != t.count { return fmt.Errorf("Incorrect count. Was %d, should be %d", t.count, count) @@ -122,7 +122,7 @@ func rootHash(count uint64, data []byte) []byte { h.Reset() h.Write(data) binary.Write(h, binary.LittleEndian, count) - return h.Sum(make([]byte, 0)) + return h.Sum(nil) } func makeHash(left, right *node) []byte { @@ -156,21 +156,21 @@ func GetHeight(count uint64) int { // BMT - The BMT Representation of the data // ROOT - BMT Root // Count - Numers of leafs at the BMT -// error - if exist validation(-1) count(-2) ok(0) -func BuildBMT(h Hasher, data []byte, segmentsize int) (bmt *BTree, roor *Root, count int, errorcode int) { +// error - +func BuildBMT(h Hasher, data []byte, segmentsize int) (bmt *BTree, roor *Root, count int, err error) { blocks := splitData(data, segmentsize) hashFunc = h leafcount := len(blocks) tree := Build(blocks) - err := tree.Validate() + err = tree.Validate() if err != nil { - return nil, nil, 0, -1 + return nil, nil, 0, errors.New("Validation error") } if tree.Count() != uint64(leafcount) { - return nil, nil, 0, -2 + return nil, nil, 0, errors.New("Validation count error") } - return tree, &Root{uint64(leafcount), tree.Root()}, leafcount, 0 + return tree, &Root{uint64(leafcount), tree.Root()}, leafcount, nil //r := Root{uint64(count), tree.Root()} } @@ -260,30 +260,29 @@ type Root struct { } // Proves the inclusion of an element at the given index with the value thats the first entry in proof -func (r *Root) CheckProof(h Hasher, proof [][]byte, index int) bool { +func (r *Root) CheckProof(h Hasher, proof [][]byte, index int) (bool, error) { hashFunc = h - t_height := GetHeight(r.Count) - root, ok := checkNode(t_height, proof, uint64(index), r.Count) + theight := GetHeight(r.Count) + var root, ok, err = checkNode(theight, proof, uint64(index), r.Count) base := rootHash(r.Count, root) - return ok && bytes.Equal(r.Base, base) + return ok && bytes.Equal(r.Base, base), err } -func checkNode(height int, proof [][]byte, index, count uint64) ([]byte, bool) { +func checkNode(height int, proof [][]byte, index uint64, count uint64) (hash []byte, ok bool, err error) { if len(proof) == 0 { - fmt.Println("Empty") - return nil, false + return nil, false, errors.New("checkNode : proof is empty") } if count <= index { fmt.Println("bad count", count, index) - return nil, false + return nil, false, fmt.Errorf("bad count %d at index %d", count, index) } if height == 1 { if index != 0 || len(proof) != 1 { fmt.Println("BAD", index, proof) - return nil, false + return nil, false, fmt.Errorf("BAD %d %d", index, proof) } - return proof[0], true + return proof[0], true, nil } childIndex := index >> uint(height-2) @@ -291,7 +290,7 @@ func checkNode(height int, proof [][]byte, index, count uint64) ([]byte, bool) { nextIndex := index & mask var data []byte - var ok bool + //var ok bool h := hashFunc() h.Reset() @@ -301,7 +300,7 @@ func checkNode(height int, proof [][]byte, index, count uint64) ([]byte, bool) { if childIndex == 1 { nextCount = count & mask h.Write(proof[last]) - data, ok = checkNode(height-1, proof[:last], nextIndex, nextCount) + data, ok, err = checkNode(height-1, proof[:last], nextIndex, nextCount) h.Write(data) } else { nextCount = count @@ -309,39 +308,38 @@ func checkNode(height int, proof [][]byte, index, count uint64) ([]byte, bool) { nextCount = ^mask } if count == nextCount { - data, ok = checkNode(height-1, proof, nextIndex, nextCount) + data, ok, err = checkNode(height-1, proof, nextIndex, nextCount) h.Write(data) } else { - data, ok = checkNode(height-1, proof[:last], nextIndex, nextCount) + data, ok, err = checkNode(height-1, proof[:last], nextIndex, nextCount) h.Write(data) h.Write(proof[last]) } } - hash := h.Sum(make([]byte, 0)) - return hash, ok + hash = h.Sum(make([]byte, 0)) + return hash, ok, nil } -// ShakeHash defines the interface to hash functions that -// support arbitrary-length output. +// BMTHash defines the interface to hash functions that type BMTHash interface { // Write absorbs more data into the hash's state. It panics if input is // written to it after output has been read from it. io.Writer // Read reads more output from the hash; reading affects the hash's - // state. (ShakeHash.Read is thus very different from Hash.Sum) + // state. // It never returns an error. io.Reader - // Clone returns a copy of the ShakeHash in its current state. + // Clone returns a copy of the BMTHash in its current state. Clone() BMTHash - // Reset resets the ShakeHash to its initial state. + // Reset resets the BMTHash to its initial state. Reset() } -// Reset clears the internal state by zeroing the sponge state and +// Reset clears the internal state func (d *state) Reset() { d.root = Root{Count: 0, Base: nil} d.btree = BTree{count: 0, root: nil, rootHash: nil} @@ -354,7 +352,7 @@ func (d *state) Write(p []byte) (written int, err error) { d.btree = *tree d.root = *r - if err1 != 0 { + if err1 != nil { err = errors.New("bmt write error") } diff --git a/swarm/storage/binarymerkle_test.go b/swarm/storage/binarymerkle_test.go index 28faea5032..bfd7650219 100644 --- a/swarm/storage/binarymerkle_test.go +++ b/swarm/storage/binarymerkle_test.go @@ -2,53 +2,17 @@ package storage import ( "fmt" - "io/ioutil" "testing" "github.com/ethereum/go-ethereum/crypto/sha3" ) -func TestGetHeight(t *testing.T) { - data := [][2]int{ - {0, 0}, - {1, 1}, - {2, 2}, - {3, 3}, - {4, 3}, - {255, 9}, - {256, 9}, - {257, 10}, - } - for _, v := range data { - h := GetHeight(uint64(v[0])) - if !(v[1] == h) { - t.Errorf("GetHeight(%d)!=%d (was %d)", v[0], v[1], h) - } - } -} - -func TestGetHeight2(t *testing.T) { - for i := 1; i < 1000; i++ { - h := GetHeight(uint64(i)) - upperBound := 1 << uint(h-1) - lowerBound := (1 << uint(h-2)) + 1 - if i < lowerBound { - t.Errorf("GetHeight(%d) too high: %d", i, h) - } - if i > upperBound { - t.Errorf("GetHeight(%d) too low: %d", i, h) - } - } -} - func TestBuildBMT3(t *testing.T) { // Grab some data to make the tree out of, and partition - data, err := ioutil.ReadFile("binarymerkle_test.go") // assume testdata exists - if err != nil { - fmt.Println(err) - return - } + data := make([]byte, 4096) + tdata := testDataReader(4096) + tdata.Read(data) var thashFunc = MakeHashFunc("BMTSHA3") var h = thashFunc() h.Reset() @@ -73,35 +37,28 @@ func TestBuildBMT3(t *testing.T) { func TestBuildBMT(t *testing.T) { // Grab some data to make the tree out of, and partition - data, err := ioutil.ReadFile("binarymerkle_test.go") // assume testdata exists - if err != nil { - fmt.Println(err) - return - } - + data := make([]byte, 4096) + tdata := testDataReader(4096) + tdata.Read(data) tree, r, count, err1 := BuildBMT(sha3.NewKeccak256, data, 1) - switch err1 { - case -1: - - t.Errorf("BMT Validation error") + if err1 != nil { + fmt.Println(err1) return - case -2: - t.Errorf("BMT leaf count validation error") - return - case 0: - fmt.Println("Build BMT OK ", count) } fmt.Println(tree.Root()) + //var ok bool + for i := 0; i < count; i++ { p := tree.InclusionProof(i) fmt.Println(p) - ok := r.CheckProof(sha3.NewKeccak256, p, i) - if !ok { + ok, err := r.CheckProof(sha3.NewKeccak256, p, i) + + if !ok || (err != nil) { t.Errorf("proof %d failed", i) } } @@ -110,12 +67,9 @@ func TestBuildBMT(t *testing.T) { func TestBuildBMT2(t *testing.T) { - // Grab some data to make the tree out of, and partition - data, err := ioutil.ReadFile("binarymerkle_test.go") // assume testdata exists - if err != nil { - fmt.Println(err) - return - } + data := make([]byte, 4096) + tdata := testDataReader(4096) + tdata.Read(data) fmt.Println(len(data)) blocks := splitData(data, 2) @@ -142,8 +96,8 @@ func TestBuildBMT2(t *testing.T) { fmt.Println(p) - ok := r.CheckProof(sha3.NewKeccak256, p, i) - if !ok { + ok, err := r.CheckProof(sha3.NewKeccak256, p, i) + if !ok || (err != nil) { t.Errorf("proof %d failed", i) } }