-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
108 lines (90 loc) · 2.29 KB
/
main.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
108
package scp
type Value []byte
type Slot struct {
Index uint64
Value
}
type Config struct {
NodeID string
CurrentSlot uint64
Validator Validator
Combiner Combiner
Ledger Ledger
SlotsLoader SlotsLoader
QuorumSlices []*QuorumSlice
}
type Consensus struct {
nominationProtocol
ballotProtocol
outputMessages chan *Message
}
func New(cfg Config) *Consensus {
outputMessages := make(chan *Message, 1000000)
link := make(chan protocolMessage)
candidates := make(chan Value, 1000)
nominationProtocol := nominationProtocol{
slotIndex: cfg.CurrentSlot,
id: cfg.NodeID,
validator: cfg.Validator,
combiner: cfg.Combiner,
quorumSlices: cfg.QuorumSlices,
proposals: newSuspendableValueCh(),
inputMessages: make(chan *Message, 1000000),
outputMessages: outputMessages,
ballotProtocol: link,
}
nominationProtocol.init(cfg.CurrentSlot, candidates)
ballotProtocol := ballotProtocol{
slotIndex: cfg.CurrentSlot,
id: cfg.NodeID,
ledger: cfg.Ledger,
loader: cfg.SlotsLoader,
quorumSlices: cfg.QuorumSlices,
inputMessages: make(chan *Message, 1000000),
outputMessages: outputMessages,
candidates: candidates,
nominationProtocol: link,
catchUpDone: make(chan struct{}),
}
ballotProtocol.init(cfg.CurrentSlot)
return &Consensus{
nominationProtocol: nominationProtocol,
ballotProtocol: ballotProtocol,
outputMessages: outputMessages,
}
}
func (c *Consensus) Run() {
go c.nominationProtocol.run()
go c.ballotProtocol.run()
}
func (c *Consensus) Propose(v Value) {
c.nominationProtocol.proposals.in <- v
}
func (c *Consensus) InputMessage(m *Message) {
switch m.Type {
case VoteNominate, AcceptNominate:
c.nominationProtocol.inputMessages <- m
case VotePrepare, AcceptPrepare, VoteCommit, AcceptCommit:
c.ballotProtocol.inputMessages <- m
}
}
func (c *Consensus) OutputMessage() *Message {
return <-c.outputMessages
}
type suspendableValueCh struct {
in chan Value
out chan Value
}
func newSuspendableValueCh() suspendableValueCh {
ch := suspendableValueCh{
in: make(chan Value),
}
ch.out = ch.in
return ch
}
func (p *suspendableValueCh) resume() {
p.out = p.in
}
func (p *suspendableValueCh) suspend() {
p.out = nil
}