-
Notifications
You must be signed in to change notification settings - Fork 103
/
trie.go
99 lines (81 loc) · 2.23 KB
/
trie.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
/**
* @file
* @copyright defined in go-seele/LICENSE
*/
package light
import (
"github.com/seeleteam/go-seele/common"
"github.com/seeleteam/go-seele/common/errors"
"github.com/seeleteam/go-seele/database"
"github.com/seeleteam/go-seele/trie"
)
type odrDatabase struct {
kvs map[string][]byte
}
func newOdrDatabase() *odrDatabase {
return &odrDatabase{make(map[string][]byte)}
}
// Get implements the trie.Database interface to store trie node key-value pairs.
func (db *odrDatabase) Get(key []byte) ([]byte, error) {
return db.kvs[string(key)], nil
}
type odrRetriever interface {
retrieveWithFilter(request odrRequest, filter peerFilter) (odrResponse, error)
}
type odrTrie struct {
odr odrRetriever
root common.Hash
db *odrDatabase
dbPrefix []byte
trie *trie.Trie
blockHash common.Hash
}
func newOdrTrie(retriever odrRetriever, root common.Hash, dbPrefix []byte, blockHash common.Hash) *odrTrie {
return &odrTrie{
odr: retriever,
root: root,
db: newOdrDatabase(),
dbPrefix: dbPrefix,
blockHash: blockHash,
}
}
func (t *odrTrie) Hash() common.Hash {
panic("unsupported")
}
func (t *odrTrie) Commit(batch database.Batch) common.Hash {
panic("unsupported")
}
func (t *odrTrie) Get(key []byte) ([]byte, bool, error) {
request := &odrTriePoof{
Root: t.root,
Key: key,
}
// send ODR request to get trie proof.
filter := peerFilter{blockHash: t.blockHash}
response, err := t.odr.retrieveWithFilter(request, filter)
if err != nil {
return nil, false, errors.NewStackedError(err, "failed to retrieve ODR trie proof")
}
// insert the trie proof in databse.
for _, n := range response.(*odrTriePoof).Proof {
key := append(t.dbPrefix, []byte(n.Key)...)
t.db.kvs[string(key)] = n.Value
}
// construct the MPT for the first time.
if t.trie == nil {
t.trie, err = trie.NewTrie(t.root, t.dbPrefix, t.db)
if err != nil {
return nil, false, errors.NewStackedError(err, "failed to create trie")
}
}
return t.trie.Get(key)
}
func (t *odrTrie) Put(key, value []byte) error {
panic("unsupported")
}
func (t *odrTrie) DeletePrefix(prefix []byte) (bool, error) {
panic("unsupported")
}
func (t *odrTrie) GetProof(key []byte) (map[string][]byte, error) {
panic("unsupported")
}