-
Notifications
You must be signed in to change notification settings - Fork 0
/
reachabilitymanager.go
86 lines (72 loc) · 2.65 KB
/
reachabilitymanager.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
package reachabilitymanager
import (
"github.com/sedraxnet/sedraxd/domain/consensus/model"
"github.com/sedraxnet/sedraxd/domain/consensus/model/externalapi"
)
// reachabilityManager maintains a structure that allows to answer
// reachability queries in sub-linear time
type reachabilityManager struct {
databaseContext model.DBReader
reachabilityDataStore model.ReachabilityDataStore
ghostdagDataStore model.GHOSTDAGDataStore
reindexSlack uint64
reindexWindow uint64
}
// New instantiates a new reachabilityManager
func New(
databaseContext model.DBReader,
ghostdagDataStore model.GHOSTDAGDataStore,
reachabilityDataStore model.ReachabilityDataStore,
) model.ReachabilityManager {
return &reachabilityManager{
databaseContext: databaseContext,
ghostdagDataStore: ghostdagDataStore,
reachabilityDataStore: reachabilityDataStore,
reindexSlack: defaultReindexSlack,
reindexWindow: defaultReindexWindow,
}
}
// AddBlock adds the block with the given blockHash into the reachability tree.
func (rt *reachabilityManager) AddBlock(stagingArea *model.StagingArea, blockHash *externalapi.DomainHash) error {
// Allocate a new reachability data
newReachabilityData := newReachabilityTreeData()
rt.stageData(stagingArea, blockHash, newReachabilityData)
ghostdagData, err := rt.ghostdagDataStore.Get(rt.databaseContext, stagingArea, blockHash, false)
if err != nil {
return err
}
reindexRoot, err := rt.reindexRoot(stagingArea)
if err != nil {
return err
}
// Insert the node into the selected parent's reachability tree
err = rt.addChild(stagingArea, ghostdagData.SelectedParent(), blockHash, reindexRoot)
if err != nil {
return err
}
// Add the block to the futureCoveringSets of all the blocks
// in the merget set
mergeSet := make([]*externalapi.DomainHash, len(ghostdagData.MergeSetBlues())+len(ghostdagData.MergeSetReds()))
copy(mergeSet, ghostdagData.MergeSetBlues())
copy(mergeSet[len(ghostdagData.MergeSetBlues()):], ghostdagData.MergeSetReds())
for _, current := range mergeSet {
err = rt.insertToFutureCoveringSet(stagingArea, current, blockHash)
if err != nil {
return err
}
}
return nil
}
func (rt *reachabilityManager) Init(stagingArea *model.StagingArea) error {
hasReachabilityData, err := rt.reachabilityDataStore.HasReachabilityData(rt.databaseContext, stagingArea, model.VirtualGenesisBlockHash)
if err != nil {
return err
}
if hasReachabilityData {
return nil
}
newReachabilityData := newReachabilityTreeData()
rt.stageData(stagingArea, model.VirtualGenesisBlockHash, newReachabilityData)
rt.stageReindexRoot(stagingArea, model.VirtualGenesisBlockHash)
return nil
}