Skip to content
This repository was archived by the owner on May 22, 2023. It is now read-only.

Commit 057c0e7

Browse files
authored
Merge pull request #740 from keep-network/mmmutex
Guard execution of on-chain firewall calls with a mutex This PR is a continuation of firewall fixes started in #737. Keeping as a draft until properly tested. This change is effectively reducing firewall on-chain concurrency to one call but this is exactly what we need. The loop going through keeps is always executing checks in a sequence. When two on-chain calls were executed at the same time, they were always a duplicate of the same call. Mutex should not slow anything down and should in fact speed up the loop. Instead of executing the same check from 8 concurrent threads and being rate-limited, we will execute 8 different checks at more or less the same time.
2 parents 954af08 + 2e8910d commit 057c0e7

1 file changed

Lines changed: 50 additions & 9 deletions

File tree

pkg/firewall/firewall.go

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,17 @@ type stakeOrActiveKeepPolicy struct {
7070
func (soakp *stakeOrActiveKeepPolicy) Validate(
7171
remotePeerPublicKey *ecdsa.PublicKey,
7272
) error {
73+
remotePeerNetworkPublicKey := coreKey.NetworkPublic(*remotePeerPublicKey)
74+
remotePeerAddress := coreKey.NetworkPubKeyToEthAddress(&remotePeerNetworkPublicKey)
75+
76+
logger.Debugf("validating firewall rules for [%v]", remotePeerAddress)
77+
7378
// Validate minimum stake policy. If the remote peer has the minimum stake,
7479
// we are fine and we should let to connect.
7580
if err := soakp.minimumStakePolicy.Validate(remotePeerPublicKey); err == nil {
7681
return nil
7782
}
7883

79-
remotePeerNetworkPublicKey := coreKey.NetworkPublic(*remotePeerPublicKey)
80-
remotePeerAddress := coreKey.NetworkPubKeyToEthAddress(&remotePeerNetworkPublicKey)
81-
8284
// Check if the remote peer has authorization on the factory.
8385
// The authorization cannot be revoked.
8486
// If peer has no authorization on the factory it means it has never
@@ -98,6 +100,11 @@ func (soakp *stakeOrActiveKeepPolicy) Validate(
98100
func (soakp *stakeOrActiveKeepPolicy) validateAuthorization(
99101
remotePeerAddress string,
100102
) error {
103+
logger.Debugf(
104+
"validating authorization for [%v]",
105+
remotePeerAddress,
106+
)
107+
101108
// Before hitting ETH client, consult the in-memory time cache.
102109
// If the caching time for the given entry elapsed or if that entry is
103110
// not in the cache, we'll have to consult the chain and execute a call
@@ -138,6 +145,10 @@ func (soakp *stakeOrActiveKeepPolicy) validateAuthorization(
138145
func (soakp *stakeOrActiveKeepPolicy) validateActiveKeepMembership(
139146
remotePeerAddress string,
140147
) error {
148+
logger.Debugf(
149+
"validating active keep membership for [%v]",
150+
remotePeerAddress,
151+
)
141152

142153
// First, check in the in-memory time cache to minimize hits to ETH client.
143154
// If the Keep client with the given chain address is in the active members
@@ -245,14 +256,21 @@ func (soakp *stakeOrActiveKeepPolicy) getKeepAtIndex(
245256
return common.HexToAddress(cachedAddress), nil
246257
}
247258

259+
cache.mutex.Lock()
260+
defer cache.mutex.Unlock()
261+
262+
cachedAddress, isCached = cache.address[index.String()]
263+
if isCached {
264+
return common.HexToAddress(cachedAddress), nil
265+
}
266+
267+
logger.Debugf("fetching keep at index [%v] from the chain", index)
248268
address, err := soakp.chain.GetKeepAtIndex(index)
249269
if err != nil {
250270
return common.Address{}, err
251271
}
252272

253-
cache.mutex.Lock()
254273
cache.address[index.String()] = address.Hex()
255-
cache.mutex.Unlock()
256274

257275
return address, nil
258276
}
@@ -280,6 +298,21 @@ func (soakp *stakeOrActiveKeepPolicy) isKeepActive(
280298
return true, nil
281299
}
282300

301+
cache.mutex.Lock()
302+
defer cache.mutex.Unlock()
303+
304+
isInactive, isCached = cache.isInactive[keepAddress.String()]
305+
if isCached && isInactive {
306+
return false, nil
307+
}
308+
if cache.isActive.Has(keepAddress.String()) {
309+
return true, nil
310+
}
311+
312+
logger.Debugf(
313+
"checking if keep with ID [%v] is active on the chain",
314+
keepAddress.String(),
315+
)
283316
isActive, err := soakp.chain.IsActive(keepAddress)
284317
if err != nil {
285318
return false, err
@@ -288,9 +321,7 @@ func (soakp *stakeOrActiveKeepPolicy) isKeepActive(
288321
if isActive {
289322
cache.isActive.Add(keepAddress.String())
290323
} else {
291-
cache.mutex.Lock()
292324
cache.isInactive[keepAddress.String()] = true
293-
cache.mutex.Unlock()
294325
}
295326

296327
return isActive, nil
@@ -311,6 +342,18 @@ func (soakp *stakeOrActiveKeepPolicy) getKeepMembers(
311342
return members, nil
312343
}
313344

345+
cache.mutex.Lock()
346+
defer cache.mutex.Unlock()
347+
348+
members, areCached = cache.members[keepAddress.String()]
349+
if areCached {
350+
return members, nil
351+
}
352+
353+
logger.Debugf(
354+
"getting members of the keep with ID [%v] from the chain",
355+
keepAddress.String(),
356+
)
314357
memberAddresses, err := soakp.chain.GetMembers(keepAddress)
315358
if err != nil {
316359
return nil, nil
@@ -321,9 +364,7 @@ func (soakp *stakeOrActiveKeepPolicy) getKeepMembers(
321364
members[i] = member.String()
322365
}
323366

324-
cache.mutex.Lock()
325367
cache.members[keepAddress.String()] = members
326-
cache.mutex.Unlock()
327368

328369
return members, nil
329370
}

0 commit comments

Comments
 (0)