From fd6bb700b77491689f0b5f34bdfb75764138f406 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Fri, 11 Nov 2016 15:38:59 -0500 Subject: [PATCH 1/3] [qa] Improve sync_blocks error messages. --- qa/rpc-tests/test_framework/util.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index b5ef0689b4..2de4d5e303 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -132,10 +132,12 @@ def sync_blocks(rpc_connections, *, wait=1, timeout=60): if tips == [tips[0]] * len(tips): return if heights == [heights[0]] * len(heights): - raise AssertionError("Block sync failed: (Hashes don't match)") + raise AssertionError("Block sync failed, mismatched block hashes:{}".format( + "".join("\n {!r}".format(tip) for tip in tips))) timeout -= wait maxheight = max(heights) - raise AssertionError("Block sync failed with heights: {}".format(heights)) + raise AssertionError("Block sync to height {} timed out:{}".format( + maxheight, "".join("\n {!r}".format(tip) for tip in tips))) def sync_chain(rpc_connections, *, wait=1, timeout=60): """ From 05e57ccd746b2e14699d2b1980927f30070cb3ad Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Fri, 11 Nov 2016 15:40:48 -0500 Subject: [PATCH 2/3] [qa] Fix sync_blocks timeout argument Motivation for this change is mainly to make sync_blocks behavior easier to understand. Behavior is unchanged in the normal case when there are only 2 nodes in the rpc_connections set. When there are more than 2 nodes, the previous "timeout -= wait" statement wouldn't take into account time spent waiting for all nodes and as a result could lead to blocking for longer than the requested timeout. --- qa/rpc-tests/test_framework/util.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 2de4d5e303..01bde0c84d 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -123,10 +123,15 @@ def str_to_b64str(string): def sync_blocks(rpc_connections, *, wait=1, timeout=60): """ - Wait until everybody has the same tip + Wait until everybody has the same tip. + + sync_blocks needs to be called with an rpc_connections set that has least + one node already synced to the latest, stable tip, otherwise there's a + chance it might return before all nodes are stably synced. """ maxheight = 0 - while timeout > 0: + start_time = cur_time = time.time() + while cur_time <= start_time + timeout: tips = [r.waitforblockheight(maxheight, int(wait * 1000)) for r in rpc_connections] heights = [t["height"] for t in tips] if tips == [tips[0]] * len(tips): @@ -134,8 +139,8 @@ def sync_blocks(rpc_connections, *, wait=1, timeout=60): if heights == [heights[0]] * len(heights): raise AssertionError("Block sync failed, mismatched block hashes:{}".format( "".join("\n {!r}".format(tip) for tip in tips))) - timeout -= wait maxheight = max(heights) + cur_time = time.time() raise AssertionError("Block sync to height {} timed out:{}".format( maxheight, "".join("\n {!r}".format(tip) for tip in tips))) From 7943b13ab3e005e1dd5c277efdbc06088d89f6de Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Fri, 11 Nov 2016 15:43:15 -0500 Subject: [PATCH 3/3] [qa] Avoid 2 list comprehensions in sync_blocks --- qa/rpc-tests/test_framework/util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 01bde0c84d..bf13b7fd84 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -134,9 +134,9 @@ def sync_blocks(rpc_connections, *, wait=1, timeout=60): while cur_time <= start_time + timeout: tips = [r.waitforblockheight(maxheight, int(wait * 1000)) for r in rpc_connections] heights = [t["height"] for t in tips] - if tips == [tips[0]] * len(tips): + if all(t == tips[0] for t in tips): return - if heights == [heights[0]] * len(heights): + if all(h == heights[0] for h in heights): raise AssertionError("Block sync failed, mismatched block hashes:{}".format( "".join("\n {!r}".format(tip) for tip in tips))) maxheight = max(heights)