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 }