Commit ca922b04 authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge pull request #4508 from ethereum-optimism/guard-gossip-validator

op-node: guard against panics in the p2p gossip validator
parents 809c4c9d 727c1fcc
...@@ -165,6 +165,18 @@ func logValidationResult(self peer.ID, msg string, log log.Logger, fn pubsub.Val ...@@ -165,6 +165,18 @@ func logValidationResult(self peer.ID, msg string, log log.Logger, fn pubsub.Val
} }
} }
func guardGossipValidator(log log.Logger, fn pubsub.ValidatorEx) pubsub.ValidatorEx {
return func(ctx context.Context, id peer.ID, message *pubsub.Message) (result pubsub.ValidationResult) {
defer func() {
if err := recover(); err != nil {
log.Error("gossip validation panic", "err", err, "peer", id)
result = pubsub.ValidationReject
}
}()
return fn(ctx, id, message)
}
}
type seenBlocks struct { type seenBlocks struct {
sync.Mutex sync.Mutex
blockHashes []common.Hash blockHashes []common.Hash
...@@ -358,7 +370,7 @@ func (p *publisher) Close() error { ...@@ -358,7 +370,7 @@ func (p *publisher) Close() error {
} }
func JoinGossip(p2pCtx context.Context, self peer.ID, ps *pubsub.PubSub, log log.Logger, cfg *rollup.Config, gossipIn GossipIn) (GossipOut, error) { func JoinGossip(p2pCtx context.Context, self peer.ID, ps *pubsub.PubSub, log log.Logger, cfg *rollup.Config, gossipIn GossipIn) (GossipOut, error) {
val := logValidationResult(self, "validated block", log, BuildBlocksValidator(log, cfg)) val := guardGossipValidator(log, logValidationResult(self, "validated block", log, BuildBlocksValidator(log, cfg)))
blocksTopicName := blocksTopicV1(cfg) blocksTopicName := blocksTopicV1(cfg)
err := ps.RegisterTopicValidator(blocksTopicName, err := ps.RegisterTopicValidator(blocksTopicName,
val, val,
......
package p2p
import (
"context"
"testing"
"github.com/ethereum/go-ethereum/log"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-node/testlog"
)
func TestGuardGossipValidator(t *testing.T) {
logger := testlog.Logger(t, log.LvlCrit)
val := guardGossipValidator(logger, func(ctx context.Context, id peer.ID, message *pubsub.Message) pubsub.ValidationResult {
if id == "mallory" {
panic("mallory was here")
}
if id == "bob" {
return pubsub.ValidationIgnore
}
return pubsub.ValidationAccept
})
// Test that panics from mallory are recovered and rejected,
// and test that we can continue to ignore bob and accept alice.
require.Equal(t, pubsub.ValidationAccept, val(context.Background(), "alice", nil))
require.Equal(t, pubsub.ValidationReject, val(context.Background(), "mallory", nil))
require.Equal(t, pubsub.ValidationIgnore, val(context.Background(), "bob", nil))
require.Equal(t, pubsub.ValidationReject, val(context.Background(), "mallory", nil))
require.Equal(t, pubsub.ValidationAccept, val(context.Background(), "alice", nil))
require.Equal(t, pubsub.ValidationIgnore, val(context.Background(), "bob", nil))
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment