forked from ava-labs/avalanchego
-
Notifications
You must be signed in to change notification settings - Fork 4
/
minority.go
77 lines (62 loc) · 1.86 KB
/
minority.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
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package bootstrapper
import (
"context"
"go.uber.org/zap"
"github.com/MetalBlockchain/metalgo/ids"
"github.com/MetalBlockchain/metalgo/utils/logging"
"github.com/MetalBlockchain/metalgo/utils/set"
)
var _ Poll = (*Minority)(nil)
// Minority implements the bootstrapping poll to determine the initial set of
// potentially accaptable blocks.
//
// This poll fetches the last accepted block from an initial set of peers. In
// order for the protocol to find a recently accepted block, there must be at
// least one correct node in this set of peers. If there is not a correct node
// in the set of peers, the node will not accept an incorrect block. However,
// the node may be unable to find an acceptable block.
type Minority struct {
requests
log logging.Logger
receivedSet set.Set[ids.ID]
received []ids.ID
}
func NewMinority(
log logging.Logger,
frontierNodes set.Set[ids.NodeID],
maxOutstanding int,
) *Minority {
return &Minority{
requests: requests{
maxOutstanding: maxOutstanding,
pendingSend: frontierNodes,
},
log: log,
}
}
func (m *Minority) RecordOpinion(_ context.Context, nodeID ids.NodeID, blkIDs set.Set[ids.ID]) error {
if !m.recordResponse(nodeID) {
// The chain router should have already dropped unexpected messages.
m.log.Error("received unexpected opinion",
zap.String("pollType", "minority"),
zap.Stringer("nodeID", nodeID),
zap.Reflect("blkIDs", blkIDs),
)
return nil
}
m.receivedSet.Union(blkIDs)
if !m.finished() {
return nil
}
m.received = m.receivedSet.List()
m.log.Debug("finalized bootstrapping poll",
zap.String("pollType", "minority"),
zap.Stringers("frontier", m.received),
)
return nil
}
func (m *Minority) Result(context.Context) ([]ids.ID, bool) {
return m.received, m.finished()
}