@@ -29,8 +29,6 @@ devp2p subprotocols by abstracting away code standardly shared by protocols.
29
29
package protocols
30
30
31
31
import (
32
- "bufio"
33
- "bytes"
34
32
"context"
35
33
"fmt"
36
34
"io"
@@ -42,9 +40,7 @@ import (
42
40
"github.com/ethereum/go-ethereum/metrics"
43
41
"github.com/ethereum/go-ethereum/p2p"
44
42
"github.com/ethereum/go-ethereum/rlp"
45
- "github.com/ethersphere/swarm/spancontext"
46
43
"github.com/ethersphere/swarm/tracing"
47
- opentracing "github.com/opentracing/opentracing-go"
48
44
)
49
45
50
46
// error codes used by this protocol scheme
@@ -115,13 +111,6 @@ func errorf(code int, format string, params ...interface{}) *Error {
115
111
}
116
112
}
117
113
118
- // WrappedMsg is used to propagate marshalled context alongside message payloads
119
- type WrappedMsg struct {
120
- Context []byte
121
- Size uint32
122
- Payload []byte
123
- }
124
-
125
114
//For accounting, the design is to allow the Spec to describe which and how its messages are priced
126
115
//To access this functionality, we provide a Hook interface which will call accounting methods
127
116
//NOTE: there could be more such (horizontal) hooks in the future
@@ -157,6 +146,10 @@ type Spec struct {
157
146
initOnce sync.Once
158
147
codes map [reflect.Type ]uint64
159
148
types map [uint64 ]reflect.Type
149
+
150
+ // if the protocol does not allow extending the p2p msg to propagate context
151
+ // even if context not disabled, context will propagate only tracing is enabled
152
+ DisableContext bool
160
153
}
161
154
162
155
func (s * Spec ) init () {
@@ -208,17 +201,27 @@ type Peer struct {
208
201
* p2p.Peer // the p2p.Peer object representing the remote
209
202
rw p2p.MsgReadWriter // p2p.MsgReadWriter to send messages to and read messages from
210
203
spec * Spec
204
+ encode func (context.Context , interface {}) (interface {}, int , error )
205
+ decode func (p2p.Msg ) (context.Context , []byte , error )
211
206
}
212
207
213
208
// NewPeer constructs a new peer
214
209
// this constructor is called by the p2p.Protocol#Run function
215
210
// the first two arguments are the arguments passed to p2p.Protocol.Run function
216
211
// the third argument is the Spec describing the protocol
217
- func NewPeer (p * p2p.Peer , rw p2p.MsgReadWriter , spec * Spec ) * Peer {
212
+ func NewPeer (peer * p2p.Peer , rw p2p.MsgReadWriter , spec * Spec ) * Peer {
213
+ encode := encodeWithContext
214
+ decode := decodeWithContext
215
+ if spec == nil || spec .DisableContext || ! tracing .Enabled {
216
+ encode = encodeWithoutContext
217
+ decode = decodeWithoutContext
218
+ }
218
219
return & Peer {
219
- Peer : p ,
220
- rw : rw ,
221
- spec : spec ,
220
+ Peer : peer ,
221
+ rw : rw ,
222
+ spec : spec ,
223
+ encode : encode ,
224
+ decode : decode ,
222
225
}
223
226
}
224
227
@@ -234,7 +237,6 @@ func (p *Peer) Run(handler func(ctx context.Context, msg interface{}) error) err
234
237
metrics .GetOrRegisterCounter ("peer.handleincoming.error" , nil ).Inc (1 )
235
238
log .Error ("peer.handleIncoming" , "err" , err )
236
239
}
237
-
238
240
return err
239
241
}
240
242
}
@@ -256,51 +258,32 @@ func (p *Peer) Send(ctx context.Context, msg interface{}) error {
256
258
metrics .GetOrRegisterCounter ("peer.send" , nil ).Inc (1 )
257
259
metrics .GetOrRegisterCounter (fmt .Sprintf ("peer.send.%T" , msg ), nil ).Inc (1 )
258
260
259
- var b bytes.Buffer
260
- if tracing .Enabled {
261
- writer := bufio .NewWriter (& b )
262
-
263
- tracer := opentracing .GlobalTracer ()
264
-
265
- sctx := spancontext .FromContext (ctx )
266
-
267
- if sctx != nil {
268
- err := tracer .Inject (
269
- sctx ,
270
- opentracing .Binary ,
271
- writer )
272
- if err != nil {
273
- return err
274
- }
275
- }
276
-
277
- writer .Flush ()
261
+ code , found := p .spec .GetCode (msg )
262
+ if ! found {
263
+ return errorf (ErrInvalidMsgType , "%v" , code )
278
264
}
279
265
280
- r , err := rlp . EncodeToBytes ( msg )
266
+ wmsg , size , err := p . encode ( ctx , msg )
281
267
if err != nil {
282
268
return err
283
269
}
284
270
285
- wmsg := WrappedMsg {
286
- Context : b .Bytes (),
287
- Size : uint32 (len (r )),
288
- Payload : r ,
271
+ // if size is not set by the wrapper, need to serialise
272
+ if size == 0 {
273
+ r , err := rlp .EncodeToBytes (msg )
274
+ if err != nil {
275
+ return err
276
+ }
277
+ size = len (r )
289
278
}
290
-
291
- //if the accounting hook is set, call it
279
+ // if the accounting hook is set, call it
292
280
if p .spec .Hook != nil {
293
- err : = p .spec .Hook .Send (p , wmsg . Size , msg )
281
+ err = p .spec .Hook .Send (p , uint32 ( size ) , msg )
294
282
if err != nil {
295
- p .Drop ()
296
283
return err
297
284
}
298
285
}
299
286
300
- code , found := p .spec .GetCode (msg )
301
- if ! found {
302
- return errorf (ErrInvalidMsgType , "%v" , code )
303
- }
304
287
return p2p .Send (p .rw , code , wmsg )
305
288
}
306
289
@@ -324,44 +307,23 @@ func (p *Peer) handleIncoming(handle func(ctx context.Context, msg interface{})
324
307
return errorf (ErrMsgTooLong , "%v > %v" , msg .Size , p .spec .MaxMsgSize )
325
308
}
326
309
327
- // unmarshal wrapped msg, which might contain context
328
- var wmsg WrappedMsg
329
- err = msg .Decode (& wmsg )
330
- if err != nil {
331
- log .Error (err .Error ())
332
- return err
333
- }
334
-
335
- ctx := context .Background ()
336
-
337
- // if tracing is enabled and the context coming within the request is
338
- // not empty, try to unmarshal it
339
- if tracing .Enabled && len (wmsg .Context ) > 0 {
340
- var sctx opentracing.SpanContext
341
-
342
- tracer := opentracing .GlobalTracer ()
343
- sctx , err = tracer .Extract (
344
- opentracing .Binary ,
345
- bytes .NewReader (wmsg .Context ))
346
- if err != nil {
347
- log .Error (err .Error ())
348
- return err
349
- }
350
-
351
- ctx = spancontext .WithContext (ctx , sctx )
352
- }
353
-
354
310
val , ok := p .spec .NewMsg (msg .Code )
355
311
if ! ok {
356
312
return errorf (ErrInvalidMsgCode , "%v" , msg .Code )
357
313
}
358
- if err := rlp .DecodeBytes (wmsg .Payload , val ); err != nil {
314
+
315
+ ctx , msgBytes , err := p .decode (msg )
316
+ if err != nil {
317
+ return errorf (ErrDecode , "%v err=%v" , msg .Code , err )
318
+ }
319
+
320
+ if err := rlp .DecodeBytes (msgBytes , val ); err != nil {
359
321
return errorf (ErrDecode , "<= %v: %v" , msg , err )
360
322
}
361
323
362
- //if the accounting hook is set, call it
324
+ // if the accounting hook is set, call it
363
325
if p .spec .Hook != nil {
364
- err := p .spec .Hook .Receive (p , wmsg . Size , val )
326
+ err := p .spec .Hook .Receive (p , uint32 ( len ( msgBytes )) , val )
365
327
if err != nil {
366
328
return err
367
329
}
0 commit comments