forked from algorand/go-algorand
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtypes.go
146 lines (129 loc) · 3.86 KB
/
types.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright (C) 2019 Algorand, Inc.
// This file is part of go-algorand
//
// go-algorand is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// go-algorand is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with go-algorand. If not, see <https://www.gnu.org/licenses/>.
package agreement
import (
"time"
"github.com/algorand/go-algorand/config"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/logging"
)
var filterTimeout = 2 * config.Protocol.SmallLambda
var deadlineTimeout = config.Protocol.BigLambda + config.Protocol.SmallLambda
var partitionStep = next + 3
var recoveryExtraTimeout = config.Protocol.SmallLambda
// FilterTimeout is the duration of the first agreement step.
func FilterTimeout() time.Duration {
return filterTimeout
}
// DeadlineTimeout is the duration of the second agreement step.
func DeadlineTimeout() time.Duration {
return deadlineTimeout
}
type (
// round denotes a single round of the agreement protocol
round = basics.Round
// step is a sequence number denoting distinct stages in Algorand
step uint64
// period is used to track progress with a given round in the protocol
period uint64
)
// Algorand 2.0 steps
const (
propose step = iota
soft
cert
next
)
const (
late step = 253 + iota
redo
down
)
func (s step) nextVoteRanges() (lower, upper time.Duration) {
extra := recoveryExtraTimeout // eg 2500 ms
lower = deadlineTimeout // eg 17500 ms (15000 + 2500)
upper = lower + extra // eg 20000 ms
for i := next; i < s; i++ {
extra *= 2
lower = upper
upper = lower + extra
}
// e.g. if s == 14
// extra = 2 ^ 8 * 2500ms = 256 * 2.5 = 512 + 128 = 640s
return lower, upper
}
// ReachesQuorum compares the current weight to the thresholds appropriate for the step,
// to determine if we've reached a quorum.
func (s step) reachesQuorum(proto config.ConsensusParams, weight uint64) bool {
switch s {
case propose:
logging.Base().Warn("Called Propose.ReachesQuorum")
return false
case soft:
return weight >= proto.SoftCommitteeThreshold
case cert:
return weight >= proto.CertCommitteeThreshold
case late:
return weight >= proto.LateCommitteeThreshold
case redo:
return weight >= proto.RedoCommitteeThreshold
case down:
return weight >= proto.DownCommitteeThreshold
default:
return weight >= proto.NextCommitteeThreshold
}
}
// threshold returns the threshold necessary for the given step.
// Do not compare values to the output of this function directly;
// instead, use s.reachesQuorum to avoid off-by-one errors.
func (s step) threshold(proto config.ConsensusParams) uint64 {
switch s {
case propose:
logging.Base().Warn("Called propose.threshold")
return 0
case soft:
return proto.SoftCommitteeThreshold
case cert:
return proto.CertCommitteeThreshold
case late:
return proto.LateCommitteeThreshold
case redo:
return proto.RedoCommitteeThreshold
case down:
return proto.DownCommitteeThreshold
default:
return proto.NextCommitteeThreshold
}
}
// CommitteeSize returns the size of the committee required for the step
func (s step) committeeSize(proto config.ConsensusParams) uint64 {
switch s {
case propose:
return proto.NumProposers
case soft:
return proto.SoftCommitteeSize
case cert:
return proto.CertCommitteeSize
case late:
return proto.LateCommitteeSize
case redo:
return proto.RedoCommitteeSize
case down:
return proto.DownCommitteeSize
default:
return proto.NextCommitteeSize
}
}