Skip to content

Commit 723bc65

Browse files
authored
Merge pull request #3256 from keep-network/firewall-bootstrap-nodes
Exempt bootstrap nodes from firewall validation This PR modifies the firewall, so that bootstrap nodes are exempted from validation, i.e. they are not required to have a stake.
2 parents e629431 + 937e779 commit 723bc65

File tree

10 files changed

+295
-47
lines changed

10 files changed

+295
-47
lines changed

cmd/flags.go

+7
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,13 @@ func initEthereumFlags(cmd *cobra.Command, cfg *config.Config) {
154154

155155
// Initialize flags for Network configuration.
156156
func initNetworkFlags(cmd *cobra.Command, cfg *config.Config) {
157+
cmd.Flags().BoolVar(
158+
&cfg.LibP2P.Bootstrap,
159+
"network.bootstrap",
160+
false,
161+
"Run the client in bootstrap mode.",
162+
)
163+
157164
cmd.Flags().StringSliceVar(
158165
&cfg.LibP2P.Peers,
159166
"network.peers",

cmd/flags_test.go

+7
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ var cmdFlagsTests = map[string]struct {
7979
expectedValueFromFlag: big.NewInt(1250000000000000000),
8080
defaultValue: big.NewInt(500000000000000000),
8181
},
82+
"network.bootstrap": {
83+
readValueFunc: func(c *config.Config) interface{} { return c.LibP2P.Bootstrap },
84+
flagName: "--network.bootstrap",
85+
flagValue: "true",
86+
expectedValueFromFlag: true,
87+
defaultValue: false,
88+
},
8289
"network.port": {
8390
readValueFunc: func(c *config.Config) interface{} { return c.LibP2P.Port },
8491
flagName: "--network.port",

cmd/start.go

+16
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,19 @@ func start(cmd *cobra.Command) error {
7070
return fmt.Errorf("error connecting to Ethereum node: [%v]", err)
7171
}
7272

73+
bootstrapPeersPublicKeys, err := libp2p.ExtractPeersPublicKeys(
74+
clientConfig.LibP2P.Peers,
75+
)
76+
if err != nil {
77+
return fmt.Errorf(
78+
"error extracting bootstrap peers public keys: [%v]",
79+
err,
80+
)
81+
}
82+
7383
firewall := firewall.AnyApplicationPolicy(
7484
[]firewall.Application{beaconChain, tbtcChain},
85+
firewall.NewAllowList(bootstrapPeersPublicKeys),
7586
)
7687

7788
netProvider, err := libp2p.Connect(
@@ -117,12 +128,16 @@ func start(cmd *cobra.Command) error {
117128

118129
scheduler := generator.StartScheduler()
119130

131+
// Monitor sortition pool only if the node is a non-bootstrap node.
132+
monitorPool := !clientConfig.LibP2P.Bootstrap
133+
120134
err = beacon.Initialize(
121135
ctx,
122136
beaconChain,
123137
netProvider,
124138
beaconKeyStorePersistence,
125139
scheduler,
140+
monitorPool,
126141
)
127142
if err != nil {
128143
return fmt.Errorf("error initializing beacon: [%v]", err)
@@ -155,6 +170,7 @@ func start(cmd *cobra.Command) error {
155170
scheduler,
156171
clientConfig.Tbtc,
157172
metricsRegistry,
173+
monitorPool,
158174
)
159175
if err != nil {
160176
return fmt.Errorf("error initializing TBTC: [%v]", err)

configs/config.toml.SAMPLE

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ KeyFile = "/Users/someuser/ethereum/data/keystore/UTC--2018-03-11T01-37-33.20276
4747
# BalanceAlertThreshold = "0.5 ether" # 0.5 ether (default value)
4848

4949
[network]
50+
Bootstrap = false
5051
Peers = [
5152
"/ip4/127.0.0.1/tcp/3919/ipfs/16Uiu2HAmFRJtCWfdXhZEZHWb4tUpH1QMMgzH1oiamCfUuK6NgqWX",
5253
]

pkg/beacon/beacon.go

+15-9
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ func Initialize(
3333
netProvider net.Provider,
3434
persistence persistence.ProtectedHandle,
3535
scheduler *generator.Scheduler,
36+
monitorPool bool,
3637
) error {
3738
groupRegistry := registry.NewGroupRegistry(logger, beaconChain, persistence)
3839
groupRegistry.LoadExistingGroups()
@@ -44,15 +45,20 @@ func Initialize(
4445
scheduler,
4546
)
4647

47-
err := sortition.MonitorPool(
48-
ctx,
49-
logger,
50-
beaconChain,
51-
sortition.DefaultStatusCheckTick,
52-
sortition.UnconditionalJoinPolicy,
53-
)
54-
if err != nil {
55-
return fmt.Errorf("could not set up sortition pool monitoring: [%v]", err)
48+
if monitorPool {
49+
err := sortition.MonitorPool(
50+
ctx,
51+
logger,
52+
beaconChain,
53+
sortition.DefaultStatusCheckTick,
54+
sortition.UnconditionalJoinPolicy,
55+
)
56+
if err != nil {
57+
return fmt.Errorf(
58+
"could not set up sortition pool monitoring: [%v]",
59+
err,
60+
)
61+
}
5662
}
5763

5864
eventDeduplicator := event.NewDeduplicator(beaconChain)

pkg/firewall/firewall.go

+42-7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,31 @@ func (nf *noFirewall) Validate(remotePeerPublicKey *operator.PublicKey) error {
2626
return nil
2727
}
2828

29+
// AllowList represents a list of operator public keys that are not checked
30+
// against the firewall rules and are always valid peers.
31+
type AllowList struct {
32+
allowedPublicKeys map[string]bool
33+
}
34+
35+
// NewAllowList creates a new firewall's allowlist based on the given public
36+
// key list.
37+
func NewAllowList(operatorPublicKeys []*operator.PublicKey) *AllowList {
38+
allowedPublicKeys := make(map[string]bool, len(operatorPublicKeys))
39+
40+
for _, operatorPublicKey := range operatorPublicKeys {
41+
allowedPublicKeys[operatorPublicKey.String()] = true
42+
}
43+
44+
return &AllowList{allowedPublicKeys}
45+
}
46+
47+
func (al *AllowList) Contains(operatorPublicKey *operator.PublicKey) bool {
48+
return al.allowedPublicKeys[operatorPublicKey.String()]
49+
}
50+
51+
// EmptyAllowList represents an empty firewall allowlist.
52+
var EmptyAllowList = NewAllowList([]*operator.PublicKey{})
53+
2954
const (
3055
// PositiveIsRecognizedCachePeriod is the time period the cache maintains
3156
// the positive result of the last `IsRecognized` checks.
@@ -42,30 +67,38 @@ var errNotRecognized = fmt.Errorf(
4267
"remote peer has not been recognized by any application",
4368
)
4469

45-
func AnyApplicationPolicy(applications []Application) net.Firewall {
70+
func AnyApplicationPolicy(
71+
applications []Application,
72+
allowList *AllowList,
73+
) net.Firewall {
4674
return &anyApplicationPolicy{
4775
applications: applications,
76+
allowList: allowList,
4877
positiveResultCache: cache.NewTimeCache(PositiveIsRecognizedCachePeriod),
4978
negativeResultCache: cache.NewTimeCache(NegativeIsRecognizedCachePeriod),
5079
}
5180
}
5281

5382
type anyApplicationPolicy struct {
5483
applications []Application
84+
allowList *AllowList
5585
positiveResultCache *cache.TimeCache
5686
negativeResultCache *cache.TimeCache
5787
}
5888

5989
// Validate checks whether the given operator meets the conditions to join
60-
// the network. Validate iterates over a list of applications and if any of them
61-
// recognizes the operator as eligible, it can join the network. Nil is returned
62-
// on a successful validation, error is returned if none of the applications
63-
// validates the operator successfully. Due to performance reasons the results
64-
// of validations are stored in a cache for a certain amount of time.
90+
// the network. The operator can join the network if it is an allowlisted node
91+
// or it is a non-allowlisted node but it is recognized as eligible by any of
92+
// the applications. Nil is returned on a successful validation, error otherwise.
93+
// Due to performance reasons, the results of validations for non-allowlisted
94+
// nodes are stored in a cache for a certain amount of time.
6595
func (aap *anyApplicationPolicy) Validate(
6696
remotePeerPublicKey *operator.PublicKey,
6797
) error {
68-
remotePeerPublicKeyHex := remotePeerPublicKey.String()
98+
// If the peer is on the allowlist, consider it validated.
99+
if aap.allowList.Contains(remotePeerPublicKey) {
100+
return nil
101+
}
69102

70103
// First, check in the in-memory time caches to minimize hits to the ETH client.
71104
// If the Keep client with the given chain address is in the positive result
@@ -78,6 +111,8 @@ func (aap *anyApplicationPolicy) Validate(
78111
aap.positiveResultCache.Sweep()
79112
aap.negativeResultCache.Sweep()
80113

114+
remotePeerPublicKeyHex := remotePeerPublicKey.String()
115+
81116
if aap.positiveResultCache.Has(remotePeerPublicKeyHex) {
82117
return nil
83118
}

0 commit comments

Comments
 (0)