-
Notifications
You must be signed in to change notification settings - Fork 5
/
config.go
165 lines (141 loc) · 5.69 KB
/
config.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package handel
import (
"crypto/rand"
"io"
"math"
"time"
)
// Config holds the different parameters used to configure Handel.
type Config struct {
// Contributions is the minimum number of contributions a multi-signature
// must contain to be considered as valid. Handel will only output
// multi-signature containing more than this threshold of contributions. It
// must be typically above 50% of the number of Handel nodes. If not
// specified, DefaultContributionsPerc of the number of signers is used by
// default.
Contributions int
// UpdatePeriod indicates at which frequency a Handel nodes sends updates
// about its state to other Handel nodes.
UpdatePeriod time.Duration
// UpdateCount indicates the number of nodes contacted during each update at
// a given level.
UpdateCount int
// FastPath indicates how many peers should we contact when a level gets
// completed.
FastPath int
// NewBitSet returns an empty bitset. This function is used to parse
// incoming packets containing bitsets.
NewBitSet func(bitlength int) BitSet
// NewPartitioner returns the Partitioner to use for this Handel round. If
// nil, it returns the RandomBinPartitioner. The id is the ID Handel is
// responsible for and reg is the global registry of participants.
NewPartitioner func(id int32, reg Registry, Logger Logger) Partitioner
// NewEvaluatorStrategy returns the signature evaluator to use during the
// Handel round.
NewEvaluatorStrategy func(s SignatureStore, h *Handel) SigEvaluator
// NewTimeoutStrategy returns the Timeout strategy to use during the Handel
// round. By default, it uses the linear timeout strategy.
NewTimeoutStrategy func(h *Handel, levels []int) TimeoutStrategy
// Logger to use for logging handel actions
Logger Logger
// Rand provides the source of entropy for shuffling the list of nodes that
// Handel must contact at each level. If not set, golang's crypto/rand is
// used.
Rand io.Reader
// DisableShuffling is a debugging flag to not shuffle any list of nodes - it
// is much easier to detect pattern in bugs in this manner
DisableShuffling bool
// UnsafeSleepTimeOnSigVerify is a test feature a sleep time (in ms) rather than actually verifying the signatures
// Can be used to save on CPU during tests or/and to test with shorter/longer verifying time
// Set to zero by default: no sleep time. When activated the sleep replaces the verification.
// This sleep time is approximate and depends on golang and the os. The actual delay can be longer.
UnsafeSleepTimeOnSigVerify int
}
// DefaultConfig returns a default configuration for Handel.
func DefaultConfig(numberOfNodes int) *Config {
contributions := PercentageToContributions(DefaultContributionsPerc, numberOfNodes)
return &Config{
Contributions: contributions,
FastPath: DefaultCandidateCount,
UpdatePeriod: DefaultUpdatePeriod,
UpdateCount: DefaultUpdateCount,
NewBitSet: DefaultBitSet,
NewPartitioner: DefaultPartitioner,
NewEvaluatorStrategy: DefaultEvaluatorStrategy,
NewTimeoutStrategy: DefaultTimeoutStrategy,
Logger: DefaultLogger,
Rand: rand.Reader,
}
}
// DefaultContributionsPerc is the default percentage used as the required
// number of contributions in a multi-signature.
const DefaultContributionsPerc = 51
// DefaultCandidateCount is the default candidate count used by Handel.
const DefaultCandidateCount = 10
// DefaultUpdatePeriod is the default update period used by Handel.
const DefaultUpdatePeriod = 10 * time.Millisecond
// DefaultUpdateCount is the default number of candidate contacted during an
// update
const DefaultUpdateCount = 1
// DefaultBitSet returns the default implementation used by Handel, i.e. the
// WilffBitSet
var DefaultBitSet = func(bitlength int) BitSet { return NewWilffBitset(bitlength) }
// DefaultPartitioner returns the default implementation of the Partitioner used
// by Handel, i.e. BinPartitioner.
var DefaultPartitioner = func(id int32, reg Registry, logger Logger) Partitioner {
return NewBinPartitioner(id, reg, logger)
}
// DefaultEvaluatorStrategy returns an evaluator based on the store's own
// evaluation strategy.
var DefaultEvaluatorStrategy = func(store SignatureStore, h *Handel) SigEvaluator {
return newEvaluatorStore(store)
}
// DefaultTimeoutStrategy returns the default timeout strategy used by handel -
// the linear strategy with the default timeout. See DefaultLevelTimeout.
func DefaultTimeoutStrategy(h *Handel, levels []int) TimeoutStrategy {
return NewDefaultLinearTimeout(h, levels)
}
// PercentageToContributions returns the exact number of contributions needed
// out of n contributions, from the given percentage. Useful when considering
// large scale signatures as in Handel, e.g. 51%, 75%...
func PercentageToContributions(perc, n int) int {
return int(math.Ceil(float64(n) * float64(perc) / 100.0))
}
func mergeWithDefault(c *Config, size int) *Config {
c2 := *c
if c.Contributions == 0 {
n := PercentageToContributions(DefaultContributionsPerc, size)
c2.Contributions = n
}
if c.FastPath == 0 {
c2.FastPath = DefaultCandidateCount
}
if c.UpdatePeriod == 0*time.Second {
c2.UpdatePeriod = DefaultUpdatePeriod
}
if c.UpdateCount == 0 {
c2.UpdateCount = DefaultUpdateCount
}
if c.NewBitSet == nil {
c2.NewBitSet = DefaultBitSet
}
if c.NewPartitioner == nil {
c2.NewPartitioner = DefaultPartitioner
}
if c.NewEvaluatorStrategy == nil {
c2.NewEvaluatorStrategy = DefaultEvaluatorStrategy
}
if c.NewTimeoutStrategy == nil {
c2.NewTimeoutStrategy = DefaultTimeoutStrategy
}
if c.Logger == nil {
c2.Logger = DefaultLogger
}
if c.Rand == nil {
c2.Rand = rand.Reader
}
if c.DisableShuffling {
c2.DisableShuffling = true
}
return &c2
}