[tests] Fix sendheaders #11707

pull jnewbery wants to merge 5 commits into bitcoin:master from jnewbery:fix_sendheaders changing 1 files +141 −121
  1. jnewbery commented at 6:55 PM on November 16, 2017: member

    This PR should fix the intermittent failure of sendheaders.py described in #11673. The first three commits are tidying up and refactoring the file. The final commit fix flakiness in sendheaders.py fixes the intermittent failures. The commit message for that commit describes the problems that are being fixed.

    I think @laanwj @MeshCollider @MarcoFalke have seen these failures.

    fixes #11673

  2. [tests] fix flake8 warnings in sendheaders.py 2613c545f5
  3. [tests] tidy up BaseNode in sendheaders.py f39d4bbd1e
  4. [tests] refactor check_last_announcement() in sendheaders.py
    All calls of check_last_announcement() asserted that the return
    value was True. Just assert inside the function instead. This
    gives better debug information if the assert fails.
    
    Also only check the contents of the most recent inv and header if
    check_last_announcement() is called with the relevant argument.
    25fd6e2c20
  5. [tests] fix flakiness in sendheaders.py
    Fixes to sources of intermittent failure in sendheaders.py
    
    - at the start of test_null_locators(), a new block is generated and
    then a getheaders is sent. check_last_accouncement() is called to assert
    that the headers message is received. However, the new block triggers an
    inv to be sent over both P2P connections, so there's a race. If the inv
    is received at the wrong time, the test fails.
    
    - test_null_locators() ends by sending a block to the node under test.
    At the start of test_nonnull_locators(), a block is mined and
    check_last_announcement() is called to assert that the inv received is
    for the same block. That means there's a race: if the inv from the block
    sent in test_null_locators() is received at the wrong time, the test
    fails.
    f0c4ab9a70
  6. fanquake added the label Tests on Nov 16, 2017
  7. meshcollider commented at 8:53 AM on November 17, 2017: contributor
  8. laanwj commented at 4:10 PM on November 17, 2017: member

    utACK f0c4ab9

  9. laanwj requested review from MarcoFalke on Nov 17, 2017
  10. in test/functional/sendheaders.py:146 in f39d4bbd1e outdated
     141 | +        getblocks_message = msg_getblocks()
     142 | +        getblocks_message.locator.vHave = locator
     143 | +        self.send_message(getblocks_message)
     144 | +
     145 | +    def wait_for_getdata(self, hash_list, timeout=60):
     146 | +        if hash_list != []:
    


    MarcoFalke commented at 4:46 PM on November 17, 2017:

    Nit: I generally prefer the "early-return-syntax" (like it was before). This saves some white space when indenting.


    jnewbery commented at 10:15 PM on November 17, 2017:

    sure, reverted

  11. in test/functional/sendheaders.py:213 in f39d4bbd1e outdated
     237 | -    # length+1 blocks).
     238 | -    # Note: we clear the state of our p2p connections after the
     239 | -    # to-be-reorged-out blocks are mined, so that we don't break later tests.
     240 | -    # return the list of block hashes newly mined
     241 |      def mine_reorg(self, length):
     242 | +        """Mine a reorg that invalidates length blocks (replacing them with # length+1 blocks).
    


    MarcoFalke commented at 4:48 PM on November 17, 2017:

    nit: loose hashtag from transforming comment into docstring.

  12. in test/functional/sendheaders.py:10 in f0c4ab9a70 outdated
       3 | @@ -4,7 +4,7 @@
       4 |  # file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5 |  """Test behavior of headers messages to announce blocks.
       6 |  
       7 | -Setup: 
       8 | +Setup:
       9 |  
      10 |  - Two nodes, two p2p connections to node0. One p2p connection should only ever
      11 |    receive inv's (omitted from testing description below, this is our control).
    


    MarcoFalke commented at 7:10 PM on November 17, 2017:

    nit: Not sure what "omitted from testing description below, this is our control" means. Mind to clarify or remove?


    jnewbery commented at 10:15 PM on November 17, 2017:

    I've clarified the language slightly

  13. in test/functional/sendheaders.py:232 in f0c4ab9a70 outdated
     274 |  
     275 |      def run_test(self):
     276 |          # Setup the p2p connections and start up the network thread.
     277 | -        inv_node = self.nodes[0].add_p2p_connection(TestNode())
     278 | +        inv_node = self.nodes[0].add_p2p_connection(BaseNode())
     279 |          # Set nServices to 0 for test_node, so no block download will occur outside of
    


    MarcoFalke commented at 7:12 PM on November 17, 2017:

    nit: Mind to fixup the comment, since segwit is now always active in regtest?


    jnewbery commented at 10:13 PM on November 17, 2017:

    fixed

  14. in test/functional/sendheaders.py:170 in f0c4ab9a70 outdated
     168 | +        with mininode_lock:
     169 | +            self.block_announced = False
     170 | +            self.last_message.pop("inv", None)
     171 | +            self.last_message.pop("headers", None)
     172 | +
     173 |      def check_last_announcement(self, headers=None, inv=None):
    


    MarcoFalke commented at 7:23 PM on November 17, 2017:

    nit: Are the default values required for headers and inv? For the case of inv_node, we must only ever send invs and headers==[]. For the case of test_node, we should send headers and inv==[]s or inv and headers==[]. Though, it is not required for the protocol, so feel free to leave as is.


    jnewbery commented at 10:11 PM on November 17, 2017:

    Right, having the default arguments like this allows looser or stricter testing. If the function is called without both arguments, then the testing is looser. We can make it tighter by explicitly calling with one of the arguments set to an empty list.

    I think it's ok as is, but I'm also happy to change if you have a better suggestion.

  15. in test/functional/sendheaders.py:363 in f0c4ab9a70 outdated
     355 | @@ -339,16 +356,16 @@ def test_nonnull_locators(self, test_node, inv_node):
     356 |                      # getdata requests (the check is further down)
     357 |                      inv_node.send_header_for_blocks(blocks)
     358 |                      inv_node.sync_with_ping()
     359 | -                [ test_node.send_message(msg_block(x)) for x in blocks ]
     360 | +                [test_node.send_message(msg_block(x)) for x in blocks]
     361 |                  test_node.sync_with_ping()
     362 |                  inv_node.sync_with_ping()
     363 |                  # This block should not be announced to the inv node (since it also
     364 |                  # broadcast it)
    


    MarcoFalke commented at 7:25 PM on November 17, 2017:

    nit: test node, not inv node, broadcasts the block.


    jnewbery commented at 10:13 PM on November 17, 2017:

    In this section of the test, both test_node and inv_node announce the new block.

  16. in test/functional/sendheaders.py:272 in f0c4ab9a70 outdated
     265 | @@ -263,7 +266,10 @@ def test_null_locators(self, test_node):
     266 |          test_node.send_get_headers(locator=[], hashstop=int(block.hash, 16))
     267 |          test_node.sync_with_ping()
     268 |          assert_equal(test_node.block_announced, False)
     269 | +        inv_node.clear_last_announcement()
     270 |          test_node.send_message(msg_block(block))
     271 | +        inv_node.check_last_announcement(inv=[int(block.hash, 16)], headers=[])
     272 | +        inv_node.clear_last_announcement()
    


    MarcoFalke commented at 7:32 PM on November 17, 2017:

    nit: is this required? check_last_announcement already includes the code of clear_last_announcement


    jnewbery commented at 10:15 PM on November 17, 2017:

    not required. Now removed

  17. MarcoFalke commented at 7:33 PM on November 17, 2017: member

    utACK f0c4ab9a7034aca6be83fcb6cd8479cd19a196a2 on the fix. Left some style comments, since you touched the file anyway. Feel free to leave.

  18. [tests] address review comments 9d42cc3331
  19. jnewbery commented at 10:17 PM on November 17, 2017: member

    Thanks for the comments @MarcoFalke . I've added a new commit to address them. Let me know if you'd like me to squash commits (it'd be slightly tedious to get the fixups into their appropriate commits, but I'm happy to do it if you want a cleaner git history).

  20. MarcoFalke commented at 10:31 PM on November 18, 2017: member

    re-utACK 9d42cc333139d7101a9223421d9eabcddfd0b025. I think it is best to leave the fixup commit on its own, so that the previous review is not invalidated by changing the commit hashes.

  21. MarcoFalke merged this on Nov 18, 2017
  22. MarcoFalke closed this on Nov 18, 2017

  23. MarcoFalke referenced this in commit 0d89fa0877 on Nov 18, 2017
  24. PastaPastaPasta referenced this in commit 47f2e505bb on Feb 13, 2020
  25. PastaPastaPasta referenced this in commit 80ba10e695 on Feb 27, 2020
  26. PastaPastaPasta referenced this in commit b279687b66 on Mar 14, 2020
  27. PastaPastaPasta referenced this in commit f798771323 on Mar 19, 2020
  28. ckti referenced this in commit be476b430d on Mar 28, 2021
  29. gades referenced this in commit 310a76e230 on Jun 30, 2021
  30. DrahtBot locked this on Sep 8, 2021

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-13 21:15 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me