66 "errors"
77 "fmt"
88 "math/rand"
9+ "sync"
910 "time"
1011
1112 "github.com/0xProject/0x-mesh/p2p"
@@ -23,7 +24,7 @@ const (
2324 TypeResponse = "Response"
2425)
2526
26- const requestResponseTimeout = 15 * time .Second
27+ const requestResponseTimeout = 30 * time .Second
2728
2829var (
2930 // retryBackoff defines how long to wait before trying again if we didn't get
3334 Max : 1 * time .Minute , // Longest back-off length
3435 Factor : 2 , // Factor to multiple each successive back-off
3536 }
37+ backoffMut = & sync.Mutex {}
3638)
3739
3840var (
@@ -105,8 +107,8 @@ func (s *Service) SupportedSubprotocols() []string {
105107
106108type Subprotocol interface {
107109 Name () string
108- GetOrders (* Request ) (* Response , error )
109- HandleOrders (* Response ) (* Request , error )
110+ GetOrders (context. Context , * Request ) (* Response , error )
111+ HandleOrders (context. Context , * Response ) (* Request , error )
110112 ParseRequestMetadata (metadata json.RawMessage ) (interface {}, error )
111113 ParseResponseMetadata (metadata json.RawMessage ) (interface {}, error )
112114}
@@ -141,6 +143,9 @@ func (s *Service) GetMatchingSubprotocol(rawReq *rawRequest) (Subprotocol, error
141143}
142144
143145func (s * Service ) HandleStream (stream network.Stream ) {
146+ log .WithFields (log.Fields {
147+ "requester" : stream .Conn ().RemotePeer ().Pretty (),
148+ }).Trace ("handling ordersync stream" )
144149 defer func () {
145150 _ = stream .Close ()
146151 }()
@@ -151,6 +156,9 @@ func (s *Service) HandleStream(stream network.Stream) {
151156 log .WithError (err ).Warn ("waitForRequest returned error" )
152157 return
153158 }
159+ log .WithFields (log.Fields {
160+ "requester" : stream .Conn ().RemotePeer ().Pretty (),
161+ }).Trace ("received ordersync request" )
154162 if rawReq .Type != TypeRequest {
155163 log .WithField ("gotType" , rawReq .Type ).Warn ("wrong type for Request" )
156164 return
@@ -160,7 +168,7 @@ func (s *Service) HandleStream(stream network.Stream) {
160168 log .WithError (err ).Warn ("GetMatchingSubprotocol returned error" )
161169 return
162170 }
163- res , err := handleRequestWithSubprotocol (subprotocol , rawReq )
171+ res , err := handleRequestWithSubprotocol (s . ctx , subprotocol , rawReq )
164172 if err != nil {
165173 log .WithError (err ).Warn ("subprotocol returned error" )
166174 return
@@ -182,6 +190,7 @@ func (s *Service) HandleStream(stream network.Stream) {
182190 "error" : err .Error (),
183191 "requester" : remotePeerID .Pretty (),
184192 }).Warn ("could not encode ordersync response" )
193+ return
185194 }
186195 if res .Complete {
187196 return
@@ -200,7 +209,6 @@ func (s *Service) GetOrders(ctx context.Context, minPeers int) error {
200209 }
201210
202211 // TODO(albrow): Do this for loop partly in parallel.
203- // TODO(albrow): Add a timeout when waiting for a response.
204212 currentNeighbors := s .node .Neighbors ()
205213 shufflePeers (currentNeighbors )
206214 for _ , peerID := range currentNeighbors {
@@ -233,24 +241,31 @@ func (s *Service) GetOrders(ctx context.Context, minPeers int) error {
233241 }
234242 }
235243
244+ backoffMut .Lock ()
236245 delayBeforeNextRetry := retryBackoff .Duration ()
246+ backoffMut .Unlock ()
237247 log .WithFields (log.Fields {
238248 "delayBeforeNextRetry" : delayBeforeNextRetry .String (),
239249 "minPeers" : minPeers ,
240250 "successfullySyncedPeers" : len (successfullySyncedPeers ),
241251 }).Debug ("ordersync could not get orders from enough peers (trying again soon)" )
242- time .Sleep (delayBeforeNextRetry )
252+ select {
253+ case <- ctx .Done ():
254+ return ctx .Err ()
255+ case <- time .After (delayBeforeNextRetry ):
256+ continue
257+ }
243258 }
244259
245260 return nil
246261}
247262
248- func handleRequestWithSubprotocol (subprotocol Subprotocol , rawReq * rawRequest ) (* Response , error ) {
263+ func handleRequestWithSubprotocol (ctx context. Context , subprotocol Subprotocol , rawReq * rawRequest ) (* Response , error ) {
249264 req , err := parseRequestWithSubprotocol (subprotocol , rawReq )
250265 if err != nil {
251266 return nil , err
252267 }
253- return subprotocol .GetOrders (req )
268+ return subprotocol .GetOrders (ctx , req )
254269}
255270
256271func parseRequestWithSubprotocol (subprotocol Subprotocol , rawReq * rawRequest ) (* Request , error ) {
@@ -316,10 +331,12 @@ func (s *Service) getOrdersFromPeer(ctx context.Context, providerID peer.ID) err
316331 if err := json .NewEncoder (stream ).Encode (rawReq ); err != nil {
317332 return err
318333 }
334+
319335 rawRes , err := waitForResponse (ctx , stream )
320336 if err != nil {
321337 return err
322338 }
339+
323340 subprotocol , found := s .subprotocols [rawRes .Subprotocol ]
324341 if ! found {
325342 return fmt .Errorf ("unsupported subprotocol: %s" , subprotocol )
@@ -329,7 +346,8 @@ func (s *Service) getOrdersFromPeer(ctx context.Context, providerID peer.ID) err
329346 if err != nil {
330347 return err
331348 }
332- nextReq , err = subprotocol .HandleOrders (res )
349+
350+ nextReq , err = subprotocol .HandleOrders (ctx , res )
333351 if err != nil {
334352 return err
335353 }
@@ -356,10 +374,10 @@ func waitForRequest(parentCtx context.Context, stream network.Stream) (*rawReque
356374 "error" : err .Error (),
357375 "requester" : stream .Conn ().RemotePeer ().Pretty (),
358376 }).Warn ("could not encode ordersync request" )
359- reqChan <- & rawReq
360377 // TODO(albrow): Handle peer scores somewhere else?
361378 // s.host.ConnManager().UpsertTag(remotePeerID, scoreTag, func(current int) int { return current + inavlidMessageScoreDiff })
362379 }
380+ reqChan <- & rawReq
363381 }()
364382
365383 select {
@@ -385,10 +403,10 @@ func waitForResponse(parentCtx context.Context, stream network.Stream) (*rawResp
385403 "error" : err .Error (),
386404 "provider" : stream .Conn ().RemotePeer ().Pretty (),
387405 }).Warn ("could not encode ordersync response" )
388- resChan <- & rawRes
389406 // TODO(albrow): Handle peer scores somewhere else?
390407 // s.host.ConnManager().UpsertTag(remotePeerID, scoreTag, func(current int) int { return current + inavlidMessageScoreDiff })
391408 }
409+ resChan <- & rawRes
392410 }()
393411
394412 select {
0 commit comments