-
Notifications
You must be signed in to change notification settings - Fork 33
Open
Labels
Description
Merkle (Patricia) tree proofs essentially prove that a certain element (or several elements) belongs to a certain data collection (list in the case of Merkle trees; map in the case of MPTs). Essentially, a MTs and MPTs are views of lists or maps, in which some elements are unknown. So, it could be logical to implement them as such.
Interface
Thus, it could be logical to have the following interface for MTs and MPTs:
constructor(json): creates an MT or MPT based on JSON retrieved from the server. Verifies the internal structure of the tree (see below) and throwsTypeErrorif the provided JSON is invalidhash(): returns the hash of the collection, calculated as per the current algorithm- [MT only?]
length(read-only property): returns the length of the underlying collection get(index): gets the element at the specified index (integer for MTs,Hashin the case of MPTs). Returnsundefinedif the element was not in the provided JSONhas(index): returnstrueif the requested index is in the collection view,falseotherwise- [MPT only?]
maybeHas(index): returnstrueif the specified index may be present in the collection (not necessarily in the current view). Hence, the proof of absence forindexis!view.maybeHas(index). Symbol.iteratorandentries(): returns the iterator for[index, value]pairs in the view, like the JSMap(maybe, pull other methods fromMaptoo, e.g.,forEach,keysandvalues).
Internal construction
Merkle tree
Recursive definition:
MT<ItemType> = oneOf({
stub: Hash, // "collapsed" part of the tree
branch: { left: MT<ItemType>, right: MT<ItemType> },
sprout: { child: MT<ItemType> }, // a non-branching intermediate node
val: ItemType, // value
});
ListView<ItemType> = {
root: MT<ItemType>,
length: Uint64
};Consistency checks:
- All values are at the depth expected by
length - All stubs are at the depth not exceeding the same depth
- The
leftchild in any branch cannot be asprout - (optional) The tree must be non-redundant, e.g., a
branchcannot have bothstubchildren
Methods:
get(index)can be implemented by traversing the tree from the roothash()can be implemented by traversing the tree from the leaves
Merkle Patricia tree
Recursive definition:
MPT<ItemType> = {
bits: BitSlice, // key bits connecting the node to its parent
node: oneOf({
stub: Hash, // "collapsed" part of the tree
branch: { left: MPT<ItemType>, right: MPT<ItemType> },
val: ItemType // value
})
};
MapView<ItemType> = MPT<ItemType>;bits may be woven into all type variants if deemed necessary.
Consistency checks:
bitsmay be empty only for the root node- For branches,
left.bitsmust start with0andright.bitswith1 - Key length of all values must be as expected (256 bits)
- Key length of all stubs must not exceed 256 bits
- (optional) The tree must be non-redundant, e.g., a
branchcannot have bothstubchildren
Methods:
get(index)andmaybeHas(index)can be implemented by traversing the tree from the roothash()can be implemented by traversing the tree from the leaves