github.com/quantosnetwork/Quantos@v0.0.0-20220306172517-e20b28c5a29a/merkle/trie.go (about)

     1  package merkle
     2  
     3  import (
     4  	"encoding/hex"
     5  	"encoding/json"
     6  	"fmt"
     7  	"github.com/davecgh/go-spew/spew"
     8  	"github.com/zeebo/blake3"
     9  	"go.uber.org/atomic"
    10  	"log"
    11  	"strings"
    12  	"sync"
    13  	"time"
    14  )
    15  
    16  /*
    17  
    18  	@dev Info about the merkle trie structure
    19  
    20  	Blake3 Merkle tree (sum512)
    21  	Leaf size: 128 [64]bytes
    22  	Root size: 128 [64]bytes
    23  	MergeLeaf size: 256 [128]bytes
    24  
    25  	ML = MergeLeaf (Node hash)
    26  	C = count
    27  	L = Leaf
    28  	mr merkle root
    29  	H = Blake3 hasher sum 512
    30  	++ = all of that type
    31  
    32  	f(mr) = H SUM(ML++)
    33  	ML = (LH[1] + LH[2])
    34  	LH = H(L)
    35  
    36  */
    37  
    38  type Hash [64]byte
    39  
    40  type MerkleTrie interface {
    41  	Get(key []byte) ([]byte, bool)
    42  	Put(key []byte, value []byte)
    43  	Del(key []byte, value []byte) bool
    44  }
    45  
    46  type treeBuilder struct {
    47  	treeContents []TreeContent
    48  	size         int
    49  	height       int
    50  	leavesTotal  int
    51  	state        TreeStates
    52  }
    53  
    54  type TreeContent [][]byte
    55  
    56  type Tree struct {
    57  	MerkleRoot []byte
    58  	TrunkRoots [][]byte
    59  	TreeHash   []byte
    60  	Branches   map[int]*branch
    61  	Hashable
    62  }
    63  
    64  type branch struct {
    65  	// a branch can have multiple branches attached to it before there are leaves
    66  	hasChildren      bool
    67  	hasParent        bool
    68  	multipleBranches []*branch
    69  	childCount       atomic.Bool
    70  	leftLeaf         *TreeLeaf
    71  	rightLeaf        *TreeLeaf
    72  	// in real life that would be the length of the branch
    73  	byteLen int
    74  	Hashable
    75  }
    76  
    77  type TreeLeaf struct {
    78  	parentBranch *branch
    79  
    80  	content TreeContent
    81  	context string
    82  	Hashable
    83  }
    84  
    85  func (tc TreeContent) hash() Hash {
    86  	b := tc.Bytes()
    87  	return hashFn(b)
    88  }
    89  
    90  func (tc TreeContent) Bytes() []byte {
    91  	b, _ := json.Marshal(tc)
    92  	return b
    93  }
    94  
    95  type Hashable interface {
    96  	hash() Hash
    97  }
    98  
    99  type EmptyLeaf struct {
   100  }
   101  
   102  func (e EmptyLeaf) hash() Hash {
   103  	return hashFn(nil)
   104  }
   105  
   106  func (b *branch) hash() Hash {
   107  	var l, r [64]byte
   108  	l = b.leftLeaf.hash()
   109  	r = b.rightLeaf.hash()
   110  	return hashFn(append(l[:], r[:]...))
   111  }
   112  
   113  func (l *TreeLeaf) hash() Hash {
   114  	return hashFn(l.content.Bytes())
   115  }
   116  
   117  func hashFn(data []byte) Hash {
   118  	return blake3.Sum512(data)
   119  }
   120  
   121  func (h Hash) String() string {
   122  	return hex.EncodeToString(h[:])
   123  }
   124  
   125  func NewTree(contents []TreeContent) {
   126  
   127  	tree := &Tree{}
   128  	c := make([]TreeContent, len(contents))
   129  	copy(c, contents)
   130  
   131  	tree.Branches = map[int]*branch{}
   132  	b := tree.newBuilder(c)
   133  	b._prepare(tree)
   134  	if b.state == DONE {
   135  		fmt.Printf("merkle trie done: %v", tree)
   136  	}
   137  	hashes := tree.Walk()
   138  	mr := tree.hashMerkleRoot(hashes)
   139  	log.Printf("tree merkle root: %v", hex.EncodeToString(mr))
   140  
   141  }
   142  
   143  func (m *Tree) newBuilder(contents []TreeContent) *treeBuilder {
   144  	builder := &treeBuilder{}
   145  	builder.height = 0
   146  	builder.state = 0
   147  	builder.size = 0
   148  	builder.leavesTotal = 0
   149  	builder.treeContents = contents
   150  	return builder
   151  }
   152  
   153  func (m *Tree) Build(contents []Hashable) {
   154  
   155  }
   156  
   157  func (m *Tree) Put(key []byte, value []byte) {}
   158  func (m *Tree) Get(key []byte) ([]byte, bool) {
   159  	return nil, false
   160  }
   161  func (m *Tree) Del(key []byte, value []byte) bool {
   162  	return false
   163  }
   164  
   165  type TreeStates int
   166  
   167  const (
   168  	NONE TreeStates = iota
   169  	WORKING
   170  	DONE
   171  	ERRORED
   172  	IDLE
   173  	VERIFIED
   174  	ARCHIVED
   175  	ARCHIVING
   176  	SNAPSHOT
   177  	WALKING
   178  	HASHING
   179  )
   180  
   181  func (tb *treeBuilder) _prepare(m *Tree) {
   182  
   183  	tb.state = IDLE
   184  	//  contentLen := len(tb.treeContents)
   185  	for i := range tb.treeContents {
   186  		tb.state = WORKING
   187  		tb._addSingleBranch(m)
   188  		// now we get the height to add the leaves
   189  		height := tb.height - 1
   190  		if height < len(tb.treeContents)-1 {
   191  			tb._addLeaves(m, height, tb.treeContents[i], tb.treeContents[i+1])
   192  		} else {
   193  			tb._addLeaves(m, height, tb.treeContents[i], tb.treeContents[i-1])
   194  		}
   195  	}
   196  	tb.state = DONE
   197  }
   198  
   199  func (tb *treeBuilder) _addSingleBranch(m *Tree) {
   200  	branch := &branch{}
   201  	branch.hasChildren = false
   202  	branch.hasParent = false
   203  	branch.leftLeaf = new(TreeLeaf)
   204  	branch.rightLeaf = new(TreeLeaf)
   205  
   206  	m.Branches[tb.height] = branch
   207  	tb.height++
   208  }
   209  
   210  func (tb *treeBuilder) _addLeaves(m *Tree, height int, left, right Hashable) {
   211  	m.Branches[height].leftLeaf = new(TreeLeaf)
   212  	m.Branches[height].leftLeaf.content = left.(TreeContent)
   213  	m.Branches[height].rightLeaf = new(TreeLeaf)
   214  	m.Branches[height].rightLeaf.content = right.(TreeContent)
   215  
   216  }
   217  
   218  func (t *Tree) Print() {
   219  
   220  	merkleRoot := t.hash()
   221  	fmt.Println(merkleRoot)
   222  
   223  }
   224  
   225  func (t *Tree) hash() Hash {
   226  	return Hash{}
   227  }
   228  
   229  type treeWalkFunction = func(b *branch, h func([]byte))
   230  
   231  var TreeReceipt []byte
   232  
   233  func (t *Tree) Walk() []map[int][]string {
   234  	branches := t.Branches
   235  	state := IDLE
   236  	//height := 0
   237  	var hashes []map[int][]string
   238  	hashes = make([]map[int][]string, len(branches))
   239  	for i := 0; i < len(branches); i++ {
   240  		state = WALKING
   241  		//height = i
   242  		branch := branches[i]
   243  
   244  		state = HASHING
   245  		left := branch.leftLeaf.hash()
   246  		right := branch.rightLeaf.hash()
   247  
   248  		leaves := map[int][]string{}
   249  		leaves[0] = []string{left.String(), right.String()}
   250  		hashes = append(hashes, leaves)
   251  		/*hashes[height][0] = left.String()
   252  		hashes[height][1] = right.String()*/
   253  
   254  	}
   255  
   256  	state = DONE
   257  
   258  	if state == DONE {
   259  		return hashes
   260  	}
   261  	return t.Walk()
   262  	//return nil
   263  }
   264  
   265  func (t *Tree) hashMerkleRoot(hashes []map[int][]string) []byte {
   266  
   267  	var mu sync.Mutex
   268  
   269  	root := &struct {
   270  		height    int
   271  		timestamp int64
   272  		hash      []byte
   273  		String    string
   274  	}{}
   275  
   276  	hasher := blake3.New()
   277  	//	hasher.Reset()
   278  
   279  	root.height = 0
   280  	root.timestamp = time.Now().UnixNano()
   281  	hs := make([][]byte, len(hashes))
   282  	mu.Lock()
   283  	defer mu.Unlock()
   284  	for i := 0; i < len(hashes)-1; i++ {
   285  
   286  		toJoin := hashes[i][0]
   287  		hsj := strings.Join(toJoin, "")
   288  
   289  		if hsj != "" {
   290  			spew.Dump(hsj)
   291  			hs[i] = []byte(hsj)
   292  			hasher.Write(hs[i])
   293  			root.height += i
   294  		}
   295  	}
   296  	rhash := blake3.Sum512(hasher.Sum(nil))
   297  	root.hash = rhash[:]
   298  	root.String = hex.EncodeToString(root.hash)
   299  
   300  	t.MerkleRoot = root.hash
   301  	return t.MerkleRoot
   302  }