-
Notifications
You must be signed in to change notification settings - Fork 3
/
state_booting.go
107 lines (89 loc) · 2.58 KB
/
state_booting.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
106
107
package basicstates
import (
"github.com/pkg/errors"
"github.com/rs/zerolog"
"github.com/spikeekips/mitum/base"
"github.com/spikeekips/mitum/base/node"
"github.com/spikeekips/mitum/isaac"
"github.com/spikeekips/mitum/storage"
"github.com/spikeekips/mitum/storage/blockdata"
"github.com/spikeekips/mitum/util"
"github.com/spikeekips/mitum/util/logging"
)
type BootingState struct {
*logging.Logging
*BaseState
local node.Local
database storage.Database
blockdata blockdata.Blockdata
policy *isaac.LocalPolicy
suffrage base.Suffrage
}
func NewBootingState(
local node.Local,
db storage.Database,
bd blockdata.Blockdata,
policy *isaac.LocalPolicy,
suffrage base.Suffrage,
) *BootingState {
return &BootingState{
Logging: logging.NewLogging(func(c zerolog.Context) zerolog.Context {
return c.Str("module", "basic-booting-state")
}),
BaseState: NewBaseState(base.StateBooting),
local: local,
database: db,
blockdata: bd,
policy: policy,
suffrage: suffrage,
}
}
func (st *BootingState) Enter(sctx StateSwitchContext) (func() error, error) {
callback := EmptySwitchFunc
if i, err := st.BaseState.Enter(sctx); err != nil {
return nil, err
} else if i != nil {
callback = i
}
if _, err := storage.CheckBlock(st.database, st.policy.NetworkID()); err != nil {
st.Log().Error().Err(err).Msg("something wrong to check blocks")
if !errors.Is(err, util.NotFoundError) {
return nil, err
}
st.Log().Debug().Msg("empty blocks found; cleaning up")
// NOTE empty block
if err := blockdata.Clean(st.database, st.blockdata, false); err != nil {
return nil, err
}
return st.enterSyncing(callback)
}
if st.suffrage.IsInside(st.local.Address()) {
return func() error {
if err := callback(); err != nil {
return err
}
st.Log().Debug().Msg("block checked; moves to joining")
return st.NewStateSwitchContext(base.StateJoining)
}, nil
}
return func() error {
if err := callback(); err != nil {
return err
}
st.Log().Debug().Msg("block checked; none-suffrage node moves to syncing")
return st.NewStateSwitchContext(base.StateSyncing)
}, nil
}
func (st *BootingState) enterSyncing(callback func() error) (func() error, error) {
if len(st.syncableChannels()) < 1 {
st.Log().Debug().Msg("empty blocks; no channels for syncing; can not sync")
return nil, errors.Errorf("empty blocks, but no channels for syncing; can not sync")
}
st.Log().Debug().Msg("empty blocks; will sync")
return func() error {
if err := callback(); err != nil {
return err
}
return st.NewStateSwitchContext(base.StateSyncing)
}, nil
}