Soft blacklist peer ids
Why make this change? This change is useful so we can blacklist peer ids, without actually disconnecting them, so that it's harder for them to tell that they are being blacklisted. Envelopes will just be dropped. What has changed? In waku we pass a config with a list of hex-encoded peer ids, and we check that against newly received envelopes. If so we just drop the envelope and return
This commit is contained in:
parent
19a82f68ad
commit
e836ffb47f
|
@ -447,10 +447,11 @@ func createShhService(ctx *node.ServiceContext, whisperConfig *params.WhisperCon
|
|||
|
||||
func createWakuService(ctx *node.ServiceContext, wakuCfg *params.WakuConfig, clusterCfg *params.ClusterConfig) (*waku.Waku, error) {
|
||||
cfg := &waku.Config{
|
||||
MaxMessageSize: wakucommon.DefaultMaxMessageSize,
|
||||
BloomFilterMode: wakuCfg.BloomFilterMode,
|
||||
FullNode: wakuCfg.FullNode,
|
||||
MinimumAcceptedPoW: params.WakuMinimumPoW,
|
||||
MaxMessageSize: wakucommon.DefaultMaxMessageSize,
|
||||
BloomFilterMode: wakuCfg.BloomFilterMode,
|
||||
FullNode: wakuCfg.FullNode,
|
||||
SoftBlacklistedPeerIDs: wakuCfg.SoftBlacklistedPeerIDs,
|
||||
MinimumAcceptedPoW: params.WakuMinimumPoW,
|
||||
}
|
||||
|
||||
if wakuCfg.MaxMessageSize > 0 {
|
||||
|
|
|
@ -208,6 +208,9 @@ type WakuConfig struct {
|
|||
// BloomFilterMode tells us whether we should be sending a bloom
|
||||
// filter rather than TopicInterest
|
||||
BloomFilterMode bool
|
||||
|
||||
// SoftBlacklistedPeerIDs is a list of peer ids that should be soft-blacklisted (messages should be dropped but connection kept)
|
||||
SoftBlacklistedPeerIDs []string
|
||||
}
|
||||
|
||||
// ----------
|
||||
|
|
|
@ -24,13 +24,14 @@ import (
|
|||
|
||||
// Config represents the configuration state of a waku node.
|
||||
type Config struct {
|
||||
MaxMessageSize uint32 `toml:",omitempty"`
|
||||
MinimumAcceptedPoW float64 `toml:",omitempty"`
|
||||
BloomFilterMode bool `toml:",omitempty"` // when true, we only match against bloom filter
|
||||
LightClient bool `toml:",omitempty"` // when true, it does not forward messages
|
||||
FullNode bool `toml:",omitempty"` // when true, it forwards all messages
|
||||
RestrictLightClientsConn bool `toml:",omitempty"` // when true, do not accept light client as peers if it is a light client itself
|
||||
EnableConfirmations bool `toml:",omitempty"` // when true, sends message confirmations
|
||||
MaxMessageSize uint32 `toml:",omitempty"`
|
||||
MinimumAcceptedPoW float64 `toml:",omitempty"`
|
||||
BloomFilterMode bool `toml:",omitempty"` // when true, we only match against bloom filter
|
||||
LightClient bool `toml:",omitempty"` // when true, it does not forward messages
|
||||
FullNode bool `toml:",omitempty"` // when true, it forwards all messages
|
||||
RestrictLightClientsConn bool `toml:",omitempty"` // when true, do not accept light client as peers if it is a light client itself
|
||||
EnableConfirmations bool `toml:",omitempty"` // when true, sends message confirmations
|
||||
SoftBlacklistedPeerIDs []string `toml:",omitempty"`
|
||||
}
|
||||
|
||||
var DefaultConfig = Config{
|
||||
|
|
24
waku/waku.go
24
waku/waku.go
|
@ -65,6 +65,7 @@ type settings struct {
|
|||
BloomFilterTolerance []byte // Bloom filter tolerated by the waku node for a limited time
|
||||
TopicInterest map[common.TopicType]bool // Topic interest for this node
|
||||
TopicInterestTolerance map[common.TopicType]bool // Topic interest tolerated by the waku node for a limited time
|
||||
SoftBlacklistedPeerIDs map[string]bool // SoftBlacklistedPeerIDs is a list of peer ids that we want to keep connected but silently drop any envelope from
|
||||
BloomFilterMode bool // Whether we should match against bloom-filter only
|
||||
LightClient bool // Light client mode enabled does not forward messages
|
||||
RestrictLightClientsConn bool // Restrict connection between two light clients
|
||||
|
@ -144,10 +145,15 @@ func New(cfg *Config, logger *zap.Logger) *Waku {
|
|||
LightClient: cfg.LightClient,
|
||||
FullNode: cfg.FullNode,
|
||||
BloomFilterMode: cfg.BloomFilterMode,
|
||||
SoftBlacklistedPeerIDs: make(map[string]bool),
|
||||
RestrictLightClientsConn: cfg.RestrictLightClientsConn,
|
||||
SyncAllowance: common.DefaultSyncAllowance,
|
||||
}
|
||||
|
||||
for _, peerID := range cfg.SoftBlacklistedPeerIDs {
|
||||
waku.settings.SoftBlacklistedPeerIDs[peerID] = true
|
||||
}
|
||||
|
||||
if cfg.FullNode {
|
||||
waku.settings.BloomFilter = common.MakeFullNodeBloom()
|
||||
waku.settings.BloomFilterTolerance = common.MakeFullNodeBloom()
|
||||
|
@ -1103,17 +1109,31 @@ func (w *Waku) HandlePeer(peer common.Peer, rw p2p.MsgReadWriter) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (w *Waku) softBlacklisted(peerID string) bool {
|
||||
w.settingsMu.RLock()
|
||||
defer w.settingsMu.RUnlock()
|
||||
return w.settings.SoftBlacklistedPeerIDs[peerID]
|
||||
}
|
||||
|
||||
func (w *Waku) OnNewEnvelopes(envelopes []*common.Envelope, peer common.Peer) ([]common.EnvelopeError, error) {
|
||||
w.logger.Debug("received new envelopes", zap.Int("count", len(envelopes)))
|
||||
envelopeErrors := make([]common.EnvelopeError, 0)
|
||||
peerID := types.EncodeHex(peer.ID())
|
||||
w.logger.Debug("received new envelopes", zap.Int("count", len(envelopes)), zap.String("peer", peerID))
|
||||
trouble := false
|
||||
|
||||
if w.softBlacklisted(peerID) {
|
||||
w.logger.Debug("peer is soft blacklisted", zap.String("peer", peerID))
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
for _, env := range envelopes {
|
||||
w.logger.Debug("received new envelope", zap.String("peer", peerID), zap.String("hash", env.Hash().Hex()))
|
||||
cached, err := w.add(env, w.LightClientMode())
|
||||
if err != nil {
|
||||
_, isTimeSyncError := err.(common.TimeSyncError)
|
||||
if !isTimeSyncError {
|
||||
trouble = true
|
||||
w.logger.Info("invalid envelope received", zap.Binary("peer", peer.ID()), zap.Error(err))
|
||||
w.logger.Info("invalid envelope received", zap.String("peer", types.EncodeHex(peer.ID())), zap.Error(err))
|
||||
}
|
||||
envelopeErrors = append(envelopeErrors, common.ErrorToEnvelopeError(env.Hash(), err))
|
||||
} else if cached {
|
||||
|
|
|
@ -31,9 +31,13 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/p2p"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/waku/common"
|
||||
v0 "github.com/status-im/status-go/waku/v0"
|
||||
v1 "github.com/status-im/status-go/waku/v1"
|
||||
)
|
||||
|
||||
var seed int64
|
||||
|
@ -49,19 +53,33 @@ func InitSingleTest() {
|
|||
func TestBasic(t *testing.T) {
|
||||
w := New(nil, nil)
|
||||
p := w.Protocols()
|
||||
waku := p[0]
|
||||
if waku.Name != v0.Name {
|
||||
t.Fatalf("failed Peer Name: %v.", waku.Name)
|
||||
waku0 := p[0]
|
||||
waku1 := p[1]
|
||||
if waku0.Name != v0.Name {
|
||||
t.Fatalf("failed Peer Name: %v.", waku0.Name)
|
||||
}
|
||||
if uint64(waku.Version) != v0.Version {
|
||||
t.Fatalf("failed Peer Version: %v.", waku.Version)
|
||||
if uint64(waku0.Version) != v0.Version {
|
||||
t.Fatalf("failed Peer Version: %v.", waku0.Version)
|
||||
}
|
||||
if waku.Length != v0.NumberOfMessageCodes {
|
||||
t.Fatalf("failed Peer Length: %v.", waku.Length)
|
||||
if waku0.Length != v0.NumberOfMessageCodes {
|
||||
t.Fatalf("failed Peer Length: %v.", waku0.Length)
|
||||
}
|
||||
if waku.Run == nil {
|
||||
if waku0.Run == nil {
|
||||
t.Fatalf("failed waku.Run.")
|
||||
}
|
||||
if waku1.Name != v1.Name {
|
||||
t.Fatalf("failed Peer Name: %v.", waku1.Name)
|
||||
}
|
||||
if uint64(waku1.Version) != v1.Version {
|
||||
t.Fatalf("failed Peer Version: %v.", waku1.Version)
|
||||
}
|
||||
if waku1.Length != v1.NumberOfMessageCodes {
|
||||
t.Fatalf("failed Peer Length: %v.", waku1.Length)
|
||||
}
|
||||
if waku1.Run == nil {
|
||||
t.Fatalf("failed waku.Run.")
|
||||
}
|
||||
|
||||
if w.GetFilter("non-existent") != nil {
|
||||
t.Fatalf("failed GetFilter.")
|
||||
}
|
||||
|
@ -1065,6 +1083,31 @@ func TestTopicInterest(t *testing.T) {
|
|||
|
||||
}
|
||||
|
||||
func TestOnNewEnvelopesSoftBlacklist(t *testing.T) {
|
||||
w1 := New(nil, nil)
|
||||
|
||||
envelope := &common.Envelope{}
|
||||
p2pPeer := p2p.NewPeer(enode.ID{0x4}, "test", []p2p.Cap{})
|
||||
peer := v1.NewPeer(w1, p2pPeer, nil, nil)
|
||||
|
||||
// Pre-condition, we need to make sure this envelope returns an EnvelopeError
|
||||
envelopeError, err := w1.OnNewEnvelopes([]*common.Envelope{envelope}, peer)
|
||||
require.NoError(t, err)
|
||||
// Make sure this envelope returns an error
|
||||
require.NotNil(t, envelopeError)
|
||||
|
||||
// build black listed waku
|
||||
cfg := &Config{
|
||||
SoftBlacklistedPeerIDs: []string{types.EncodeHex(peer.ID())},
|
||||
}
|
||||
w2 := New(cfg, nil)
|
||||
|
||||
envelopeError, err = w2.OnNewEnvelopes([]*common.Envelope{envelope}, peer)
|
||||
require.NoError(t, err)
|
||||
// Since it's blacklisted, it will just drop envelopes, keep the connection open
|
||||
require.Nil(t, envelopeError)
|
||||
}
|
||||
|
||||
func handleError(t *testing.T, err error) {
|
||||
if err != nil {
|
||||
t.Logf("deferred function error: '%s'", err)
|
||||
|
|
Loading…
Reference in New Issue