|
31 | 31 | disconnect_nodes, |
32 | 32 | get_datadir_path, |
33 | 33 | initialize_datadir, |
34 | | - sync_blocks, |
35 | | - sync_mempools, |
36 | 34 | ) |
37 | 35 |
|
38 | 36 |
|
@@ -541,15 +539,54 @@ def join_network(self): |
541 | 539 | connect_nodes(self.nodes[1], 2) |
542 | 540 | self.sync_all() |
543 | 541 |
|
544 | | - def sync_blocks(self, nodes=None, **kwargs): |
545 | | - sync_blocks(nodes or self.nodes, **kwargs) |
546 | | - |
547 | | - def sync_mempools(self, nodes=None, **kwargs): |
548 | | - sync_mempools(nodes or self.nodes, **kwargs) |
549 | | - |
550 | | - def sync_all(self, nodes=None, **kwargs): |
551 | | - self.sync_blocks(nodes, **kwargs) |
552 | | - self.sync_mempools(nodes, **kwargs) |
| 542 | + def sync_blocks(self, nodes=None, wait=1, timeout=60): |
| 543 | + """ |
| 544 | + Wait until everybody has the same tip. |
| 545 | + sync_blocks needs to be called with an rpc_connections set that has least |
| 546 | + one node already synced to the latest, stable tip, otherwise there's a |
| 547 | + chance it might return before all nodes are stably synced. |
| 548 | + """ |
| 549 | + rpc_connections = nodes or self.nodes |
| 550 | + timeout = int(timeout * self.options.timeout_factor) |
| 551 | + stop_time = time.time() + timeout |
| 552 | + while time.time() <= stop_time: |
| 553 | + best_hash = [x.getbestblockhash() for x in rpc_connections] |
| 554 | + if best_hash.count(best_hash[0]) == len(rpc_connections): |
| 555 | + return |
| 556 | + # Check that each peer has at least one connection |
| 557 | + assert (all([len(x.getpeerinfo()) for x in rpc_connections])) |
| 558 | + time.sleep(wait) |
| 559 | + raise AssertionError("Block sync timed out after {}s:{}".format( |
| 560 | + timeout, |
| 561 | + "".join("\n {!r}".format(b) for b in best_hash), |
| 562 | + )) |
| 563 | + |
| 564 | + def sync_mempools(self, nodes=None, wait=1, timeout=60, flush_scheduler=True): |
| 565 | + """ |
| 566 | + Wait until everybody has the same transactions in their memory |
| 567 | + pools |
| 568 | + """ |
| 569 | + rpc_connections = nodes or self.nodes |
| 570 | + timeout = int(timeout * self.options.timeout_factor) |
| 571 | + stop_time = time.time() + timeout |
| 572 | + while time.time() <= stop_time: |
| 573 | + pool = [set(r.getrawmempool()) for r in rpc_connections] |
| 574 | + if pool.count(pool[0]) == len(rpc_connections): |
| 575 | + if flush_scheduler: |
| 576 | + for r in rpc_connections: |
| 577 | + r.syncwithvalidationinterfacequeue() |
| 578 | + return |
| 579 | + # Check that each peer has at least one connection |
| 580 | + assert (all([len(x.getpeerinfo()) for x in rpc_connections])) |
| 581 | + time.sleep(wait) |
| 582 | + raise AssertionError("Mempool sync timed out after {}s:{}".format( |
| 583 | + timeout, |
| 584 | + "".join("\n {!r}".format(m) for m in pool), |
| 585 | + )) |
| 586 | + |
| 587 | + def sync_all(self, nodes=None): |
| 588 | + self.sync_blocks(nodes) |
| 589 | + self.sync_mempools(nodes) |
553 | 590 |
|
554 | 591 | # Private helper methods. These should not be accessed by the subclass test scripts. |
555 | 592 |
|
|
0 commit comments