Skip to content

Commit f58ccaf

Browse files
Apply suggestions from code review
Improve documentation for Process method of pusher engine, and log an error instead of returning an error. See: #6780 (comment) Co-authored-by: Alexander Hentschel <[email protected]>
1 parent 42b2331 commit f58ccaf

File tree

2 files changed

+24
-8
lines changed

2 files changed

+24
-8
lines changed

engine/collection/pusher/engine.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,26 @@ func (e *Engine) processOutboundMessages(ctx context.Context) error {
141141
}
142142
}
143143

144-
// Process processes the given event from the node with the given origin ID in
145-
// a non-blocking manner. It returns the potential processing error when done.
146-
// Because the pusher engine does not accept inputs from the network,
147-
// always drop any messages and return an error.
144+
// Process is called by the networking layer, when peers broadcast messages with this node
145+
// as one of the recipients. The protocol specifies that Collector nodes broadcast Collection
146+
// Guarantees to Consensus Nodes and _only_ those. When the pusher engine (running only on
147+
// Collectors) receives a message, this message is evidence of byzantine behavior.
148+
// Byzantine inputs are internally handled by the pusher.Engine and do *not* result in
149+
// error returns. No errors expected during normal operation (including byzantine inputs).
148150
func (e *Engine) Process(channel channels.Channel, originID flow.Identifier, message any) error {
149-
return fmt.Errorf("pusher engine should only receive local messages on the same node: got message %T on channel %v from origin %v", message, channel, originID)
151+
// Targeting a collector node's pusher.Engine with messages could be considered as a slashable offense.
152+
// Though, for generating cryptographic evidence, we need Message Forensics - see reference [1].
153+
// Much further into the future, when we are implementing slashing challenges, we'll probably implement a
154+
// dedicated consumer to post-process evidence of protocol violations into slashing challenges. For now,
155+
// we just log this with the `KeySuspicious` to alert the node operator.
156+
// [1] Message Forensics FLIP https://github.com/onflow/flips/pull/195)
157+
errs := fmt.Errorf("collector node's pusher.Engine was targeted by message %T on channel %v", message, channel)
158+
e.log.Warn().
159+
Err(errs).
160+
Bool(logging.KeySuspicious, true).
161+
Str("peer_id", originID.String()).
162+
Msg("potentially byzantine networking traffic detected")
163+
return nil
150164
}
151165

152166
// SubmitCollectionGuarantee adds a collection guarantee to the engine's queue

engine/collection/pusher/engine_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,13 @@ func (suite *Suite) TestSubmitCollectionGuaranteeNonLocal() {
108108

109109
guarantee := unittest.CollectionGuaranteeFixture()
110110

111-
// send from a non-allowed role
111+
// verify that pusher.Engine handles any (potentially byzantine) input:
112+
// A byzantine peer could target the collector node's pusher engine with messages
113+
// The pusher should discard those and explicitly not get tricked into broadcasting
114+
// collection guarantees which a byzantine peer might try to inject into the system.
112115
sender := suite.identities.Filter(filter.HasRole[flow.Identity](flow.RoleVerification))[0]
113116

114117
err := suite.engine.Process(channels.PushGuarantees, sender.NodeID, guarantee)
115-
suite.Require().Error(err)
116-
118+
suite.Require().NoError(err)
117119
suite.conduit.AssertNumberOfCalls(suite.T(), "Multicast", 0)
118120
}

0 commit comments

Comments
 (0)