-
Notifications
You must be signed in to change notification settings - Fork 17
/
sync.go
105 lines (95 loc) · 3.2 KB
/
sync.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package trie
import (
"bytes"
"fmt"
"github.com/MadBase/MadNet/errorz"
"github.com/dgraph-io/badger/v2"
)
func GetNodeDB(txn *badger.Txn, prefix []byte, key []byte) ([]byte, error) {
key = convNilToBytes(key)
var node Hash
copy(node[:], key)
v, err := getNodeDB(txn, prefix, key)
if err != nil {
return nil, err
}
return v, nil
}
func (s *SMT) StoreSnapShotNode(txn *badger.Txn, batch []byte, root []byte, layer int) ([][]byte, int, []LeafNode, error) {
pbatch, err := s.parseBatch(batch)
if err != nil {
return nil, 0, nil, err
}
if layer == 0 {
subBatch, lvs, err := s.storeFastSyncRoot(txn, pbatch, root)
if err != nil {
return nil, 0, nil, err
}
return subBatch, layer + 1, lvs, nil
}
return s.storeFastSyncNonRoot(txn, pbatch, root, layer)
}
func (s *SMT) verifyBatchEasy(batch [][]byte, root []byte, layer int) ([]byte, bool) {
if !bytes.Equal(batch[0], []byte{0}) {
// batch is a shortcut node
return s.verifyBatch(batch, 0, 1, 256-4*layer, root, false)
}
// batch is a regular node
return s.verifyBatch(batch, 0, 4, 256-4*(layer+1), root, false)
}
func (s *SMT) getInteriorNodesEasy(batch [][]byte, root []byte, layer int) ([][]byte, bool) {
if !bytes.Equal(batch[0], []byte{0}) {
// batch is a shortcut node
subBatch, _, ok := s.getInteriorNodesNext(batch, 0, 1, 256-4*layer, root)
return subBatch, ok
}
// batch is a regular node
subBatch, _, ok := s.getInteriorNodesNext(batch, 0, 4, 256-4*(layer+1), root)
return subBatch, ok
}
func (s *SMT) storeFastSyncRoot(txn *badger.Txn, batch [][]byte, root []byte) ([][]byte, []LeafNode, error) {
_, ok := s.verifyBatchEasy(batch, root, 0)
if !ok {
return nil, nil, errorz.ErrInvalid{}.New("Error in smt.StoreFastSyncRoot at s.verifyBatchEasy(batch, root, 0)")
}
err := s.db.setNodeDB(txn, root, s.db.serializeBatch(batch))
if err != nil {
return nil, nil, err
}
subBatch, ok := s.getInteriorNodesEasy(batch, root, 0)
if !ok {
return nil, nil, errorz.ErrInvalid{}.New("Error in smt.StoreFastSyncRoot at s.getInteriorNodesEasy(batch, root, 0)")
}
lvs := s.getFinalLeafNodes(batch, 0)
return subBatch, lvs, nil
}
func (s *SMT) storeFastSyncNonRoot(txn *badger.Txn, batch [][]byte, root []byte, layer int) ([][]byte, int, []LeafNode, error) {
if layer <= 0 {
return nil, 0, nil, errorz.ErrInvalid{}.New("Error in smt.StoreFastSyncNonRoot at s.storeFastSyncNonRoot: invalid layer")
}
_, ok := s.verifyBatchEasy(batch, root, layer)
if !ok {
return nil, 0, nil, errorz.ErrInvalid{}.New(fmt.Sprintf("Error in smt.StoreFastSyncNonRoot at s.verifyBatchEasy(batch, root, layer): layer:%v", layer))
}
err := s.db.setNodeDB(txn, root, s.db.serializeBatch(batch))
if err != nil {
return nil, 0, nil, err
}
subBatch, ok := s.getInteriorNodesEasy(batch, root, layer)
if !ok {
return nil, 0, nil, errorz.ErrInvalid{}.New("Error in smt.StoreFastSyncNonRoot at s.getInteriorNodesEasy(batch, root, layer)")
}
lvs := s.getFinalLeafNodes(batch, 0)
return subBatch, layer + 1, lvs, nil
}
func (s *SMT) FinalizeSnapShotRoot(txn *badger.Txn, root []byte, height uint32) error {
err := s.db.setCommitHeightDB(txn, height)
if err != nil {
return err
}
err = s.db.setRootForHeightDB(txn, height, root)
if err != nil {
return err
}
return nil
}