github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/network/underlay/network.go (about)

     1  package underlay
     2  
     3  import (
     4  	"bufio"
     5  	"context"
     6  	"errors"
     7  	"fmt"
     8  	"io"
     9  	"sync"
    10  	"time"
    11  
    12  	ggio "github.com/gogo/protobuf/io"
    13  	"github.com/ipfs/go-datastore"
    14  	libp2pnet "github.com/libp2p/go-libp2p/core/network"
    15  	"github.com/libp2p/go-libp2p/core/peer"
    16  	"github.com/libp2p/go-libp2p/core/peerstore"
    17  	"github.com/libp2p/go-libp2p/core/protocol"
    18  	"github.com/rs/zerolog"
    19  
    20  	"github.com/onflow/flow-go/model/flow"
    21  	"github.com/onflow/flow-go/model/flow/filter"
    22  	"github.com/onflow/flow-go/module"
    23  	"github.com/onflow/flow-go/module/component"
    24  	"github.com/onflow/flow-go/module/irrecoverable"
    25  	"github.com/onflow/flow-go/network"
    26  	alspmgr "github.com/onflow/flow-go/network/alsp/manager"
    27  	netcache "github.com/onflow/flow-go/network/cache"
    28  	"github.com/onflow/flow-go/network/channels"
    29  	"github.com/onflow/flow-go/network/codec"
    30  	"github.com/onflow/flow-go/network/internal/p2putils"
    31  	"github.com/onflow/flow-go/network/message"
    32  	"github.com/onflow/flow-go/network/p2p"
    33  	"github.com/onflow/flow-go/network/p2p/blob"
    34  	p2plogging "github.com/onflow/flow-go/network/p2p/logging"
    35  	"github.com/onflow/flow-go/network/p2p/ping"
    36  	"github.com/onflow/flow-go/network/p2p/subscription"
    37  	"github.com/onflow/flow-go/network/p2p/unicast/protocols"
    38  	"github.com/onflow/flow-go/network/p2p/unicast/ratelimit"
    39  	"github.com/onflow/flow-go/network/p2p/utils"
    40  	"github.com/onflow/flow-go/network/queue"
    41  	"github.com/onflow/flow-go/network/underlay/internal"
    42  	"github.com/onflow/flow-go/network/validator"
    43  	flowpubsub "github.com/onflow/flow-go/network/validator/pubsub"
    44  	_ "github.com/onflow/flow-go/utils/binstat"
    45  	"github.com/onflow/flow-go/utils/logging"
    46  )
    47  
    48  const (
    49  	_ = iota
    50  	_ = 1 << (10 * iota)
    51  	mb
    52  	gb
    53  )
    54  
    55  const (
    56  	// DefaultMaxUnicastMsgSize defines maximum message size in unicast mode for most messages
    57  	DefaultMaxUnicastMsgSize = 10 * mb // 10 mb
    58  
    59  	// LargeMsgMaxUnicastMsgSize defines maximum message size in unicast mode for large messages
    60  	LargeMsgMaxUnicastMsgSize = gb // 1 gb
    61  
    62  	// DefaultUnicastTimeout is the default maximum time to wait for a default unicast request to complete
    63  	// assuming at least a 1mb/sec connection
    64  	DefaultUnicastTimeout = 5 * time.Second
    65  
    66  	// LargeMsgUnicastTimeout is the maximum time to wait for a unicast request to complete for large message size
    67  	LargeMsgUnicastTimeout = 1000 * time.Second
    68  )
    69  
    70  var (
    71  	// ErrUnicastMsgWithoutSub error is provided to the slashing violations consumer in the case where
    72  	// the network receives a message via unicast but does not have a corresponding subscription for
    73  	// the channel in that message.
    74  	ErrUnicastMsgWithoutSub = errors.New("networking layer does not have subscription for the channel ID indicated in the unicast message received")
    75  )
    76  
    77  // Network serves as the comprehensive networking layer that integrates three interfaces within Flow; Underlay, EngineRegistry, and ConduitAdapter.
    78  // It is responsible for creating conduits through which engines can send and receive messages to and from other engines on the network, as well as registering other services
    79  // such as BlobService and PingService. It also provides a set of APIs that can be used to send messages to other nodes on the network.
    80  // Network is also responsible for managing the topology of the network, i.e., the set of nodes that are connected to each other.
    81  // It is also responsible for managing the set of nodes that are connected to each other.
    82  type Network struct {
    83  	// TODO: using a waitgroup here doesn't actually guarantee that we'll wait for all
    84  	// goroutines to exit, because new goroutines could be started after we've already
    85  	// returned from wg.Wait(). We need to solve this the right way using ComponentManager
    86  	// and worker routines.
    87  	wg sync.WaitGroup
    88  	*component.ComponentManager
    89  	ctx                         context.Context
    90  	sporkId                     flow.Identifier
    91  	identityProvider            module.IdentityProvider
    92  	identityTranslator          p2p.IDTranslator
    93  	logger                      zerolog.Logger
    94  	codec                       network.Codec
    95  	me                          module.Local
    96  	metrics                     module.NetworkCoreMetrics
    97  	receiveCache                *netcache.ReceiveCache // used to deduplicate incoming messages
    98  	queue                       network.MessageQueue
    99  	subscriptionManager         network.SubscriptionManager // used to keep track of subscribed channels
   100  	conduitFactory              network.ConduitFactory
   101  	topology                    network.Topology
   102  	registerEngineRequests      chan *registerEngineRequest
   103  	registerBlobServiceRequests chan *registerBlobServiceRequest
   104  	misbehaviorReportManager    network.MisbehaviorReportManager
   105  	unicastMessageTimeout       time.Duration
   106  	libP2PNode                  p2p.LibP2PNode
   107  	bitswapMetrics              module.BitswapMetrics
   108  	peerUpdateLock              sync.Mutex // protects the peer update process
   109  	previousProtocolStatePeers  []peer.AddrInfo
   110  	slashingViolationsConsumer  network.ViolationsConsumer
   111  	peerManagerFilters          []p2p.PeerFilter
   112  	unicastRateLimiters         *ratelimit.RateLimiters
   113  	validators                  []network.MessageValidator
   114  	authorizedSenderValidator   *validator.AuthorizedSenderValidator
   115  	preferredUnicasts           []protocols.ProtocolName
   116  }
   117  
   118  var _ network.EngineRegistry = &Network{}
   119  var _ network.Underlay = &Network{}
   120  var _ network.ConduitAdapter = &Network{}
   121  
   122  type registerEngineRequest struct {
   123  	channel          channels.Channel
   124  	messageProcessor network.MessageProcessor
   125  	respChan         chan *registerEngineResp
   126  }
   127  
   128  type registerEngineResp struct {
   129  	conduit network.Conduit
   130  	err     error
   131  }
   132  
   133  type registerBlobServiceRequest struct {
   134  	channel  channels.Channel
   135  	ds       datastore.Batching
   136  	opts     []network.BlobServiceOption
   137  	respChan chan *registerBlobServiceResp
   138  }
   139  
   140  type registerBlobServiceResp struct {
   141  	blobService network.BlobService
   142  	err         error
   143  }
   144  
   145  var ErrNetworkShutdown = errors.New("network has already shutdown")
   146  
   147  // NetworkConfig is a configuration struct for the network. It contains all the
   148  // necessary components to create a new network.
   149  type NetworkConfig struct {
   150  	Logger                           zerolog.Logger
   151  	Codec                            network.Codec
   152  	Me                               module.Local
   153  	Topology                         network.Topology
   154  	Metrics                          module.NetworkCoreMetrics
   155  	IdentityProvider                 module.IdentityProvider
   156  	IdentityTranslator               p2p.IDTranslator
   157  	ReceiveCache                     *netcache.ReceiveCache
   158  	ConduitFactory                   network.ConduitFactory
   159  	AlspCfg                          *alspmgr.MisbehaviorReportManagerConfig
   160  	SporkId                          flow.Identifier
   161  	UnicastMessageTimeout            time.Duration
   162  	Libp2pNode                       p2p.LibP2PNode
   163  	BitSwapMetrics                   module.BitswapMetrics
   164  	SlashingViolationConsumerFactory func(network.ConduitAdapter) network.ViolationsConsumer
   165  }
   166  
   167  // Validate validates the configuration, and sets default values for any missing fields.
   168  func (cfg *NetworkConfig) Validate() {
   169  	if cfg.UnicastMessageTimeout <= 0 {
   170  		cfg.UnicastMessageTimeout = DefaultUnicastTimeout
   171  	}
   172  }
   173  
   174  // NetworkConfigOption is a function that can be used to override network config parmeters.
   175  type NetworkConfigOption func(*NetworkConfig)
   176  
   177  // WithAlspConfig overrides the default misbehavior report manager config. It is mostly used for testing purposes.
   178  // Note: do not override the default misbehavior report manager config in production unless you know what you are doing.
   179  // Args:
   180  // cfg: misbehavior report manager config
   181  // Returns:
   182  // NetworkConfigOption: network param option
   183  func WithAlspConfig(cfg *alspmgr.MisbehaviorReportManagerConfig) NetworkConfigOption {
   184  	return func(params *NetworkConfig) {
   185  		params.AlspCfg = cfg
   186  	}
   187  }
   188  
   189  // WithCodec overrides the default codec (i.e., encoder and decoder). It is mostly used for testing purposes.
   190  // Note: do not override the default codec in production unless you know what you are doing.
   191  func WithCodec(codec network.Codec) NetworkConfigOption {
   192  	return func(params *NetworkConfig) {
   193  		params.Codec = codec
   194  	}
   195  }
   196  
   197  func WithSlashingViolationConsumerFactory(factory func(adapter network.ConduitAdapter) network.ViolationsConsumer) NetworkConfigOption {
   198  	return func(params *NetworkConfig) {
   199  		params.SlashingViolationConsumerFactory = factory
   200  	}
   201  }
   202  
   203  // NetworkOption is a function that can be used to override network attributes.
   204  // It is mostly used for testing purposes.
   205  // Note: do not override network attributes in production unless you know what you are doing.
   206  type NetworkOption func(*Network)
   207  
   208  // WithAlspManager sets the misbehavior report manager for the network. It overrides the default
   209  // misbehavior report manager that is created from the config.
   210  // Note that this option is mostly used for testing purposes, do not use it in production unless you
   211  // know what you are doing.
   212  //
   213  // Args:
   214  //
   215  //	mgr: misbehavior report manager
   216  //
   217  // Returns:
   218  //
   219  //	NetworkOption: network option
   220  func WithAlspManager(mgr network.MisbehaviorReportManager) NetworkOption {
   221  	return func(n *Network) {
   222  		n.misbehaviorReportManager = mgr
   223  	}
   224  }
   225  
   226  // WithPeerManagerFilters sets the peer manager filters for the network. It overrides the default
   227  // peer manager filters that are created from the config.
   228  func WithPeerManagerFilters(filters ...p2p.PeerFilter) NetworkOption {
   229  	return func(n *Network) {
   230  		n.peerManagerFilters = filters
   231  	}
   232  }
   233  
   234  // WithUnicastRateLimiters sets the unicast rate limiters for the network. It overrides the default
   235  // unicast rate limiters that are created from the config.
   236  func WithUnicastRateLimiters(limiters *ratelimit.RateLimiters) NetworkOption {
   237  	return func(n *Network) {
   238  		n.unicastRateLimiters = limiters
   239  	}
   240  }
   241  
   242  // WithPreferredUnicastProtocols sets the preferred unicast protocols for the network. It overrides the default
   243  // preferred unicast.
   244  func WithPreferredUnicastProtocols(protocols ...protocols.ProtocolName) NetworkOption {
   245  	return func(n *Network) {
   246  		n.preferredUnicasts = protocols
   247  	}
   248  }
   249  
   250  // WithMessageValidators sets the message validators for the network. It overrides the default
   251  // message validators.
   252  func WithMessageValidators(validators ...network.MessageValidator) NetworkOption {
   253  	return func(n *Network) {
   254  		n.validators = validators
   255  	}
   256  }
   257  
   258  // NewNetwork creates a new network with the given configuration.
   259  // Args:
   260  // param: network configuration
   261  // opts: network options
   262  // Returns:
   263  // Network: a new network
   264  func NewNetwork(param *NetworkConfig, opts ...NetworkOption) (*Network, error) {
   265  	param.Validate()
   266  
   267  	n := &Network{
   268  		logger:                      param.Logger.With().Str("component", "network").Logger(),
   269  		codec:                       param.Codec,
   270  		me:                          param.Me,
   271  		receiveCache:                param.ReceiveCache,
   272  		topology:                    param.Topology,
   273  		metrics:                     param.Metrics,
   274  		bitswapMetrics:              param.BitSwapMetrics,
   275  		identityProvider:            param.IdentityProvider,
   276  		conduitFactory:              param.ConduitFactory,
   277  		registerEngineRequests:      make(chan *registerEngineRequest),
   278  		registerBlobServiceRequests: make(chan *registerBlobServiceRequest),
   279  		sporkId:                     param.SporkId,
   280  		identityTranslator:          param.IdentityTranslator,
   281  		unicastMessageTimeout:       param.UnicastMessageTimeout,
   282  		libP2PNode:                  param.Libp2pNode,
   283  		unicastRateLimiters:         ratelimit.NoopRateLimiters(),
   284  		validators:                  DefaultValidators(param.Logger.With().Str("component", "network-validators").Logger(), param.Me.NodeID()),
   285  	}
   286  
   287  	n.subscriptionManager = subscription.NewChannelSubscriptionManager(n)
   288  
   289  	misbehaviorMngr, err := alspmgr.NewMisbehaviorReportManager(param.AlspCfg, n)
   290  	if err != nil {
   291  		return nil, fmt.Errorf("could not create misbehavior report manager: %w", err)
   292  	}
   293  	n.misbehaviorReportManager = misbehaviorMngr
   294  
   295  	for _, opt := range opts {
   296  		opt(n)
   297  	}
   298  
   299  	if err := n.conduitFactory.RegisterAdapter(n); err != nil {
   300  		return nil, fmt.Errorf("could not register network adapter: %w", err)
   301  	}
   302  
   303  	builder := component.NewComponentManagerBuilder()
   304  	builder.AddWorker(func(ctx irrecoverable.SignalerContext, ready component.ReadyFunc) {
   305  		n.logger.Debug().Msg("starting misbehavior manager")
   306  		n.misbehaviorReportManager.Start(ctx)
   307  
   308  		select {
   309  		case <-n.misbehaviorReportManager.Ready():
   310  			n.logger.Debug().Msg("misbehavior manager is ready")
   311  			ready()
   312  		case <-ctx.Done():
   313  			// jumps to the end of the select statement to let a graceful shutdown.
   314  		}
   315  
   316  		<-ctx.Done()
   317  		n.logger.Debug().Msg("stopping misbehavior manager")
   318  		<-n.misbehaviorReportManager.Done()
   319  		n.logger.Debug().Msg("misbehavior manager stopped")
   320  	})
   321  	builder.AddWorker(func(ctx irrecoverable.SignalerContext, ready component.ReadyFunc) {
   322  		n.logger.Debug().Msg("setting up network context")
   323  		n.ctx = ctx
   324  
   325  		ready()
   326  
   327  		<-ctx.Done()
   328  		n.logger.Debug().Msg("network context is done")
   329  	})
   330  
   331  	for _, limiter := range n.unicastRateLimiters.Limiters() {
   332  		rateLimiter := limiter
   333  		builder.AddWorker(func(ctx irrecoverable.SignalerContext, ready component.ReadyFunc) {
   334  			ready()
   335  			rateLimiter.Start(ctx)
   336  			<-rateLimiter.Ready()
   337  			ready()
   338  			<-rateLimiter.Done()
   339  		})
   340  	}
   341  
   342  	builder.AddWorker(func(ctx irrecoverable.SignalerContext, ready component.ReadyFunc) {
   343  		// creation of slashing violations consumer should be postponed till here where the network
   344  		// is start and the overlay is set.
   345  		n.slashingViolationsConsumer = param.SlashingViolationConsumerFactory(n)
   346  
   347  		n.authorizedSenderValidator = validator.NewAuthorizedSenderValidator(
   348  			n.logger,
   349  			n.slashingViolationsConsumer,
   350  			n.Identity)
   351  
   352  		err := n.libP2PNode.WithDefaultUnicastProtocol(n.handleIncomingStream, n.preferredUnicasts)
   353  		if err != nil {
   354  			ctx.Throw(fmt.Errorf("could not register preferred unicast protocols on libp2p node: %w", err))
   355  		}
   356  
   357  		n.UpdateNodeAddresses()
   358  		n.libP2PNode.WithPeersProvider(n.authorizedPeers)
   359  
   360  		ready()
   361  
   362  		<-ctx.Done()
   363  		n.logger.Info().Str("component", "network").Msg("stopping subroutines, blocking on read connection loops to end")
   364  
   365  		// wait for the readConnection and readSubscription routines to stop
   366  		n.wg.Wait()
   367  		n.logger.Info().Str("component", "network").Msg("stopped subroutines")
   368  	})
   369  
   370  	builder.AddWorker(n.createInboundMessageQueue)
   371  	builder.AddWorker(n.processRegisterEngineRequests)
   372  	builder.AddWorker(n.processRegisterBlobServiceRequests)
   373  
   374  	n.ComponentManager = builder.Build()
   375  	return n, nil
   376  }
   377  
   378  func (n *Network) processRegisterEngineRequests(parent irrecoverable.SignalerContext, ready component.ReadyFunc) {
   379  	ready()
   380  
   381  	// we need to wait for the libp2p node to be ready before we can register engines
   382  	n.logger.Debug().Msg("waiting for libp2p node to be ready")
   383  	<-n.libP2PNode.Ready()
   384  	n.logger.Debug().Msg("libp2p node is ready")
   385  
   386  	for {
   387  		select {
   388  		case req := <-n.registerEngineRequests:
   389  			conduit, err := n.handleRegisterEngineRequest(parent, req.channel, req.messageProcessor)
   390  			resp := &registerEngineResp{
   391  				conduit: conduit,
   392  				err:     err,
   393  			}
   394  
   395  			select {
   396  			case <-parent.Done():
   397  				return
   398  			case req.respChan <- resp:
   399  			}
   400  		case <-parent.Done():
   401  			return
   402  		}
   403  	}
   404  }
   405  
   406  func (n *Network) processRegisterBlobServiceRequests(parent irrecoverable.SignalerContext, ready component.ReadyFunc) {
   407  	ready()
   408  
   409  	n.logger.Debug().Msg("waiting for libp2p node to be ready")
   410  	<-n.libP2PNode.Ready()
   411  	n.logger.Debug().Msg("libp2p node is ready")
   412  
   413  	for {
   414  		select {
   415  		case req := <-n.registerBlobServiceRequests:
   416  			blobService, err := n.handleRegisterBlobServiceRequest(parent, req.channel, req.ds, req.opts)
   417  			resp := &registerBlobServiceResp{
   418  				blobService: blobService,
   419  				err:         err,
   420  			}
   421  
   422  			select {
   423  			case <-parent.Done():
   424  				return
   425  			case req.respChan <- resp:
   426  			}
   427  		case <-parent.Done():
   428  			return
   429  		}
   430  	}
   431  }
   432  
   433  // createInboundMessageQueue creates the queue that will be used to process incoming messages.
   434  func (n *Network) createInboundMessageQueue(ctx irrecoverable.SignalerContext, ready component.ReadyFunc) {
   435  	n.queue = queue.NewMessageQueue(ctx, queue.GetEventPriority, n.metrics)
   436  	queue.CreateQueueWorkers(ctx, queue.DefaultNumWorkers, n.queue, n.queueSubmitFunc)
   437  
   438  	ready()
   439  }
   440  
   441  func (n *Network) handleRegisterEngineRequest(parent irrecoverable.SignalerContext, channel channels.Channel, engine network.MessageProcessor) (network.Conduit, error) {
   442  	if !channels.ChannelExists(channel) {
   443  		return nil, fmt.Errorf("unknown channel: %s, should be registered in topic map", channel)
   444  	}
   445  
   446  	err := n.subscriptionManager.Register(channel, engine)
   447  	if err != nil {
   448  		return nil, fmt.Errorf("failed to register engine for channel %s: %w", channel, err)
   449  	}
   450  
   451  	n.logger.Info().
   452  		Str("channel_id", channel.String()).
   453  		Msg("channel successfully registered")
   454  
   455  	// create the conduit
   456  	newConduit, err := n.conduitFactory.NewConduit(parent, channel)
   457  	if err != nil {
   458  		return nil, fmt.Errorf("could not create conduit using factory: %w", err)
   459  	}
   460  
   461  	return newConduit, nil
   462  }
   463  
   464  func (n *Network) handleRegisterBlobServiceRequest(
   465  	parent irrecoverable.SignalerContext,
   466  	channel channels.Channel,
   467  	ds datastore.Batching,
   468  	opts []network.BlobServiceOption,
   469  ) (network.BlobService, error) {
   470  	bs, err := blob.NewBlobService(n.libP2PNode.Host(), n.libP2PNode.Routing(), channel.String(), ds, n.bitswapMetrics, n.logger, opts...)
   471  	if err != nil {
   472  		return nil, fmt.Errorf("could not create blob service: %w", err)
   473  	}
   474  
   475  	// start the blob service using the network's context
   476  	bs.Start(parent)
   477  
   478  	return bs, nil
   479  }
   480  
   481  // Register will register the given engine with the given unique engine engineID,
   482  // returning a conduit to directly submit messages to the message bus of the
   483  // engine.
   484  func (n *Network) Register(channel channels.Channel, messageProcessor network.MessageProcessor) (network.Conduit, error) {
   485  	respChan := make(chan *registerEngineResp)
   486  
   487  	select {
   488  	case <-n.ComponentManager.ShutdownSignal():
   489  		return nil, ErrNetworkShutdown
   490  	case n.registerEngineRequests <- &registerEngineRequest{
   491  		channel:          channel,
   492  		messageProcessor: messageProcessor,
   493  		respChan:         respChan,
   494  	}:
   495  		select {
   496  		case <-n.ComponentManager.ShutdownSignal():
   497  			return nil, ErrNetworkShutdown
   498  		case resp := <-respChan:
   499  			return resp.conduit, resp.err
   500  		}
   501  	}
   502  }
   503  
   504  func (n *Network) RegisterPingService(pingProtocol protocol.ID, provider network.PingInfoProvider) (network.PingService, error) {
   505  	select {
   506  	case <-n.ComponentManager.ShutdownSignal():
   507  		return nil, ErrNetworkShutdown
   508  	default:
   509  		return ping.NewPingService(n.libP2PNode.Host(), pingProtocol, n.logger, provider), nil
   510  	}
   511  }
   512  
   513  // RegisterBlobService registers a BlobService on the given channel.
   514  // The returned BlobService can be used to request blobs from the network.
   515  func (n *Network) RegisterBlobService(channel channels.Channel, ds datastore.Batching, opts ...network.BlobServiceOption) (network.BlobService, error) {
   516  	respChan := make(chan *registerBlobServiceResp)
   517  
   518  	select {
   519  	case <-n.ComponentManager.ShutdownSignal():
   520  		return nil, ErrNetworkShutdown
   521  	case n.registerBlobServiceRequests <- &registerBlobServiceRequest{
   522  		channel:  channel,
   523  		ds:       ds,
   524  		opts:     opts,
   525  		respChan: respChan,
   526  	}:
   527  		select {
   528  		case <-n.ComponentManager.ShutdownSignal():
   529  			return nil, ErrNetworkShutdown
   530  		case resp := <-respChan:
   531  			return resp.blobService, resp.err
   532  		}
   533  	}
   534  }
   535  
   536  // UnRegisterChannel unregisters the engine for the specified channel. The engine will no longer be able to send or
   537  // receive messages from that channel.
   538  func (n *Network) UnRegisterChannel(channel channels.Channel) error {
   539  	err := n.subscriptionManager.Unregister(channel)
   540  	if err != nil {
   541  		return fmt.Errorf("failed to unregister engine for channel %s: %w", channel, err)
   542  	}
   543  	return nil
   544  }
   545  
   546  func (n *Network) Identities() flow.IdentityList {
   547  	return n.identityProvider.Identities(filter.NotEjectedFilter)
   548  }
   549  
   550  func (n *Network) Identity(pid peer.ID) (*flow.Identity, bool) {
   551  	return n.identityProvider.ByPeerID(pid)
   552  }
   553  
   554  func (n *Network) Receive(msg network.IncomingMessageScope) error {
   555  	n.metrics.InboundMessageReceived(msg.Size(), msg.Channel().String(), msg.Protocol().String(), msg.PayloadType())
   556  
   557  	err := n.processNetworkMessage(msg)
   558  	if err != nil {
   559  		return fmt.Errorf("could not process message: %w", err)
   560  	}
   561  	return nil
   562  }
   563  
   564  func (n *Network) processNetworkMessage(msg network.IncomingMessageScope) error {
   565  	// checks the cache for deduplication and adds the message if not already present
   566  	if !n.receiveCache.Add(msg.EventID()) {
   567  		// drops duplicate message
   568  		n.logger.Debug().
   569  			Hex("sender_id", logging.ID(msg.OriginId())).
   570  			Hex("event_id", msg.EventID()).
   571  			Str("channel", msg.Channel().String()).
   572  			Msg("dropping message due to duplication")
   573  
   574  		n.metrics.DuplicateInboundMessagesDropped(msg.Channel().String(), msg.Protocol().String(), msg.PayloadType())
   575  
   576  		return nil
   577  	}
   578  
   579  	// create queue message
   580  	qm := queue.QMessage{
   581  		Payload:  msg.DecodedPayload(),
   582  		Size:     msg.Size(),
   583  		Target:   msg.Channel(),
   584  		SenderID: msg.OriginId(),
   585  	}
   586  
   587  	// insert the message in the queue
   588  	err := n.queue.Insert(qm)
   589  	if err != nil {
   590  		return fmt.Errorf("failed to insert message in queue: %w", err)
   591  	}
   592  
   593  	return nil
   594  }
   595  
   596  // UnicastOnChannel sends the message in a reliable way to the given recipient.
   597  // It uses 1-1 direct messaging over the underlying network to deliver the message.
   598  // It returns an error if unicasting fails.
   599  func (n *Network) UnicastOnChannel(channel channels.Channel, payload interface{}, targetID flow.Identifier) error {
   600  	if targetID == n.me.NodeID() {
   601  		n.logger.Debug().Msg("network skips self unicasting")
   602  		return nil
   603  	}
   604  
   605  	msg, err := message.NewOutgoingScope(
   606  		flow.IdentifierList{targetID},
   607  		channels.TopicFromChannel(channel, n.sporkId),
   608  		payload,
   609  		n.codec.Encode,
   610  		message.ProtocolTypeUnicast)
   611  	if err != nil {
   612  		return fmt.Errorf("could not generate outgoing message scope for unicast: %w", err)
   613  	}
   614  
   615  	n.metrics.UnicastMessageSendingStarted(channel.String())
   616  	defer n.metrics.UnicastMessageSendingCompleted(channel.String())
   617  
   618  	// since it is a unicast, we only need to get the first peer ID.
   619  	peerID, err := n.identityTranslator.GetPeerID(msg.TargetIds()[0])
   620  	if err != nil {
   621  		return fmt.Errorf("could not find peer id for target id: %w", err)
   622  	}
   623  
   624  	maxMsgSize := unicastMaxMsgSize(msg.PayloadType())
   625  	if msg.Size() > maxMsgSize {
   626  		// message size goes beyond maximum size that the serializer can handle.
   627  		// proceeding with this message results in closing the connection by the target side, and
   628  		// delivery failure.
   629  		return fmt.Errorf("message size %d exceeds configured max message size %d", msg.Size(), maxMsgSize)
   630  	}
   631  
   632  	maxTimeout := n.unicastMaxMsgDuration(msg.PayloadType())
   633  
   634  	// pass in a context with timeout to make the unicast call fail fast
   635  	ctx, cancel := context.WithTimeout(n.ctx, maxTimeout)
   636  	defer cancel()
   637  
   638  	// protect the underlying connection from being inadvertently pruned by the peer manager while the stream and
   639  	// connection creation is being attempted, and remove it from protected list once stream created.
   640  	channel, ok := channels.ChannelFromTopic(msg.Topic())
   641  	if !ok {
   642  		return fmt.Errorf("could not find channel for topic %s", msg.Topic())
   643  	}
   644  	streamProtectionTag := fmt.Sprintf("%v:%v", channel, msg.PayloadType())
   645  
   646  	err = n.libP2PNode.OpenAndWriteOnStream(ctx, peerID, streamProtectionTag, func(stream libp2pnet.Stream) error {
   647  		bufw := bufio.NewWriter(stream)
   648  		writer := ggio.NewDelimitedWriter(bufw)
   649  
   650  		err = writer.WriteMsg(msg.Proto())
   651  		if err != nil {
   652  			return fmt.Errorf("failed to send message to target id %x with peer id %s: %w", msg.TargetIds()[0], peerID, err)
   653  		}
   654  
   655  		// flush the stream
   656  		err = bufw.Flush()
   657  		if err != nil {
   658  			return fmt.Errorf("failed to flush stream for target id %x with peer id %s: %w", msg.TargetIds()[0], peerID, err)
   659  		}
   660  
   661  		return nil
   662  	})
   663  	if err != nil {
   664  		return fmt.Errorf("failed to send message to %x: %w", targetID, err)
   665  	}
   666  
   667  	n.metrics.OutboundMessageSent(msg.Size(), channel.String(), message.ProtocolTypeUnicast.String(), msg.PayloadType())
   668  	return nil
   669  }
   670  
   671  // PublishOnChannel sends the message in an unreliable way to the given recipients.
   672  // In this context, unreliable means that the message is published over a libp2p pub-sub
   673  // channel and can be read by any node subscribed to that channel.
   674  // The selector could be used to optimize or restrict delivery.
   675  func (n *Network) PublishOnChannel(channel channels.Channel, message interface{}, targetIDs ...flow.Identifier) error {
   676  	filteredIDs := flow.IdentifierList(targetIDs).Filter(n.removeSelfFilter())
   677  
   678  	if len(filteredIDs) == 0 {
   679  		return network.EmptyTargetList
   680  	}
   681  
   682  	err := n.sendOnChannel(channel, message, filteredIDs)
   683  
   684  	if err != nil {
   685  		return fmt.Errorf("failed to publish on channel %s: %w", channel, err)
   686  	}
   687  
   688  	return nil
   689  }
   690  
   691  // MulticastOnChannel unreliably sends the specified event over the channel to randomly selected 'num' number of recipients
   692  // selected from the specified targetIDs.
   693  func (n *Network) MulticastOnChannel(channel channels.Channel, message interface{}, num uint, targetIDs ...flow.Identifier) error {
   694  	selectedIDs, err := flow.IdentifierList(targetIDs).Filter(n.removeSelfFilter()).Sample(num)
   695  	if err != nil {
   696  		return fmt.Errorf("sampling failed: %w", err)
   697  	}
   698  
   699  	if len(selectedIDs) == 0 {
   700  		return network.EmptyTargetList
   701  	}
   702  
   703  	err = n.sendOnChannel(channel, message, selectedIDs)
   704  
   705  	// publishes the message to the selected targets
   706  	if err != nil {
   707  		return fmt.Errorf("failed to multicast on channel %s: %w", channel, err)
   708  	}
   709  
   710  	return nil
   711  }
   712  
   713  // removeSelfFilter removes the flow.Identifier of this node if present, from the list of nodes
   714  func (n *Network) removeSelfFilter() flow.IdentifierFilter {
   715  	return func(id flow.Identifier) bool {
   716  		return id != n.me.NodeID()
   717  	}
   718  }
   719  
   720  // sendOnChannel sends the message on channel to targets.
   721  func (n *Network) sendOnChannel(channel channels.Channel, msg interface{}, targetIDs []flow.Identifier) error {
   722  	n.logger.Debug().
   723  		Interface("message", msg).
   724  		Str("channel", channel.String()).
   725  		Str("target_ids", fmt.Sprintf("%v", targetIDs)).
   726  		Msg("sending new message on channel")
   727  
   728  	// generate network message (encoding) based on list of recipients
   729  	scope, err := message.NewOutgoingScope(
   730  		targetIDs,
   731  		channels.TopicFromChannel(channel, n.sporkId),
   732  		msg,
   733  		n.codec.Encode,
   734  		message.ProtocolTypePubSub)
   735  	if err != nil {
   736  		return fmt.Errorf("failed to generate outgoing message scope %s: %w", channel, err)
   737  	}
   738  
   739  	// publish the message through the channel, however, the message
   740  	// is only restricted to targetIDs (if they subscribed to channel).
   741  	err = n.libP2PNode.Publish(n.ctx, scope)
   742  	if err != nil {
   743  		return fmt.Errorf("failed to send message on channel %s: %w", channel, err)
   744  	}
   745  
   746  	n.metrics.OutboundMessageSent(scope.Size(), channel.String(), message.ProtocolTypePubSub.String(), scope.PayloadType())
   747  
   748  	return nil
   749  }
   750  
   751  // queueSubmitFunc submits the message to the engine synchronously. It is the callback for the queue worker
   752  // when it gets a message from the queue
   753  func (n *Network) queueSubmitFunc(message interface{}) {
   754  	qm := message.(queue.QMessage)
   755  
   756  	logger := n.logger.With().
   757  		Str("channel_id", qm.Target.String()).
   758  		Str("sender_id", qm.SenderID.String()).
   759  		Logger()
   760  
   761  	eng, err := n.subscriptionManager.GetEngine(qm.Target)
   762  	if err != nil {
   763  		// This means the message was received on a channel that the node has not registered an
   764  		// engine for. This may be because the message was received during startup and the node
   765  		// hasn't subscribed to the channel yet, or there is a bug.
   766  		logger.Err(err).Msg("failed to submit message")
   767  		return
   768  	}
   769  
   770  	logger.Debug().Msg("submitting message to engine")
   771  
   772  	n.metrics.MessageProcessingStarted(qm.Target.String())
   773  
   774  	// submits the message to the engine synchronously and
   775  	// tracks its processing time.
   776  	startTimestamp := time.Now()
   777  
   778  	err = eng.Process(qm.Target, qm.SenderID, qm.Payload)
   779  	if err != nil {
   780  		logger.Err(err).Msg("failed to process message")
   781  	}
   782  
   783  	n.metrics.MessageProcessingFinished(qm.Target.String(), time.Since(startTimestamp))
   784  }
   785  
   786  func (n *Network) Topology() flow.IdentityList {
   787  	return n.topology.Fanout(n.Identities())
   788  }
   789  
   790  // ReportMisbehaviorOnChannel reports the misbehavior of a node on sending a message to the current node that appears
   791  // valid based on the networking layer but is considered invalid by the current node based on the Flow protocol.
   792  // The misbehavior report is sent to the current node's networking layer on the given channel to be processed.
   793  // Args:
   794  // - channel: The channel on which the misbehavior report is sent.
   795  // - report: The misbehavior report to be sent.
   796  // Returns:
   797  // none
   798  func (n *Network) ReportMisbehaviorOnChannel(channel channels.Channel, report network.MisbehaviorReport) {
   799  	n.misbehaviorReportManager.HandleMisbehaviorReport(channel, report)
   800  }
   801  
   802  func DefaultValidators(log zerolog.Logger, flowID flow.Identifier) []network.MessageValidator {
   803  	return []network.MessageValidator{
   804  		validator.ValidateNotSender(flowID),   // validator to filter out messages sent by this node itself
   805  		validator.ValidateTarget(log, flowID), // validator to filter out messages not intended for this node
   806  	}
   807  }
   808  
   809  // isProtocolParticipant returns a PeerFilter that returns true if a peer is a staked (i.e., authorized) node.
   810  func (n *Network) isProtocolParticipant() p2p.PeerFilter {
   811  	return func(p peer.ID) error {
   812  		if _, ok := n.Identity(p); !ok {
   813  			return fmt.Errorf("failed to get identity of unknown peer with peer id %s", p2plogging.PeerId(p))
   814  		}
   815  		return nil
   816  	}
   817  }
   818  
   819  func (n *Network) peerIDs(flowIDs flow.IdentifierList) peer.IDSlice {
   820  	result := make([]peer.ID, 0, len(flowIDs))
   821  
   822  	for _, fid := range flowIDs {
   823  		pid, err := n.identityTranslator.GetPeerID(fid)
   824  		if err != nil {
   825  			// We probably don't need to fail the entire function here, since the other
   826  			// translations may still succeed
   827  			n.logger.
   828  				Err(err).
   829  				Str(logging.KeySuspicious, "true").
   830  				Hex("node_id", logging.ID(fid)).
   831  				Msg("failed to translate to peer ID")
   832  			continue
   833  		}
   834  
   835  		result = append(result, pid)
   836  	}
   837  
   838  	return result
   839  }
   840  
   841  func (n *Network) UpdateNodeAddresses() {
   842  	n.logger.Info().Msg("updating protocol state node addresses")
   843  
   844  	ids := n.Identities()
   845  	newInfos, invalid := utils.PeerInfosFromIDs(ids)
   846  
   847  	for id, err := range invalid {
   848  		n.logger.
   849  			Err(err).
   850  			Bool(logging.KeySuspicious, true).
   851  			Hex("node_id", logging.ID(id)).
   852  			Msg("failed to extract peer info from identity")
   853  	}
   854  
   855  	n.peerUpdateLock.Lock()
   856  	defer n.peerUpdateLock.Unlock()
   857  
   858  	// set old addresses to expire
   859  	for _, oldInfo := range n.previousProtocolStatePeers {
   860  		n.libP2PNode.Host().Peerstore().SetAddrs(oldInfo.ID, oldInfo.Addrs, peerstore.TempAddrTTL)
   861  	}
   862  
   863  	for _, info := range newInfos {
   864  		n.libP2PNode.Host().Peerstore().SetAddrs(info.ID, info.Addrs, peerstore.PermanentAddrTTL)
   865  	}
   866  
   867  	n.previousProtocolStatePeers = newInfos
   868  }
   869  
   870  // authorizedPeers is a peer manager callback used by the underlying libp2p node that updates who can connect to this node (as
   871  // well as who this node can connect to).
   872  // and who is not allowed to connect to this node. This function is called by the peer manager and connection gater components
   873  // of libp2p.
   874  //
   875  // Args:
   876  // none
   877  // Returns:
   878  // - peer.IDSlice: a list of peer IDs that are allowed to connect to this node (and that this node can connect to). Any peer
   879  // not in this list is assumed to be disconnected from this node (if connected) and not allowed to connect to this node.
   880  // This is the guarantee that the underlying libp2p node implementation makes.
   881  func (n *Network) authorizedPeers() peer.IDSlice {
   882  	peerIDs := make([]peer.ID, 0)
   883  	for _, id := range n.peerIDs(n.Topology().NodeIDs()) {
   884  		peerAllowed := true
   885  		for _, filter := range n.peerManagerFilters {
   886  			if err := filter(id); err != nil {
   887  				n.logger.Debug().
   888  					Err(err).
   889  					Str("peer_id", p2plogging.PeerId(id)).
   890  					Msg("filtering topology peer")
   891  
   892  				peerAllowed = false
   893  				break
   894  			}
   895  		}
   896  
   897  		if peerAllowed {
   898  			peerIDs = append(peerIDs, id)
   899  		}
   900  	}
   901  
   902  	return peerIDs
   903  }
   904  
   905  func (n *Network) OnDisallowListNotification(notification *network.DisallowListingUpdate) {
   906  	for _, pid := range n.peerIDs(notification.FlowIds) {
   907  		n.libP2PNode.OnDisallowListNotification(pid, notification.Cause)
   908  	}
   909  }
   910  
   911  func (n *Network) OnAllowListNotification(notification *network.AllowListingUpdate) {
   912  	for _, pid := range n.peerIDs(notification.FlowIds) {
   913  		n.libP2PNode.OnAllowListNotification(pid, notification.Cause)
   914  	}
   915  }
   916  
   917  // handleIncomingStream handles an incoming stream from a remote peer
   918  // it is a callback that gets called for each incoming stream by libp2p with a new stream object.
   919  // TODO: this should be eventually moved to libp2p node.
   920  func (n *Network) handleIncomingStream(s libp2pnet.Stream) {
   921  	// qualify the logger with local and remote address
   922  	log := p2putils.StreamLogger(n.logger, s)
   923  
   924  	log.Info().Msg("incoming stream received")
   925  
   926  	success := false
   927  
   928  	remotePeer := s.Conn().RemotePeer()
   929  
   930  	defer func() {
   931  		if success {
   932  			err := s.Close()
   933  			if err != nil {
   934  				log.Err(err).Msg("failed to close stream")
   935  			}
   936  		} else {
   937  			err := s.Reset()
   938  			if err != nil {
   939  				log.Err(err).Msg("failed to reset stream")
   940  			}
   941  		}
   942  	}()
   943  
   944  	// check if peer is currently rate limited before continuing to process stream.
   945  	if n.unicastRateLimiters.MessageRateLimiter.IsRateLimited(remotePeer) || n.unicastRateLimiters.BandWidthRateLimiter.IsRateLimited(remotePeer) {
   946  		log.Debug().
   947  			Bool(logging.KeySuspicious, true).
   948  			Msg("dropping unicast stream from rate limited peer")
   949  		return
   950  	}
   951  
   952  	// TODO: We need to allow per-topic timeouts and message size limits.
   953  	// This allows us to configure higher limits for topics on which we expect
   954  	// to receive large messages (e.g. Chunk Data Packs), and use the normal
   955  	// limits for other topics. In order to enable this, we will need to register
   956  	// a separate stream handler for each topic.
   957  	ctx, cancel := context.WithTimeout(n.ctx, LargeMsgUnicastTimeout)
   958  	defer cancel()
   959  
   960  	deadline, _ := ctx.Deadline()
   961  
   962  	err := s.SetReadDeadline(deadline)
   963  	if err != nil {
   964  		log.Err(err).Msg("failed to set read deadline for stream")
   965  		return
   966  	}
   967  
   968  	// create the reader
   969  	r := ggio.NewDelimitedReader(s, LargeMsgMaxUnicastMsgSize)
   970  	for {
   971  		if ctx.Err() != nil {
   972  			return
   973  		}
   974  
   975  		// Note: message fields must not be trusted until explicitly validated
   976  		var msg message.Message
   977  		// read the next message (blocking call)
   978  		err = r.ReadMsg(&msg)
   979  		if err != nil {
   980  			if err == io.EOF {
   981  				break
   982  			}
   983  
   984  			n.logger.Err(err).Msg("failed to read message")
   985  			return
   986  		}
   987  
   988  		channel := channels.Channel(msg.ChannelID)
   989  		topic := channels.TopicFromChannel(channel, n.sporkId)
   990  
   991  		// ignore messages if node does not have subscription to topic
   992  		if !n.libP2PNode.HasSubscription(topic) {
   993  			violation := &network.Violation{
   994  				Identity: nil, PeerID: p2plogging.PeerId(remotePeer), Channel: channel, Protocol: message.ProtocolTypeUnicast,
   995  			}
   996  
   997  			msgCode, err := codec.MessageCodeFromPayload(msg.Payload)
   998  			if err != nil {
   999  				violation.Err = err
  1000  				n.slashingViolationsConsumer.OnUnknownMsgTypeError(violation)
  1001  				return
  1002  			}
  1003  
  1004  			// msg type is not guaranteed to be correct since it is set by the client
  1005  			_, what, err := codec.InterfaceFromMessageCode(msgCode)
  1006  			if err != nil {
  1007  				violation.Err = err
  1008  				n.slashingViolationsConsumer.OnUnknownMsgTypeError(violation)
  1009  				return
  1010  			}
  1011  
  1012  			violation.MsgType = what
  1013  			violation.Err = ErrUnicastMsgWithoutSub
  1014  			n.slashingViolationsConsumer.OnUnauthorizedUnicastOnChannel(violation)
  1015  			return
  1016  		}
  1017  
  1018  		// check if unicast messages have reached rate limit before processing next message
  1019  		if !n.unicastRateLimiters.MessageAllowed(remotePeer) {
  1020  			return
  1021  		}
  1022  
  1023  		// check if we can get a role for logging and metrics label if this is not a public channel
  1024  		role := ""
  1025  		if !channels.IsPublicChannel(channels.Channel(msg.ChannelID)) {
  1026  			if identity, ok := n.Identity(remotePeer); ok {
  1027  				role = identity.Role.String()
  1028  			}
  1029  		}
  1030  
  1031  		// check unicast bandwidth rate limiter for peer
  1032  		if !n.unicastRateLimiters.BandwidthAllowed(
  1033  			remotePeer,
  1034  			role,
  1035  			msg.Size(),
  1036  			message.MessageType(msg.Payload),
  1037  			channels.Topic(msg.ChannelID)) {
  1038  			return
  1039  		}
  1040  
  1041  		n.wg.Add(1)
  1042  		go func() {
  1043  			defer n.wg.Done()
  1044  			n.processUnicastStreamMessage(remotePeer, &msg)
  1045  		}()
  1046  	}
  1047  
  1048  	success = true
  1049  }
  1050  
  1051  // Subscribe subscribes the network to a channel.
  1052  // No errors are expected during normal operation.
  1053  func (n *Network) Subscribe(channel channels.Channel) error {
  1054  	topic := channels.TopicFromChannel(channel, n.sporkId)
  1055  
  1056  	var peerFilter p2p.PeerFilter
  1057  	var validators []validator.PubSubMessageValidator
  1058  	if channels.IsPublicChannel(channel) {
  1059  		// NOTE: for public channels the callback used to check if a node is staked will
  1060  		// return true for every node.
  1061  		peerFilter = p2p.AllowAllPeerFilter()
  1062  	} else {
  1063  		// for channels used by the staked nodes, add the topic validator to filter out messages from non-staked nodes
  1064  		validators = append(validators, n.authorizedSenderValidator.PubSubMessageValidator(channel))
  1065  
  1066  		// NOTE: For non-public channels the libP2P node topic validator will reject
  1067  		// messages from unstaked nodes.
  1068  		peerFilter = n.isProtocolParticipant()
  1069  	}
  1070  
  1071  	topicValidator := flowpubsub.TopicValidator(n.logger, peerFilter, validators...)
  1072  	s, err := n.libP2PNode.Subscribe(topic, topicValidator)
  1073  	if err != nil {
  1074  		return fmt.Errorf("could not subscribe to topic (%s): %w", topic, err)
  1075  	}
  1076  
  1077  	// create a new readSubscription with the context of the network
  1078  	rs := internal.NewReadSubscription(s, n.processPubSubMessages, n.logger)
  1079  	n.wg.Add(1)
  1080  
  1081  	// kick off the receive loop to continuously receive messages
  1082  	go func() {
  1083  		defer n.wg.Done()
  1084  		rs.ReceiveLoop(n.ctx)
  1085  	}()
  1086  
  1087  	// update peers to add some nodes interested in the same topic as direct peers
  1088  	n.libP2PNode.RequestPeerUpdate()
  1089  
  1090  	return nil
  1091  }
  1092  
  1093  // processPubSubMessages processes messages received from the pubsub subscription.
  1094  func (n *Network) processPubSubMessages(msg *message.Message, peerID peer.ID) {
  1095  	n.processAuthenticatedMessage(msg, peerID, message.ProtocolTypePubSub)
  1096  }
  1097  
  1098  // Unsubscribe unsubscribes the network from a channel.
  1099  // The following benign errors are expected during normal operations from libP2P:
  1100  // - the libP2P node fails to unsubscribe to the topic created from the provided channel.
  1101  //
  1102  // All errors returned from this function can be considered benign.
  1103  func (n *Network) Unsubscribe(channel channels.Channel) error {
  1104  	topic := channels.TopicFromChannel(channel, n.sporkId)
  1105  	return n.libP2PNode.Unsubscribe(topic)
  1106  }
  1107  
  1108  // processUnicastStreamMessage will decode, perform authorized sender validation and process a message
  1109  // sent via unicast stream. This func should be invoked in a separate goroutine to avoid creating a message decoding bottleneck.
  1110  func (n *Network) processUnicastStreamMessage(remotePeer peer.ID, msg *message.Message) {
  1111  	channel := channels.Channel(msg.ChannelID)
  1112  
  1113  	// TODO: once we've implemented per topic message size limits per the TODO above,
  1114  	// we can remove this check
  1115  	maxSize, err := UnicastMaxMsgSizeByCode(msg.Payload)
  1116  	if err != nil {
  1117  		n.slashingViolationsConsumer.OnUnknownMsgTypeError(&network.Violation{
  1118  			Identity: nil, PeerID: p2plogging.PeerId(remotePeer), MsgType: "", Channel: channel, Protocol: message.ProtocolTypeUnicast, Err: err,
  1119  		})
  1120  		return
  1121  	}
  1122  	if msg.Size() > maxSize {
  1123  		// message size exceeded
  1124  		n.logger.Error().
  1125  			Str("peer_id", p2plogging.PeerId(remotePeer)).
  1126  			Str("channel", msg.ChannelID).
  1127  			Int("max_size", maxSize).
  1128  			Int("size", msg.Size()).
  1129  			Bool(logging.KeySuspicious, true).
  1130  			Msg("received message exceeded permissible message maxSize")
  1131  		return
  1132  	}
  1133  
  1134  	// if message channel is not public perform authorized sender validation
  1135  	if !channels.IsPublicChannel(channel) {
  1136  		messageType, err := n.authorizedSenderValidator.Validate(remotePeer, msg.Payload, channel, message.ProtocolTypeUnicast)
  1137  		if err != nil {
  1138  			n.logger.
  1139  				Error().
  1140  				Err(err).
  1141  				Str("peer_id", p2plogging.PeerId(remotePeer)).
  1142  				Str("type", messageType).
  1143  				Str("channel", msg.ChannelID).
  1144  				Msg("unicast authorized sender validation failed")
  1145  			return
  1146  		}
  1147  	}
  1148  	n.processAuthenticatedMessage(msg, remotePeer, message.ProtocolTypeUnicast)
  1149  }
  1150  
  1151  // processAuthenticatedMessage processes a message and a source (indicated by its peer ID) and eventually passes it to the overlay
  1152  // In particular, it populates the `OriginID` field of the message with a Flow ID translated from this source.
  1153  func (n *Network) processAuthenticatedMessage(msg *message.Message, peerID peer.ID, protocol message.ProtocolType) {
  1154  	originId, err := n.identityTranslator.GetFlowID(peerID)
  1155  	if err != nil {
  1156  		// this error should never happen. by the time the message gets here, the peer should be
  1157  		// authenticated which means it must be known
  1158  		n.logger.Error().
  1159  			Err(err).
  1160  			Str("peer_id", p2plogging.PeerId(peerID)).
  1161  			Bool(logging.KeySuspicious, true).
  1162  			Msg("dropped message from unknown peer")
  1163  		return
  1164  	}
  1165  
  1166  	channel := channels.Channel(msg.ChannelID)
  1167  	decodedMsgPayload, err := n.codec.Decode(msg.Payload)
  1168  	switch {
  1169  	case codec.IsErrUnknownMsgCode(err):
  1170  		// slash peer if message contains unknown message code byte
  1171  		violation := &network.Violation{
  1172  			PeerID: p2plogging.PeerId(peerID), OriginID: originId, Channel: channel, Protocol: protocol, Err: err,
  1173  		}
  1174  		n.slashingViolationsConsumer.OnUnknownMsgTypeError(violation)
  1175  		return
  1176  	case codec.IsErrMsgUnmarshal(err) || codec.IsErrInvalidEncoding(err):
  1177  		// slash if peer sent a message that could not be marshalled into the message type denoted by the message code byte
  1178  		violation := &network.Violation{
  1179  			PeerID: p2plogging.PeerId(peerID), OriginID: originId, Channel: channel, Protocol: protocol, Err: err,
  1180  		}
  1181  		n.slashingViolationsConsumer.OnInvalidMsgError(violation)
  1182  		return
  1183  	case err != nil:
  1184  		// this condition should never happen and indicates there's a bug
  1185  		// don't crash as a result of external inputs since that creates a DoS vector
  1186  		// collect slashing data because this could potentially lead to slashing
  1187  		err = fmt.Errorf("unexpected error during message validation: %w", err)
  1188  		violation := &network.Violation{
  1189  			PeerID: p2plogging.PeerId(peerID), OriginID: originId, Channel: channel, Protocol: protocol, Err: err,
  1190  		}
  1191  		n.slashingViolationsConsumer.OnUnexpectedError(violation)
  1192  		return
  1193  	}
  1194  
  1195  	scope, err := message.NewIncomingScope(originId, protocol, msg, decodedMsgPayload)
  1196  	if err != nil {
  1197  		n.logger.Error().
  1198  			Err(err).
  1199  			Str("peer_id", p2plogging.PeerId(peerID)).
  1200  			Str("origin_id", originId.String()).
  1201  			Msg("could not create incoming message scope")
  1202  		return
  1203  	}
  1204  
  1205  	n.processMessage(scope)
  1206  }
  1207  
  1208  // processMessage processes a message and eventually passes it to the overlay
  1209  func (n *Network) processMessage(scope network.IncomingMessageScope) {
  1210  	logger := n.logger.With().
  1211  		Str("channel", scope.Channel().String()).
  1212  		Str("type", scope.Protocol().String()).
  1213  		Int("msg_size", scope.Size()).
  1214  		Hex("origin_id", logging.ID(scope.OriginId())).
  1215  		Logger()
  1216  
  1217  	// run through all the message validators
  1218  	for _, v := range n.validators {
  1219  		// if any one fails, stop message propagation
  1220  		if !v.Validate(scope) {
  1221  			logger.Debug().Msg("new message filtered by message validators")
  1222  			return
  1223  		}
  1224  	}
  1225  
  1226  	logger.Debug().Msg("processing new message")
  1227  
  1228  	// if validation passed, send the message to the overlay
  1229  	err := n.Receive(scope)
  1230  	if err != nil {
  1231  		n.logger.Error().Err(err).Msg("could not deliver payload")
  1232  	}
  1233  }
  1234  
  1235  // UnicastMaxMsgSizeByCode returns the max permissible size for a unicast message code
  1236  func UnicastMaxMsgSizeByCode(payload []byte) (int, error) {
  1237  	msgCode, err := codec.MessageCodeFromPayload(payload)
  1238  	if err != nil {
  1239  		return 0, err
  1240  	}
  1241  	_, messageType, err := codec.InterfaceFromMessageCode(msgCode)
  1242  	if err != nil {
  1243  		return 0, err
  1244  	}
  1245  
  1246  	maxSize := unicastMaxMsgSize(messageType)
  1247  	return maxSize, nil
  1248  }
  1249  
  1250  // unicastMaxMsgSize returns the max permissible size for a unicast message
  1251  func unicastMaxMsgSize(messageType string) int {
  1252  	switch messageType {
  1253  	case "*messages.ChunkDataResponse", "messages.ChunkDataResponse":
  1254  		return LargeMsgMaxUnicastMsgSize
  1255  	default:
  1256  		return DefaultMaxUnicastMsgSize
  1257  	}
  1258  }
  1259  
  1260  // unicastMaxMsgDuration returns the max duration to allow for a unicast send to complete
  1261  func (n *Network) unicastMaxMsgDuration(messageType string) time.Duration {
  1262  	switch messageType {
  1263  	case "*messages.ChunkDataResponse", "messages.ChunkDataResponse":
  1264  		if LargeMsgUnicastTimeout > n.unicastMessageTimeout {
  1265  			return LargeMsgUnicastTimeout
  1266  		}
  1267  		return n.unicastMessageTimeout
  1268  	default:
  1269  		return n.unicastMessageTimeout
  1270  	}
  1271  }