-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathoptions.go
More file actions
416 lines (370 loc) · 11.1 KB
/
Copy pathoptions.go
File metadata and controls
416 lines (370 loc) · 11.1 KB
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
package observer
import (
"context"
"fmt"
"math"
"time"
"github.com/filecoin-project/go-f3/blssig"
"github.com/filecoin-project/go-f3/gpbft"
"github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/multiformats/go-multiaddr"
madns "github.com/multiformats/go-multiaddr-dns"
)
type Option func(*options) error
type options struct {
host host.Host
connectivityBootstrapPeers []peer.AddrInfo
messageBufferSize int
subBufferSize int
networkName gpbft.NetworkName
connectivityCheckInterval time.Duration
connectivityConcurrency int
connectivityBootstrappersThreshold int
connectivityDHTThreshold int
connectivityLotusPeersThreshold int
connectivityLotusAPIEndpoints []string
queryServerListenAddress string
queryServerReadTimeout time.Duration
rotatePath string
rotateInterval time.Duration
retention time.Duration
maxRetentionSize int64
pubSub *pubsub.PubSub
pubSubValidatorDisabled bool
dataSourceName string
maxBatchSize int
maxBatchDelay time.Duration
ecPeriod time.Duration
initialPowerTableCID cid.Cid
finalityCertsClientRequestTimeout time.Duration
finalityCertsStorePath string
finalityCertsVerifier gpbft.Verifier
finalityCertsInitialPollInterval time.Duration
finalityCertsMinPollInterval time.Duration
finalityCertsMaxPollInterval time.Duration
chainExchangeBufferSize int
chainExchangeMaxMessageAge time.Duration
}
func newOptions(opts ...Option) (*options, error) {
opt := options{
messageBufferSize: 100,
subBufferSize: 1024,
connectivityCheckInterval: 10 * time.Second,
connectivityConcurrency: 10,
connectivityDHTThreshold: 5,
queryServerReadTimeout: 5 * time.Second,
rotatePath: ".",
rotateInterval: 10 * time.Minute,
retention: -1,
maxBatchSize: 1000,
maxBatchDelay: time.Minute,
ecPeriod: 30 * time.Second,
finalityCertsClientRequestTimeout: 10 * time.Second,
finalityCertsVerifier: blssig.VerifierWithKeyOnG1(),
finalityCertsInitialPollInterval: 10 * time.Second,
finalityCertsMinPollInterval: 30 * time.Second,
finalityCertsMaxPollInterval: 2 * time.Minute,
chainExchangeBufferSize: 1000,
chainExchangeMaxMessageAge: 3 * time.Minute,
maxRetentionSize: 0,
}
for _, apply := range opts {
if err := apply(&opt); err != nil {
return nil, err
}
}
var err error
if opt.host == nil {
opt.host, err = libp2p.New()
if err != nil {
return nil, err
}
}
if opt.networkName == "" {
return nil, fmt.Errorf("network name must be provided")
}
return &opt, nil
}
func WithHost(h host.Host) Option {
return func(o *options) error {
o.host = h
return nil
}
}
func WithPubSubValidatorDisabled(disable bool) Option {
return func(o *options) error {
o.pubSubValidatorDisabled = disable
return nil
}
}
func WithNetworkName(name gpbft.NetworkName) Option {
return func(o *options) error {
o.networkName = name
return nil
}
}
// WithBootstrapPeers sets the bootstrap peers for connectivity. The threshold
// is the minimum connectivity threshold below which the bootstrap peers are
// used to improve connectivity. Disabled if the threshold is set to 0 or no peers are provided.
//
// See: WithBootstrapPeersFromString.
func WithBootstrapPeers(threshold int, peers ...peer.AddrInfo) Option {
return func(o *options) error {
o.connectivityBootstrapPeers = peers
o.connectivityBootstrappersThreshold = threshold
return nil
}
}
// WithBootstrapPeersFromString sets the bootstrap peers for connectivity. The
// threshold is the minimum connectivity threshold below which the bootstrap
// peers are used to improve connectivity. Disabled if the threshold is set to 0
// or no peers are provided.
//
// Any provided string addresses are resolved with a timeout of 10 seconds. An
// error is returned if any one of given addresses fail to resolve.
//
// See: WithBootstrapPeers.
func WithBootstrapPeersFromString(threshold int, peers ...string) Option {
const maddrResolutionTimeout = 10 * time.Second
return func(o *options) error {
o.connectivityBootstrapPeers = make([]peer.AddrInfo, 0, len(peers))
for _, v := range peers {
maddr, err := multiaddr.NewMultiaddr(v)
if err != nil {
return fmt.Errorf("invalid multiaddr: %q: %w", v, err)
}
ctx, cancel := context.WithTimeout(context.Background(), maddrResolutionTimeout)
defer cancel()
resolved, err := madns.Resolve(ctx, maddr)
if err != nil {
return fmt.Errorf("failed to resolve multiaddr: %q: %w", v, err)
}
for _, maddr := range resolved {
addr, err := peer.AddrInfoFromP2pAddr(maddr)
if err != nil {
return fmt.Errorf("invalid bootstrap address: %q: %w", v, err)
}
o.connectivityBootstrapPeers = append(o.connectivityBootstrapPeers, *addr)
}
}
o.connectivityBootstrappersThreshold = threshold
return nil
}
}
// WithDHTPeerDiscovery sets the threshold for peer discovery via Filecoin DHT.
// Disabled if set to zero.
func WithDHTPeerDiscovery(threshold int) Option {
return func(o *options) error {
o.connectivityDHTThreshold = threshold
return nil
}
}
// WithLotusPeerDiscovery configures peer discovery via Filecoin.NetPeers API
// call through a list of lotus daemons. Disabled if threshold is set to 0 or no
// lotusDaemon endpoints are provided.
func WithLotusPeerDiscovery(threshold int, apiEndpoints ...string) Option {
return func(o *options) error {
o.connectivityLotusPeersThreshold = threshold
o.connectivityLotusAPIEndpoints = apiEndpoints
return nil
}
}
func WithMessageBufferSize(messageBufferSize int) Option {
return func(o *options) error {
o.messageBufferSize = messageBufferSize
return nil
}
}
func WithSubscriptionBufferSize(subBufferSize int) Option {
return func(o *options) error {
o.subBufferSize = subBufferSize
return nil
}
}
func WithConnectivityCheckInterval(interval time.Duration) Option {
return func(o *options) error {
o.connectivityCheckInterval = interval
return nil
}
}
// WithMaxConcurrentConnectionAttempts sets the maximum number of concurrent
// connection attempts to make to peers. This is used to limit the number of
// concurrent connection attempts to make to peers when the connectivity
// threshold is below the specified threshold for any one of the configured
// connectivity repair mechanisms. The default is 50.
func WithMaxConcurrentConnectionAttempts(limit int) Option {
return func(o *options) error {
if limit < 1 {
return fmt.Errorf("max concurrent connection attempts must be greater than 0")
}
o.connectivityConcurrency = limit
return nil
}
}
func WithConnectivityMinPeers(count int) Option {
return func(o *options) error {
o.connectivityBootstrappersThreshold = count
return nil
}
}
func WithQueryServerListenAddress(addr string) Option {
return func(o *options) error {
o.queryServerListenAddress = addr
return nil
}
}
func WithQueryServerReadTimeout(d time.Duration) Option {
return func(o *options) error {
o.queryServerReadTimeout = d
return nil
}
}
func WithRotatePath(path string) Option {
return func(o *options) error {
o.rotatePath = path
return nil
}
}
func WithRotateInterval(d time.Duration) Option {
return func(o *options) error {
o.rotateInterval = d
return nil
}
}
func WithRetention(retention time.Duration) Option {
return func(o *options) error {
o.retention = retention
return nil
}
}
// WithMaxRetentionSize sets the maximum size of the retention directory.
// This is weakly enforced, and the directory may grow larger than this
// size. If the directory grows larger than this size, the oldest files
// will be deleted until the directory size is below this size.
func WithMaxRetentionSize(size uint64) Option {
return func(o *options) error {
if size > math.MaxInt64 {
return fmt.Errorf("max retention size must be less than or equal to %d", math.MaxInt64)
}
o.maxRetentionSize = int64(size)
return nil
}
}
func WithDataSourceName(dataSourceName string) Option {
return func(o *options) error {
o.dataSourceName = dataSourceName
return nil
}
}
func WithPubSub(ps *pubsub.PubSub) Option {
return func(o *options) error {
o.pubSub = ps
return nil
}
}
func WithMaxBatchSize(size int) Option {
return func(o *options) error {
o.maxBatchSize = size
return nil
}
}
func WithMaxBatchDelay(d time.Duration) Option {
return func(o *options) error {
if d < 0 {
return fmt.Errorf("max batch delay must be greater than or equal to 0")
}
o.maxBatchDelay = d
return nil
}
}
func WithECPeriod(d time.Duration) Option {
return func(o *options) error {
if d <= 0 {
return fmt.Errorf("ec period must be greater than 0")
}
o.ecPeriod = d
return nil
}
}
func WithInitialPowerTableCID(c cid.Cid) Option {
return func(o *options) error {
if c == cid.Undef {
return fmt.Errorf("initial power table CID must be defined")
}
o.initialPowerTableCID = c
return nil
}
}
func WithFinalityCertsClientRequestTimeout(d time.Duration) Option {
return func(o *options) error {
if d <= 0 {
return fmt.Errorf("finality certs client request timeout must be greater than 0")
}
o.finalityCertsClientRequestTimeout = d
return nil
}
}
func WithFinalityCertsStorePath(path string) Option {
return func(o *options) error {
o.finalityCertsStorePath = path
return nil
}
}
func WithFinalityCertsVerifier(v gpbft.Verifier) Option {
return func(o *options) error {
if v == nil {
return fmt.Errorf("finality certs verifier cannot be nil")
}
o.finalityCertsVerifier = v
return nil
}
}
func WithFinalityCertsInitialPollInterval(d time.Duration) Option {
return func(o *options) error {
if d <= 0 {
return fmt.Errorf("finality certs initial poll interval must be greater than 0")
}
o.finalityCertsInitialPollInterval = d
return nil
}
}
func WithFinalityCertsMinPollInterval(d time.Duration) Option {
return func(o *options) error {
if d <= 0 {
return fmt.Errorf("finality certs minimum poll interval must be greater than 0")
}
o.finalityCertsMinPollInterval = d
return nil
}
}
func WithFinalityCertsMaxPollInterval(d time.Duration) Option {
return func(o *options) error {
if d <= 0 {
return fmt.Errorf("finality certs maximum poll interval must be greater than 0")
}
o.finalityCertsMaxPollInterval = d
return nil
}
}
func WithChainExchangeBufferSize(size int) Option {
return func(o *options) error {
if size < 1 {
return fmt.Errorf("chain exchange buffer size must be at least 1")
}
o.chainExchangeBufferSize = size
return nil
}
}
func WithChainExchangeMaxMessageAge(d time.Duration) Option {
return func(o *options) error {
if d <= 0 {
return fmt.Errorf("chain exchange max message age must be greater than 0")
}
o.chainExchangeMaxMessageAge = d
return nil
}
}