status-go/peers/cotopicpool.go
frank 38308d48f2
feat_: log on panic (#5849)
* feat_: log error and stacktrace when panic in goroutine

* test_: add test TestSafeGo

* chore_: rename logAndCall to call

* chore_: rename SafeGo to Go

* chore_: make lint-fix

* chore_: use t.Cleanup

* chore_: Revert "chore_: use t.Cleanup"

This reverts commit 4eb420d179cc0e208e84c13cb941e6b3d1ed9819.

* chore_: Revert "chore_: make lint-fix"

This reverts commit fcc995f157e671a4229b47419c3a0e4004b5fdab.

* chore_: Revert "chore_: rename SafeGo to Go"

This reverts commit a6d73d6df583f313032d79aac62f66328039cb55.

* chore_: Revert "chore_: rename logAndCall to call"

This reverts commit 8fbe993bedb9fbba67349a44f151e2dd5e3bc4cc.

* chore_: Revert "test_: add test TestSafeGo"

This reverts commit a1fa91839f3960398980c6bf456e6462ec944819.

* chore_: Revert "feat_: log error and stacktrace when panic in goroutine"

This reverts commit f612dd828fa2ce410d0e806fe773ecbe3e86a68a.

* feat_: log error and stacktrace when panic in goroutine

* chore_: make lint-fix

* chore_: rename logAndCall to call

* chore_: renaming LogOnPanic

* chore_: update rest goroutine function calls

* chore_: make lint-fix
2024-09-27 06:37:32 +08:00

117 lines
3.4 KiB
Go

package peers
import (
"context"
"time"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/status-im/status-go/common"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/signal"
)
// Verifier verifies if a give node is trusted.
type Verifier interface {
VerifyNode(context.Context, enode.ID) bool
}
// MailServerDiscoveryTopic topic name for mailserver discovery.
const MailServerDiscoveryTopic = "whispermail"
// MailServerDiscoveryLimits default mailserver discovery limits.
var MailServerDiscoveryLimits = params.Limits{Min: 3, Max: 3}
// cacheOnlyTopicPool handles a mail server topic pool.
type cacheOnlyTopicPool struct {
*TopicPool
verifier Verifier
}
// newCacheOnlyTopicPool returns instance of CacheOnlyTopicPool.
func newCacheOnlyTopicPool(t *TopicPool, verifier Verifier) *cacheOnlyTopicPool {
return &cacheOnlyTopicPool{
TopicPool: t,
verifier: verifier,
}
}
// MaxReached checks if the max allowed peers is reached or not. When true
// peerpool will stop the discovery process on this TopicPool.
// Main difference with basic TopicPool is we want to stop discovery process
// when the number of cached peers eq/exceeds the max limit.
func (t *cacheOnlyTopicPool) MaxReached() bool {
t.mu.RLock()
defer t.mu.RUnlock()
if t.limits.Max == 0 {
return true
}
peers := t.cache.GetPeersRange(t.topic, t.limits.Max)
return len(peers) >= t.limits.Max
}
var sendEnodeDiscovered = signal.SendEnodeDiscovered
// ConfirmAdded calls base TopicPool ConfirmAdded method and sends a signal
// confirming the enode has been discovered.
func (t *cacheOnlyTopicPool) ConfirmAdded(server *p2p.Server, nodeID enode.ID) {
trusted := t.verifier.VerifyNode(context.TODO(), nodeID)
if trusted {
// add to cache only if trusted
t.TopicPool.ConfirmAdded(server, nodeID)
sendEnodeDiscovered(nodeID.String(), string(t.topic))
t.subtractToLimits()
}
// If a peer was trusted, it was moved to connectedPeers,
// signal was sent and we can safely remove it.
if peer, ok := t.connectedPeers[nodeID]; ok {
// NOTE: removeServerPeer removes the server peer immediately.
// which means the next discovery.summary is not going to include
// the peer.
// We leave some time so that we ensure the signal is propagated
go func() {
defer common.LogOnPanic()
time.Sleep(200)
t.removeServerPeer(server, peer)
}()
// Delete it from `connectedPeers` immediately to
// prevent removing it from the cache which logic is
// implemented in TopicPool.
delete(t.connectedPeers, nodeID)
}
// It a peer was not trusted, it is still in pendingPeers.
// We should remove it from the p2p.Server.
if peer, ok := t.pendingPeers[nodeID]; ok {
// NOTE: removeServerPeer removes the server peer immediately.
// which means the next discovery.summary is not going to include
// the peer.
// We leave some time so that we ensure the signal is propagated
go func() {
defer common.LogOnPanic()
time.Sleep(200)
t.removeServerPeer(server, peer.peerInfo)
}()
// Delete it from `connectedPeers` immediately to
// prevent removing it from the cache which logic is
// implemented in TopicPool.
delete(t.pendingPeers, nodeID)
}
}
// subtractToLimits subtracts one to topic pool limits.
func (t *cacheOnlyTopicPool) subtractToLimits() {
t.mu.Lock()
defer t.mu.Unlock()
if t.limits.Max > 0 {
t.limits.Max = t.limits.Max - 1
}
if t.limits.Min > 0 {
t.limits.Min = t.limits.Min - 1
}
}