Documentation ¶
Index ¶
- Constants
- Variables
- func GenerateProof(provenLeafIndices map[uint64]bool, treeCache CacheReader) (sortedProvenLeafIndices []uint64, provenLeaves, proofNodes [][]byte, err error)
- func GetNode(c CacheReader, nodePos Position) ([]byte, error)
- func GetSha256Parent(lChild, rChild []byte) []byte
- func NewPositionsIterator(positions Set) *positionsIterator
- func NewSparseBoolStack(trueIndices Set) *sparseBoolStack
- func ValidatePartialTree(leafIndices []uint64, leaves, proof [][]byte, expectedRoot []byte, ...) (bool, error)
- type CacheReader
- type CacheWriter
- type HashFunc
- type LayerReadWriter
- type LayerReader
- type LayerWriter
- type LeafIterator
- type ParkingSnapshot
- type Position
- type Set
- type Tree
- type TreeBuilder
- func (tb TreeBuilder) Build() (*Tree, error)
- func (tb TreeBuilder) WithCacheWriter(cacheWriter CacheWriter) TreeBuilder
- func (tb TreeBuilder) WithHashFunc(hash HashFunc) TreeBuilder
- func (tb TreeBuilder) WithLeavesToProve(leavesToProves map[uint64]bool) TreeBuilder
- func (tb TreeBuilder) WithMinHeight(minHeight uint) TreeBuilder
- type Validator
Examples ¶
Constants ¶
const MaxUint = ^uint(0)
const NodeSize = shared.NodeSize
Variables ¶
var EmptyNode node
var ErrMissingValueAtBaseLayer = errors.New("reader for base layer must be included")
var PaddingValue = node{ OnProvenPath: false, // contains filtered or unexported fields }
PaddingValue is used for padding unbalanced trees. This value should not be permitted at the leaf layer to distinguish padding from actual members of the tree.
var RootHeightFromWidth = shared.RootHeightFromWidth
Functions ¶
func GenerateProof ¶
func GetNode ¶
func GetNode(c CacheReader, nodePos Position) ([]byte, error)
GetNode reads the node at the requested Position from the cache or calculates it if not available.
func GetSha256Parent ¶
func NewPositionsIterator ¶
func NewPositionsIterator(positions Set) *positionsIterator
func NewSparseBoolStack ¶
func NewSparseBoolStack(trueIndices Set) *sparseBoolStack
Types ¶
type CacheReader ¶
type CacheReader = shared.CacheReader
type CacheWriter ¶
type CacheWriter = shared.CacheWriter
type LayerReadWriter ¶
type LayerReadWriter = shared.LayerReadWriter
type LayerReader ¶
type LayerReader = shared.LayerReader
type LayerWriter ¶
type LayerWriter = shared.LayerWriter
type LeafIterator ¶
type LeafIterator struct {
// contains filtered or unexported fields
}
type ParkingSnapshot ¶
type ParkingSnapshot [][]byte
func ValidatePartialTreeWithParkingSnapshots ¶
func ValidatePartialTreeWithParkingSnapshots(leafIndices []uint64, leaves, proof [][]byte, expectedRoot []byte, hash HashFunc, ) (bool, []ParkingSnapshot, error)
ValidatePartialTree uses leafIndices, leaves and proof to calculate the merkle root of the tree and then compares it to expectedRoot. Additionally, it reconstructs the parked nodes when each proven leaf was originally added to the tree and returns a list of snapshots. This method is ~15% slower than ValidatePartialTree.
type Set ¶
func (Set) AsSortedSlice ¶
type Tree ¶
type Tree struct {
// contains filtered or unexported fields
}
Tree calculates a merkle tree root. It can optionally calculate a proof, or partial tree, for leaves defined in advance. Leaves are appended to the tree incrementally. It uses O(log(n)) memory to calculate the root and O(k*log(n)) (k being the number of leaves to prove) memory to calculate proofs.
Tree is NOT thread safe.
Example ¶
Annotated example explaining how to use this package
// First, we create a cache writer with caching policy and layer read-writer factory: cacheWriter := cache.NewWriter(cache.MinHeightPolicy(0), cache.MakeSliceReadWriterFactory()) // We then initialize the tree: tree, err := NewTreeBuilder().WithCacheWriter(cacheWriter).Build() if err != nil { fmt.Println("Error while building the tree:", err.Error()) return } // We add the leaves one-by-one: for i := uint64(0); i < 8; i++ { err := tree.AddLeaf(NewNodeFromUint64(i)) if err != nil { fmt.Println("Error while adding a leaf:", err.Error()) return } } // After adding some leaves we can access the root of the tree: fmt.Println(tree.Root()) // 89a0f1577268cc19b0a39c7a69f804fd140640c699585eb635ebb03c06154cce // If we need to generate a proof, we could derive the proven leaves from the root. Here we create a static set: leavesToProve := setOf(0, 4, 7) // We get a cache reader from the cache writer: cacheReader, err := cacheWriter.GetReader() if err != nil { fmt.Println("Error while getting cache reader:", err.Error()) return } // We pass the cache into GenerateProof along with the set of leaves to prove: sortedProvenLeafIndices, provenLeaves, proof, err := GenerateProof(leavesToProve, cacheReader) if err != nil { fmt.Println("Error while getting generating proof:", err.Error()) return } // We now have access to a sorted list of proven leaves, the values of those leaves and the Merkle proof for them: fmt.Println(sortedProvenLeafIndices) // 0 4 7 fmt.Println(nodes(provenLeaves)) // 0000 0400 0700 fmt.Println(nodes(proof)) // 0100 0094 0500 0600 // We can validate these values using ValidatePartialTree: valid, err := ValidatePartialTree(sortedProvenLeafIndices, provenLeaves, proof, tree.Root(), GetSha256Parent) if err != nil { fmt.Println("Error while validating proof:", err.Error()) return } fmt.Println(valid) // true /*************************************************** | 89a0 | | ba94 633b | | cb59 .0094. bd50 fa67 | | =0000=.0100. 0200 0300 =0400=.0500..0600.=0700= | ***************************************************/
Output:
func NewCachingTree ¶
func NewCachingTree(cacheWriter CacheWriter) (*Tree, error)
func (*Tree) AddLeaf ¶
AddLeaf incorporates a new leaf to the state of the tree. It updates the state required to eventually determine the root of the tree and also updates the proof, if applicable.
func (*Tree) GetParkedNodes ¶
func (*Tree) Proof ¶
Proof returns a partial tree proving the membership of leaves that were passed in leavesToProve when the tree was initialized. For a single proved leaf this is a standard merkle proof (one sibling per layer of the tree from the leaves to the root, excluding the proved leaf and root). If the tree is unbalanced (num. of leaves is not a power of 2) it will perform padding on-the-fly.
func (*Tree) Root ¶
Root returns the root of the tree. If the tree is unbalanced (num. of leaves is not a power of 2) it will perform padding on-the-fly.
func (*Tree) RootAndProof ¶
RootAndProof returns the root of the tree and a partial tree proving the membership of leaves that were passed in leavesToProve when the tree was initialized. For a single proved leaf this is a standard merkle proof (one sibling per layer of the tree from the leaves to the root, excluding the proved leaf and root). If the tree is unbalanced (num. of leaves is not a power of 2) it will perform padding on-the-fly.
func (*Tree) SetParkedNodes ¶
type TreeBuilder ¶
type TreeBuilder struct {
// contains filtered or unexported fields
}
func NewTreeBuilder ¶
func NewTreeBuilder() TreeBuilder
func (TreeBuilder) Build ¶
func (tb TreeBuilder) Build() (*Tree, error)
func (TreeBuilder) WithCacheWriter ¶
func (tb TreeBuilder) WithCacheWriter(cacheWriter CacheWriter) TreeBuilder
func (TreeBuilder) WithHashFunc ¶
func (tb TreeBuilder) WithHashFunc(hash HashFunc) TreeBuilder
func (TreeBuilder) WithLeavesToProve ¶
func (tb TreeBuilder) WithLeavesToProve(leavesToProves map[uint64]bool) TreeBuilder
func (TreeBuilder) WithMinHeight ¶
func (tb TreeBuilder) WithMinHeight(minHeight uint) TreeBuilder