You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 throws TypeError if the provided JSON is invalid
hash(): 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, Hash in the case of MPTs). Returns undefined if the element was not in the provided JSON
has(index): returns true if the requested index is in the collection view, false otherwise
[MPT only?] maybeHas(index): returns true if the specified index may be present in the collection (not necessarily in the current view). Hence, the proof of absence for index is !view.maybeHas(index).
Symbol.iterator and entries(): returns the iterator for [index, value] pairs in the view, like the JS Map (maybe, pull other methods from Map too, e.g., forEach, keys and values).
Internal construction
Merkle tree
Recursive definition:
MT<ItemType>=oneOf({stub: Hash,// "collapsed" part of the treebranch: {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 left child in any branch cannot be a sprout
(optional) The tree must be non-redundant, e.g., a branch cannot have both stub children
Methods:
get(index) can be implemented by traversing the tree from the root
hash() 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 parentnode: oneOf({stub: Hash,// "collapsed" part of the treebranch: {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:
bits may be empty only for the root node
For branches, left.bits must start with 0 and right.bits with 1
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 branch cannot have both stub children
Methods:
get(index) and maybeHas(index) can be implemented by traversing the tree from the root
hash() can be implemented by traversing the tree from the leaves
The text was updated successfully, but these errors were encountered:
@boguslavsky@defuz @gisochre Are you OK with this interface? Maybe, ListView or MapView need to have other methods? As for JSON for constructors, I see it slightly more verbose than it is currently, in order to be parseable within generic Exonum type spec:
I've implemented a PoC for type defs, which includes possibility of tree implementation, among other things. Very rough, but you probably get the general idea.
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 throwsTypeError
if the provided JSON is invalidhash()
: returns the hash of the collection, calculated as per the current algorithmlength
(read-only property): returns the length of the underlying collectionget(index)
: gets the element at the specified index (integer for MTs,Hash
in the case of MPTs). Returnsundefined
if the element was not in the provided JSONhas(index)
: returnstrue
if the requested index is in the collection view,false
otherwisemaybeHas(index)
: returnstrue
if the specified index may be present in the collection (not necessarily in the current view). Hence, the proof of absence forindex
is!view.maybeHas(index)
.Symbol.iterator
andentries()
: returns the iterator for[index, value]
pairs in the view, like the JSMap
(maybe, pull other methods fromMap
too, e.g.,forEach
,keys
andvalues
).Internal construction
Merkle tree
Recursive definition:
Consistency checks:
length
left
child in any branch cannot be asprout
branch
cannot have bothstub
childrenMethods:
get(index)
can be implemented by traversing the tree from the roothash()
can be implemented by traversing the tree from the leavesMerkle Patricia tree
Recursive definition:
bits
may be woven into all type variants if deemed necessary.Consistency checks:
bits
may be empty only for the root nodeleft.bits
must start with0
andright.bits
with1
branch
cannot have bothstub
childrenMethods:
get(index)
andmaybeHas(index)
can be implemented by traversing the tree from the roothash()
can be implemented by traversing the tree from the leavesThe text was updated successfully, but these errors were encountered: