mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 07:06:42 +00:00
Use errors (instead of error codes)
This commit is contained in:
parent
44a9a39c84
commit
fe85196dd6
2 changed files with 49 additions and 97 deletions
|
|
@ -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")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue