@@ -146,7 +146,6 @@ def fetch_hashchain(self):
146
146
147
147
if skeleton_fetch and not skeleton :
148
148
remaining = self .fetch_headers (self .skeleton_peer ,from0 )
149
-
150
149
skeleton_fetch = False
151
150
if not remaining :
152
151
log_st .warn ('no more skeleton received' )
@@ -155,20 +154,18 @@ def fetch_hashchain(self):
155
154
#should not continuew??
156
155
157
156
if skeleton_fetch :
158
-
159
157
self .fetch_headerbatch (from0 ,skeleton )
160
- log_st .debug ('header batch' , headerbatch = self .batch_result )
158
+ # log_st.debug('header batch', headerbatch= self.batch_result)
161
159
# check result
162
160
if self .header_processed > 0 :
163
- # self.fetch_blocks(header_batch)
164
- #from0 = from0 + self.max_skeleton_size*self.max_blockheaders_per_request
165
161
from0 += self .header_processed
162
+ remaining = self .batch_result [self .header_processed :]
166
163
else :
167
164
return self .exit (success = False )
168
-
165
+ #scheduling block download for unprocessed headers in the skeleton or last header batch
169
166
if remaining :
170
- log_st .debug ('fetching new skeletons' )
171
- # self.fetch_blocks (remaining)
167
+ log_st .debug ('scheduling new headers' , count = len ( remaining ), start = from0 )
168
+ self .synchronizer . blockheader_queue . put (remaining )
172
169
from0 += len (remaining )
173
170
174
171
@@ -233,7 +230,7 @@ def fetch_headerbatch(self,origin,skeleton):
233
230
self .pending_headerRequests [proto ] = HeaderRequest (start )
234
231
proto .idle = False
235
232
fetching = True
236
- log_st .debug ('sent header request' ,request = start , proto = proto )
233
+ log_st .debug ('sent header request' ,request = start , proto = proto )
237
234
else :
238
235
task_empty = True
239
236
break
@@ -331,15 +328,19 @@ def verify_headers(self,proto,headers):
331
328
332
329
def fetch_headers (self ,proto , fromx ):
333
330
deferred = AsyncResult ()
334
- blockheaders_batch = []
335
- proto .send_getblockheaders (fromx ,self .max_blockheaders_per_request )
331
+ blockheaders_batch = None
332
+ proto .send_getblockheaders (fromx ,self .max_blockheaders_per_request , 0 , 1 )
336
333
try :
334
+ self .requests [proto ] = deferred
337
335
blockheaders_batch = deferred .get (block = True ,timeout = self .blockheaders_request_timeout )
338
336
except gevent .Timeout :
339
337
log_st .warn ('syncing batch hashchain timed out' )
340
- return []
338
+ proto .stop ()
339
+ return self .exit (success = False )
341
340
finally :
342
- return blockheaders_batch
341
+ del self .requests [proto ]
342
+
343
+ return blockheaders_batch
343
344
344
345
345
346
def receive_blockheaders (self , proto , blockheaders ):
@@ -405,7 +406,7 @@ def run(self):
405
406
def schedule_block_fetch (self ):
406
407
batch_header = []
407
408
log_st .debug ('start sheduleing blocks' )
408
- self .synchronizer .blockheader_queue = Queue ()
409
+ self .synchronizer .blockheader_queue = Queue (maxsize = 8192 )
409
410
410
411
while True :
411
412
batch_header = self .synchronizer .blockheader_queue .get ()
@@ -436,32 +437,18 @@ def fetch_blocks(self):
436
437
num_blocks = 0
437
438
num_fetched = 0
438
439
retry = 0
439
- last_block = None
440
- # batch_header = []
441
- #while not self.blockheaders_queue.empty():
442
- # self.synchronizer.blockheader_queue = Queue()
443
- # while True:
444
- # batch_header= self.synchronizer.blockheader_queue.get()
445
- # num_blocks = len(batch_header)
446
- # log_body_st.debug('delivered headers', delivered_heades=batch_header)
447
- # gevent.sleep(0)
448
- # while batch_header:
449
- # limit = len(batch_header) if len(batch_header) < self.max_blocks_process else self.max_blocks_process
450
- # blockbody_batch = batch_header[:limit]
451
- # for header in blockbody_batch:
452
- #check chain order
453
- #self.block_requests_pool[header.hash]= header
454
- # self.block_requests_pool.append(header)
455
- # self.bodytask_queue.put((header.number,header))
456
- #check if length block_requests_pool is equal to blockhashes_batch
457
- # batch_header = batch_header[limit:]
458
-
440
+ last_block = None
441
+ throttled = False
459
442
while True :
460
443
try :
461
444
result = self .fetch_ready .get ()
462
445
log_st .debug ('start fetching blocks' )
446
+ if throttled :
447
+ gevent .sleep (0.1 )
448
+ num_blocks = len (self .block_requests_pool )
463
449
deferred = AsyncResult ()
464
450
self .body_request = deferred
451
+ # throttled = False
465
452
466
453
#check timed out pending requests
467
454
for proto in list (self .pending_bodyRequests ):
@@ -477,8 +464,6 @@ def fetch_blocks(self):
477
464
# proto.body_idle = True
478
465
proto .stop ()
479
466
480
- # log_st.debug('header task queue size, pending queue size, batch_requestsize',size=self.bodytask_queue.qsize(),pending=len(self.pending_blockRequests),batch_request=len(self.block_requests_pool))
481
- #if self.headertask_queue.qsize == 0 and len(self.pending_headerRequests)==0 and len(self.batch_requests)==0 :
482
467
if len (self .block_requests_pool ) == 0 :
483
468
log_body_st .debug ('block body fetching completed!' )
484
469
# return True
@@ -491,6 +476,14 @@ def fetch_blocks(self):
491
476
# assert proto not in self.requests
492
477
if proto .is_stopped :
493
478
continue
479
+
480
+ #if self.chainservice.block_queue.qsize()> 1010:
481
+ if pending > 8192 - num_fetched :
482
+ throttled = True
483
+ log_body_st .debug ('throttled' )
484
+ break
485
+ else :
486
+ throttled = False
494
487
proto_deferred = AsyncResult ()
495
488
# check if it's finished
496
489
block_batch = []
@@ -515,10 +508,10 @@ def fetch_blocks(self):
515
508
break
516
509
# check if there are protos available for header fetching
517
510
#if not fetching and not self.headertask_queue.empty() and pending == len(self.pending_headerRequests):
518
- if not fetching and not task_empty :
511
+ if not fetching and not task_empty and not throttled :
519
512
log_body_st .warn ('no protocols available' )
520
513
return self .exit (success = False )
521
- elif task_empty and pending == len (self .pending_bodyRequests ):
514
+ if task_empty or throttled and pending == len (self .pending_bodyRequests ):
522
515
continue
523
516
try :
524
517
proto_received = deferred .get (timeout = self .blocks_request_timeout )['proto' ]
@@ -558,7 +551,7 @@ def fetch_blocks(self):
558
551
# add received t_blocks
559
552
num_fetched += len (bodies )
560
553
log_body_st .debug ('received block bodies' ,
561
- num = len (bodies ),blockbody = bodies , num_fetched = num_fetched ,
554
+ num = len (bodies ),num_fetched = num_fetched ,
562
555
total = num_blocks , missing = num_blocks - num_fetched )
563
556
proto_received .body_idle = True
564
557
del self .requests [proto_received ]
@@ -581,18 +574,6 @@ def fetch_blocks(self):
581
574
except Exception as ex :
582
575
log_body_st .error (error = ex )
583
576
584
-
585
-
586
- # for body in bodies:
587
- # try:
588
- # h = headers.pop(0)
589
- # t_block = TransientBlock(h, body.transactions, body.uncles)
590
- # self.chainservice.add_block(t_block, proto) # this blocks if the queue is full
591
- # self.block_requests_pool.remove(h)
592
- # except IndexError as e:
593
- # log_st.error('headers and bodies mismatch', error=e)
594
- # self.exit(success=False)
595
- # log_st.debug('adding blocks done', took=time.time() - ts)
596
577
597
578
# done
598
579
last_block = t_block
@@ -665,7 +646,7 @@ def __init__(self, chainservice, force_sync=None):
665
646
self ._protocols = dict () # proto: chain_difficulty
666
647
self .synctask = None
667
648
self .syncbody = None
668
- self .blockheader_queue = Queue ()
649
+ self .blockheader_queue = Queue (maxsize = 8192 )
669
650
670
651
def synctask_exited (self , success = False ):
671
652
# note: synctask broadcasts best block
0 commit comments