Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use int64 in memoryMerkleTree #321

Merged
merged 1 commit into from
Jan 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions integration/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ func checkInclusionProofsAtIndex(index int64, logID int64, tree *merkle.InMemory
}

// Remember that the in memory tree uses 1 based leaf indices
path := tree.PathToRootAtSnapshot(int(index+1), int(treeSize))
path := tree.PathToRootAtSnapshot(index+1, treeSize)

if err = compareLogAndTreeProof(resp.Proof, path); err != nil {
// The log and tree proof don't match, details in the error
Expand Down Expand Up @@ -434,7 +434,9 @@ func checkConsistencyProof(consistParams consistencyProofParams, treeID int64, t
}

// Get the proof from the memory tree
proof := tree.SnapshotConsistency((int(consistParams.size1) * params.sequencerBatchSize), (int(consistParams.size2) * params.sequencerBatchSize))
proof := tree.SnapshotConsistency(
(consistParams.size1 * int64(params.sequencerBatchSize)),
(consistParams.size2 * int64(params.sequencerBatchSize)))

// Compare the proofs, they should be identical
return compareLogAndTreeProof(resp.Proof, proof)
Expand Down
25 changes: 25 additions & 0 deletions merkle/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package merkle

// parent returns the index of the parent node in the parent level of the tree.
func parent(leafIndex int64) int64 {
return leafIndex >> 1
}

// isRightChild returns true if the node is a right child.
func isRightChild(leafIndex int64) bool {
return leafIndex&1 == 1
}
4 changes: 2 additions & 2 deletions merkle/compact_merkle_tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,10 @@ func TestCompactVsFullTree(t *testing.T) {
imt := NewInMemoryMerkleTree(NewRFC6962TreeHasher(crypto.NewSHA256()))
nodes := make(map[string][]byte)

for i := 0; i < 1024; i++ {
for i := int64(0); i < 1024; i++ {
cmt, err := NewCompactMerkleTreeWithState(
NewRFC6962TreeHasher(crypto.NewSHA256()),
int64(imt.LeafCount()),
imt.LeafCount(),
func(depth int, index int64) ([]byte, error) {
k, err := nodeKey(depth, index)
if err != nil {
Expand Down
68 changes: 29 additions & 39 deletions merkle/memory_merkle_tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ func (t TreeEntry) HashInto(dest []byte) []byte {
// access to when testing the code and examining how it works
type TreeEntryDescriptor struct {
Value TreeEntry
XCoord int // The horizontal node coordinate
YCoord int // The vertical node coordinate
XCoord int64 // The horizontal node coordinate
YCoord int64 // The vertical node coordinate
}

// InMemoryMerkleTree holds a Merkle Tree in memory as a 2D node array
Expand Down Expand Up @@ -97,13 +97,13 @@ type InMemoryMerkleTree struct {
// at each level, all nodes computed so far, except possibly the last node,
// are fixed and will no longer change.
tree [][]TreeEntry
leavesProcessed int
levelCount int
leavesProcessed int64
levelCount int64
hasher TreeHasher
}

// isPowerOfTwoPlusOne tests whether a number is (2^x)-1 for some x. From MerkleTreeMath in C++
func isPowerOfTwoPlusOne(leafCount int) bool {
func isPowerOfTwoPlusOne(leafCount int64) bool {
if leafCount == 0 {
return false
}
Expand All @@ -116,18 +116,8 @@ func isPowerOfTwoPlusOne(leafCount int) bool {
return (((leafCount - 1) & (leafCount - 2)) == 0)
}

// parent returns the index of the parent node in the parent level of the tree.
func parent(leaf int) int {
return leaf >> 1
}

// isRightChild returns true if the node is a right child; false if it is the left (or only) child.
func isRightChild(leaf int) bool {
return (leaf & 1) != 0
}

// sibling returns the index of the node's (left or right) sibling in the same level.
func sibling(leaf int) int {
func sibling(leaf int64) int64 {
if isRightChild(leaf) {
return leaf - 1
}
Expand All @@ -145,7 +135,7 @@ func NewInMemoryMerkleTree(hasher TreeHasher) *InMemoryMerkleTree {
return &mt
}

func (mt *InMemoryMerkleTree) leafHash(leaf int) []byte {
func (mt *InMemoryMerkleTree) leafHash(leaf int64) []byte {
if leaf == 0 || leaf > mt.LeafCount() {
return nil
}
Expand All @@ -156,26 +146,26 @@ func (mt *InMemoryMerkleTree) leafHash(leaf int) []byte {
// NodeCount gets the current node count (of the lazily evaluated tree).
// Caller is responsible for keeping track of the lazy evaluation status. This will not
// update the tree.
func (mt *InMemoryMerkleTree) NodeCount(level int) int {
func (mt *InMemoryMerkleTree) NodeCount(level int64) int64 {
if mt.lazyLevelCount() <= level {
panic(fmt.Errorf("lazyLevelCount <= level in nodeCount: %d", mt.lazyLevelCount()))
}

return len(mt.tree[level])
return int64(len(mt.tree[level]))
}

// LevelCount returns the number of levels in the current Merkle tree
func (mt *InMemoryMerkleTree) LevelCount() int {
func (mt *InMemoryMerkleTree) LevelCount() int64 {
return mt.levelCount
}

// lazyLevelCount is the current level count of the lazily evaluated tree.
func (mt *InMemoryMerkleTree) lazyLevelCount() int {
return len(mt.tree)
func (mt *InMemoryMerkleTree) lazyLevelCount() int64 {
return int64(len(mt.tree))
}

// LeafCount returns the number of leaves in the tree.
func (mt *InMemoryMerkleTree) LeafCount() int {
func (mt *InMemoryMerkleTree) LeafCount() int64 {
if len(mt.tree) == 0 {
return 0
}
Expand All @@ -195,7 +185,7 @@ func (mt *InMemoryMerkleTree) root() TreeEntry {
}

// lastNode returns the last node of the given level in the tree.
func (mt *InMemoryMerkleTree) lastNode(level int) TreeEntry {
func (mt *InMemoryMerkleTree) lastNode(level int64) TreeEntry {
levelNodes := mt.NodeCount(level)

if levelNodes < 1 {
Expand All @@ -211,7 +201,7 @@ func (mt *InMemoryMerkleTree) addLevel() {
}

// pushBack appends a node to the level.
func (mt *InMemoryMerkleTree) pushBack(level int, treeEntry TreeEntry) {
func (mt *InMemoryMerkleTree) pushBack(level int64, treeEntry TreeEntry) {
if mt.lazyLevelCount() <= level {
panic(fmt.Errorf("lazyLevelCount <= level in pushBack: %d", mt.lazyLevelCount()))
}
Expand All @@ -220,7 +210,7 @@ func (mt *InMemoryMerkleTree) pushBack(level int, treeEntry TreeEntry) {
}

// popBack pops (removes and returns) the last node of the level.
func (mt *InMemoryMerkleTree) popBack(level int) {
func (mt *InMemoryMerkleTree) popBack(level int64) {
if len(mt.tree[level]) < 1 {
panic(errors.New("no nodes to pop in popBack"))
}
Expand All @@ -235,11 +225,11 @@ func (mt *InMemoryMerkleTree) popBack(level int) {
//
// Returns the position of the leaf in the tree. Indexing starts at 1,
// so position = number of leaves in the tree after this update.
func (mt *InMemoryMerkleTree) AddLeaf(leafData []byte) (int, TreeEntry) {
func (mt *InMemoryMerkleTree) AddLeaf(leafData []byte) (int64, TreeEntry) {
return mt.addLeafHash(mt.hasher.HashLeaf(leafData))
}

func (mt *InMemoryMerkleTree) addLeafHash(leafData []byte) (int, TreeEntry) {
func (mt *InMemoryMerkleTree) addLeafHash(leafData []byte) (int64, TreeEntry) {
treeEntry := TreeEntry{}
treeEntry.hash = leafData

Expand Down Expand Up @@ -277,7 +267,7 @@ func (mt *InMemoryMerkleTree) CurrentRoot() TreeEntry {
//
// Returns an empty string if the snapshot requested is in the future
// (i.e., the tree is not large enough).
func (mt *InMemoryMerkleTree) RootAtSnapshot(snapshot int) TreeEntry {
func (mt *InMemoryMerkleTree) RootAtSnapshot(snapshot int64) TreeEntry {
if snapshot == 0 {
return TreeEntry{mt.hasher.HashEmpty()}
}
Expand All @@ -296,7 +286,7 @@ func (mt *InMemoryMerkleTree) RootAtSnapshot(snapshot int) TreeEntry {
}

// updateToSnapshot updates the tree to a given snapshot (if necessary), returns the root.
func (mt *InMemoryMerkleTree) updateToSnapshot(snapshot int) TreeEntry {
func (mt *InMemoryMerkleTree) updateToSnapshot(snapshot int64) TreeEntry {
if snapshot == 0 {
return TreeEntry{mt.hasher.HashEmpty()}
}
Expand All @@ -318,7 +308,7 @@ func (mt *InMemoryMerkleTree) updateToSnapshot(snapshot int) TreeEntry {
}

// Update tree, moving up level-by-level.
level := 0
level := int64(0)
// Index of the first node to be processed at the current level.
firstNode := mt.leavesProcessed
// Index of the last node.
Expand Down Expand Up @@ -359,8 +349,8 @@ func (mt *InMemoryMerkleTree) updateToSnapshot(snapshot int) TreeEntry {

// recomputePastSnapshot returns the root of the tree as it was for a past snapshot.
// If node is not nil, additionally records the rightmost node for the given snapshot and node_level.
func (mt *InMemoryMerkleTree) recomputePastSnapshot(snapshot int, nodeLevel int, node *TreeEntry) TreeEntry {
level := 0
func (mt *InMemoryMerkleTree) recomputePastSnapshot(snapshot int64, nodeLevel int64, node *TreeEntry) TreeEntry {
level := int64(0)
// Index of the rightmost node at the current level for this snapshot.
lastNode := snapshot - 1

Expand Down Expand Up @@ -426,7 +416,7 @@ func (mt *InMemoryMerkleTree) recomputePastSnapshot(snapshot int, nodeLevel int,
// is one below the root.
// Returns an empty slice if the tree is not large enough
// or the leaf index is 0.
func (mt *InMemoryMerkleTree) PathToCurrentRoot(leaf int) []TreeEntryDescriptor {
func (mt *InMemoryMerkleTree) PathToCurrentRoot(leaf int64) []TreeEntryDescriptor {
return mt.PathToRootAtSnapshot(leaf, mt.LeafCount())
}

Expand All @@ -437,7 +427,7 @@ func (mt *InMemoryMerkleTree) PathToCurrentRoot(leaf int) []TreeEntryDescriptor
// last element is one below the root. Returns an empty slice if
// the leaf index is 0, the snapshot requested is in the future or
// the snapshot tree is not large enough.
func (mt *InMemoryMerkleTree) PathToRootAtSnapshot(leaf int, snapshot int) []TreeEntryDescriptor {
func (mt *InMemoryMerkleTree) PathToRootAtSnapshot(leaf int64, snapshot int64) []TreeEntryDescriptor {
if leaf > snapshot || snapshot > mt.LeafCount() || leaf == 0 {
return []TreeEntryDescriptor{}
}
Expand All @@ -447,15 +437,15 @@ func (mt *InMemoryMerkleTree) PathToRootAtSnapshot(leaf int, snapshot int) []Tre

// pathFromNodeToRootAtSnapshot returns the path from a node at a given level
// (both indexed starting with 0) to the root at a given snapshot.
func (mt *InMemoryMerkleTree) pathFromNodeToRootAtSnapshot(node int, level int, snapshot int) []TreeEntryDescriptor {
func (mt *InMemoryMerkleTree) pathFromNodeToRootAtSnapshot(node int64, level int64, snapshot int64) []TreeEntryDescriptor {
var path []TreeEntryDescriptor

if snapshot == 0 {
return path
}

// Index of the last node.
lastNode := (snapshot - 1) >> uint(level)
lastNode := (snapshot - 1) >> uint64(level)

if level >= mt.levelCount || node > lastNode || snapshot > mt.LeafCount() {
return path
Expand Down Expand Up @@ -496,14 +486,14 @@ func (mt *InMemoryMerkleTree) pathFromNodeToRootAtSnapshot(node int, level int,
// Returns a slice of node hashes, ordered according to levels.
// Returns an empty slice if snapshot1 is 0, snapshot 1 >= snapshot2,
// or one of the snapshots requested is in the future.
func (mt *InMemoryMerkleTree) SnapshotConsistency(snapshot1 int, snapshot2 int) []TreeEntryDescriptor {
func (mt *InMemoryMerkleTree) SnapshotConsistency(snapshot1 int64, snapshot2 int64) []TreeEntryDescriptor {
var proof []TreeEntryDescriptor

if snapshot1 == 0 || snapshot1 >= snapshot2 || snapshot2 > mt.LeafCount() {
return proof
}

level := 0
level := int64(0)
// Rightmost node in snapshot1.
node := snapshot1 - 1

Expand Down