phoreproject / graphene

Phore Synapse working repository
MIT License
13 stars 6 forks source link

Implement Tree, PartialTree and Witness #68

Open meyer9 opened 5 years ago

meyer9 commented 5 years ago

These data types are for shard storage.

Data Types

Tree

Partial Tree

PartialTrees are not really trees. They're simply the state root and witnesses. The witnesses allow certain parts of the tree to be updated or verified.

Witness

Witnesses are trees that detail certain parts of the tree. Witnesses do not have to contain the whole tree, but just certain branches needed to update information about the tree or verify information about the tree. Partial trees only contain leaf nodes (values) if the verifier needs to verify a key, but not if they just need to update the key.

Example Code

tree = Tree()

tree.set(1, 1)
tree.set(2, 2)
tree.set(3, 3)
tree.set(4, 4)

hashTree0 = tree.hash()

witnesses = []
witnesses.append(tree.setWithWitness(1, 2))
witnesses.append(tree.setWithWitness(2, 3))
witnesses.append(tree.deleteWithWitness(3))
witnesses.append(tree.proveKey(4))

hashTree1 = tree.hash()

partialTree = PartialTree(hashTree0, witnesses)
partialTree.set(1, 2)
partialTree.set(2, 3)
partialTree.delete(3)

assert partialTree.verify(4, 4)

assert partialTree.hash() == hashTree1

partialTree.set(3, 4) # error: no witness for setting key 3
partialTree.delete(4) # error: no witness for deleting key 4
partialTree.verify(4, 5) # error: no witness proving key 4 is set to 5

Diagram

This is a diagram to explain how updating/verifying keys should work.

tree(1)

Currently, the tree root can be calculated by calculating: (using x = 1)

l0 = hash(x || 2)
l1 = hash(l0 || l0_sibling)
root = hash(l1 || l2_sibling)

We can prove 1 is in the root by verifying that when 1 is plugged in for x, the state root is returned.

We can also update the tree by changing 1 to another value, yielding a new state root.

The PartialTree should also keep track of changed values which should take priority over proving in the tree. Because the state root will be different after modifying the tree at all, proving will have to use the original state root. Proving a value that was not modified will obviously verify. Proving a value that was modified will verify because the modified value is cached.

In the diagram above, the yellow node is the node to update/verify and the red nodes are the witnesses needed.

The witness tree should store witnesses on the opposite branch to where they actually are in the tree. In the example above, the witnesses are all on the right branch on the tree. The witness tree should actually store them on the left branches of the tree. (Hopefully this doesn't conflict with how a CSMT is defined).