github.com/koko1123/flow-go-1@v0.29.6/network/p2p/p2pnode/gossipSubAdapter.go (about)

     1  package p2pnode
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	pubsub "github.com/libp2p/go-libp2p-pubsub"
     8  	"github.com/libp2p/go-libp2p/core/host"
     9  	"github.com/libp2p/go-libp2p/core/peer"
    10  	"github.com/rs/zerolog"
    11  
    12  	"github.com/koko1123/flow-go-1/network/p2p"
    13  	"github.com/koko1123/flow-go-1/utils/logging"
    14  )
    15  
    16  // GossipSubAdapter is a wrapper around the libp2p GossipSub implementation
    17  // that implements the PubSubAdapter interface for the Flow network.
    18  type GossipSubAdapter struct {
    19  	gossipSub *pubsub.PubSub
    20  	logger    zerolog.Logger
    21  }
    22  
    23  var _ p2p.PubSubAdapter = (*GossipSubAdapter)(nil)
    24  
    25  func NewGossipSubAdapter(ctx context.Context, logger zerolog.Logger, h host.Host, cfg p2p.PubSubAdapterConfig) (p2p.PubSubAdapter, error) {
    26  	gossipSubConfig, ok := cfg.(*GossipSubAdapterConfig)
    27  	if !ok {
    28  		return nil, fmt.Errorf("invalid gossipsub config type: %T", cfg)
    29  	}
    30  
    31  	gossipSub, err := pubsub.NewGossipSub(ctx, h, gossipSubConfig.Build()...)
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  	return &GossipSubAdapter{
    36  		gossipSub: gossipSub,
    37  		logger:    logger,
    38  	}, nil
    39  }
    40  
    41  func (g *GossipSubAdapter) RegisterTopicValidator(topic string, topicValidator p2p.TopicValidatorFunc) error {
    42  	// wrap the topic validator function into a libp2p topic validator function.
    43  	var v pubsub.ValidatorEx = func(ctx context.Context, from peer.ID, message *pubsub.Message) pubsub.ValidationResult {
    44  		switch result := topicValidator(ctx, from, message); result {
    45  		case p2p.ValidationAccept:
    46  			return pubsub.ValidationAccept
    47  		case p2p.ValidationIgnore:
    48  			return pubsub.ValidationIgnore
    49  		case p2p.ValidationReject:
    50  			return pubsub.ValidationReject
    51  		default:
    52  			// should never happen, indicates a bug in the topic validator
    53  			g.logger.Fatal().Msgf("invalid validation result: %v", result)
    54  		}
    55  		// should never happen, indicates a bug in the topic validator, but we need to return something
    56  		g.logger.Warn().
    57  			Bool(logging.KeySuspicious, true).
    58  			Msg("invalid validation result, returning reject")
    59  		return pubsub.ValidationReject
    60  	}
    61  
    62  	return g.gossipSub.RegisterTopicValidator(topic, v, pubsub.WithValidatorInline(true))
    63  }
    64  
    65  func (g *GossipSubAdapter) UnregisterTopicValidator(topic string) error {
    66  	return g.gossipSub.UnregisterTopicValidator(topic)
    67  }
    68  
    69  func (g *GossipSubAdapter) Join(topic string) (p2p.Topic, error) {
    70  	t, err := g.gossipSub.Join(topic)
    71  	if err != nil {
    72  		return nil, fmt.Errorf("could not join topic %s: %w", topic, err)
    73  	}
    74  	return NewGossipSubTopic(t), nil
    75  }
    76  
    77  func (g *GossipSubAdapter) GetTopics() []string {
    78  	return g.gossipSub.GetTopics()
    79  }
    80  
    81  func (g *GossipSubAdapter) ListPeers(topic string) []peer.ID {
    82  	return g.gossipSub.ListPeers(topic)
    83  }