2014-05-19 20:46:41 -07:00
|
|
|
package merkle
|
|
|
|
|
2014-05-20 16:33:10 -07:00
|
|
|
import (
|
2014-07-01 14:50:24 -07:00
|
|
|
"crypto/sha256"
|
|
|
|
"fmt"
|
2014-07-02 16:03:04 -07:00
|
|
|
|
2014-07-01 14:50:24 -07:00
|
|
|
. "github.com/tendermint/tendermint/binary"
|
2014-05-20 16:33:10 -07:00
|
|
|
)
|
|
|
|
|
2014-09-03 19:21:19 -07:00
|
|
|
func HashFromByteSlices(items [][]byte) []byte {
|
2014-09-07 02:21:25 -07:00
|
|
|
switch len(items) {
|
|
|
|
case 0:
|
|
|
|
panic("Cannot compute hash of empty slice")
|
|
|
|
case 1:
|
|
|
|
return items[0]
|
|
|
|
default:
|
|
|
|
var n int64
|
|
|
|
var err error
|
|
|
|
var hasher = sha256.New()
|
|
|
|
hash := HashFromByteSlices(items[0 : len(items)/2])
|
|
|
|
WriteByteSlice(hasher, hash, &n, &err)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
hash = HashFromByteSlices(items[len(items)/2:])
|
|
|
|
WriteByteSlice(hasher, hash, &n, &err)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
return hasher.Sum(nil)
|
|
|
|
}
|
2014-09-03 19:21:19 -07:00
|
|
|
}
|
|
|
|
|
2014-06-04 01:39:50 -07:00
|
|
|
/*
|
2014-09-07 02:21:25 -07:00
|
|
|
Compute a deterministic merkle hash from a list of Binary objects.
|
2014-06-04 01:39:50 -07:00
|
|
|
*/
|
2014-09-03 19:21:19 -07:00
|
|
|
func HashFromBinarySlice(items []Binary) []byte {
|
2014-07-01 14:50:24 -07:00
|
|
|
switch len(items) {
|
|
|
|
case 0:
|
|
|
|
panic("Cannot compute hash of empty slice")
|
|
|
|
case 1:
|
|
|
|
hasher := sha256.New()
|
|
|
|
_, err := items[0].WriteTo(hasher)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2014-09-03 19:21:19 -07:00
|
|
|
return hasher.Sum(nil)
|
2014-07-01 14:50:24 -07:00
|
|
|
default:
|
2014-09-03 19:21:19 -07:00
|
|
|
var n int64
|
|
|
|
var err error
|
|
|
|
var hasher = sha256.New()
|
|
|
|
hash := HashFromBinarySlice(items[0 : len(items)/2])
|
|
|
|
WriteByteSlice(hasher, hash, &n, &err)
|
2014-07-01 14:50:24 -07:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2014-09-03 19:21:19 -07:00
|
|
|
hash = HashFromBinarySlice(items[len(items)/2:])
|
|
|
|
WriteByteSlice(hasher, hash, &n, &err)
|
2014-07-01 14:50:24 -07:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2014-09-03 19:21:19 -07:00
|
|
|
return hasher.Sum(nil)
|
2014-07-01 14:50:24 -07:00
|
|
|
}
|
2014-06-04 01:39:50 -07:00
|
|
|
}
|
|
|
|
|
2014-05-20 16:33:10 -07:00
|
|
|
func PrintIAVLNode(node *IAVLNode) {
|
2014-07-01 14:50:24 -07:00
|
|
|
fmt.Println("==== NODE")
|
|
|
|
if node != nil {
|
|
|
|
printIAVLNode(node, 0)
|
|
|
|
}
|
|
|
|
fmt.Println("==== END")
|
2014-05-20 16:33:10 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
func printIAVLNode(node *IAVLNode, indent int) {
|
2014-07-01 14:50:24 -07:00
|
|
|
indentPrefix := ""
|
|
|
|
for i := 0; i < indent; i++ {
|
|
|
|
indentPrefix += " "
|
|
|
|
}
|
2014-05-27 22:31:47 -07:00
|
|
|
|
2014-07-01 14:50:24 -07:00
|
|
|
if node.right != nil {
|
|
|
|
printIAVLNode(node.rightFilled(nil), indent+1)
|
|
|
|
}
|
2014-05-27 22:31:47 -07:00
|
|
|
|
2014-07-01 14:50:24 -07:00
|
|
|
fmt.Printf("%s%v:%v\n", indentPrefix, node.key, node.height)
|
2014-05-27 22:31:47 -07:00
|
|
|
|
2014-07-01 14:50:24 -07:00
|
|
|
if node.left != nil {
|
|
|
|
printIAVLNode(node.leftFilled(nil), indent+1)
|
|
|
|
}
|
2014-05-27 22:31:47 -07:00
|
|
|
|
2014-05-20 16:33:10 -07:00
|
|
|
}
|
2014-05-23 17:49:28 -07:00
|
|
|
|
2014-05-23 23:11:22 -07:00
|
|
|
func maxUint8(a, b uint8) uint8 {
|
2014-07-01 14:50:24 -07:00
|
|
|
if a > b {
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
return b
|
2014-05-23 23:11:22 -07:00
|
|
|
}
|