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

     1  package conduit
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/onflow/flow-go/model/flow"
     8  	"github.com/onflow/flow-go/network"
     9  	"github.com/onflow/flow-go/network/channels"
    10  )
    11  
    12  // DefaultConduitFactory is a wrapper around the network ConduitAdapter.
    13  // It directly passes the incoming messages to the corresponding methods of the
    14  // network ConduitAdapter.
    15  type DefaultConduitFactory struct {
    16  	adapter network.ConduitAdapter
    17  }
    18  
    19  var _ network.ConduitFactory = (*DefaultConduitFactory)(nil)
    20  
    21  // NewDefaultConduitFactory creates a new DefaultConduitFactory, this is the default conduit factory used by the node.
    22  // Args:
    23  //
    24  //	none
    25  //
    26  // Returns:
    27  //
    28  //	a new instance of the DefaultConduitFactory.
    29  func NewDefaultConduitFactory() *DefaultConduitFactory {
    30  	return &DefaultConduitFactory{}
    31  }
    32  
    33  // RegisterAdapter sets the ConduitAdapter component of the factory.
    34  // The ConduitAdapter is a wrapper around the Network layer that only exposes the set of methods
    35  // that are needed by a conduit.
    36  func (d *DefaultConduitFactory) RegisterAdapter(adapter network.ConduitAdapter) error {
    37  	if d.adapter != nil {
    38  		return fmt.Errorf("could not register a new network adapter, one already exists")
    39  	}
    40  
    41  	d.adapter = adapter
    42  
    43  	return nil
    44  }
    45  
    46  // NewConduit creates a conduit on the specified channel.
    47  // Prior to creating any conduit, the factory requires an ConduitAdapter to be registered with it.
    48  func (d *DefaultConduitFactory) NewConduit(ctx context.Context, channel channels.Channel) (network.Conduit, error) {
    49  	if d.adapter == nil {
    50  		return nil, fmt.Errorf("could not create a new conduit, missing a registered network adapter")
    51  	}
    52  
    53  	child, cancel := context.WithCancel(ctx)
    54  
    55  	return &Conduit{
    56  		ctx:     child,
    57  		cancel:  cancel,
    58  		channel: channel,
    59  		adapter: d.adapter,
    60  	}, nil
    61  }
    62  
    63  // Conduit is a helper of the overlay layer which functions as an accessor for
    64  // sending messages within a single engine process. It sends all messages to
    65  // what can be considered a bus reserved for that specific engine.
    66  type Conduit struct {
    67  	ctx     context.Context
    68  	cancel  context.CancelFunc
    69  	channel channels.Channel
    70  	adapter network.ConduitAdapter
    71  }
    72  
    73  var _ network.Conduit = (*Conduit)(nil)
    74  
    75  // Publish sends an event to the network layer for unreliable delivery
    76  // to subscribers of the given event on the network layer. It uses a
    77  // publish-subscribe layer and can thus not guarantee that the specified
    78  // recipients received the event.
    79  func (c *Conduit) Publish(event interface{}, targetIDs ...flow.Identifier) error {
    80  	if c.ctx.Err() != nil {
    81  		return fmt.Errorf("conduit for channel %s closed", c.channel)
    82  	}
    83  	return c.adapter.PublishOnChannel(c.channel, event, targetIDs...)
    84  }
    85  
    86  // Unicast sends an event in a reliable way to the given recipient.
    87  // It uses 1-1 direct messaging over the underlying network to deliver the event.
    88  // It returns an error if the unicast fails.
    89  func (c *Conduit) Unicast(event interface{}, targetID flow.Identifier) error {
    90  	if c.ctx.Err() != nil {
    91  		return fmt.Errorf("conduit for channel %s closed", c.channel)
    92  	}
    93  	return c.adapter.UnicastOnChannel(c.channel, event, targetID)
    94  }
    95  
    96  // Multicast unreliably sends the specified event to the specified number of recipients selected from the specified subset.
    97  // The recipients are selected randomly from targetIDs
    98  func (c *Conduit) Multicast(event interface{}, num uint, targetIDs ...flow.Identifier) error {
    99  	if c.ctx.Err() != nil {
   100  		return fmt.Errorf("conduit for channel %s closed", c.channel)
   101  	}
   102  	return c.adapter.MulticastOnChannel(c.channel, event, num, targetIDs...)
   103  }
   104  
   105  // ReportMisbehavior reports the misbehavior of a node on sending a message to the current node that appears valid
   106  // based on the networking layer but is considered invalid by the current node based on the Flow protocol.
   107  // The misbehavior is reported to the networking layer to penalize the misbehaving node.
   108  // The implementation must be thread-safe and non-blocking.
   109  func (c *Conduit) ReportMisbehavior(report network.MisbehaviorReport) {
   110  	c.adapter.ReportMisbehaviorOnChannel(c.channel, report)
   111  }
   112  
   113  func (c *Conduit) Close() error {
   114  	if c.ctx.Err() != nil {
   115  		return fmt.Errorf("conduit for channel %s already closed", c.channel)
   116  	}
   117  	// close the conduit context
   118  	c.cancel()
   119  	// call the close function
   120  	return c.adapter.UnRegisterChannel(c.channel)
   121  }