test: enable opening partial p2p connections where useful #18498

pull jonatack wants to merge 2 commits into bitcoin:master from jonatack:allow-peer-conn-sans-sync changing 10 files +26 −22
  1. jonatack commented at 2:47 PM on April 1, 2020: member

    As a follow-up to PR #18247, which added sync_with_ping by default in add_p2p_connection(), this PR allows optionally passing an argument to add_p2p_connection to avoid running sync_with_ping for partial connections.

    The second commit passes that argument in cases where add_p2p_connection is followed closely by a call to sync_with_ping or send_with_ping, or where the test integrity appears better served with the previous behavior of opening a partial connection.

    As this PR maintains previous behavior WRT a few tests, there should be no downside here.

  2. laanwj added the label Tests on Apr 1, 2020
  3. in test/functional/test_framework/test_node.py:507 in db53a10bd6 outdated
     479 | @@ -480,7 +480,9 @@ def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, **kwargs):
     480 |              #
     481 |              # So syncing here is redundant when we only want to send a message, but the cost is low (a few milliseconds)
     482 |              # in comparision to the upside of making tests less fragile and unexpected intermittent errors less likely.
     483 | -            p2p_conn.sync_with_ping()
     484 | +            # Connections may opt out by passing `sync_with_ping=False`.
     485 | +            if sync_with_ping:
     486 | +                p2p_conn.sync_with_ping()
    


    vasild commented at 3:23 PM on April 1, 2020:

    Wouldn't it be confusing to have add_p2p_connection(..., wait_for_verack=False, sync_with_ping=True) not execute sync_with_ping()?


    jonatack commented at 2:14 PM on April 2, 2020:

    Thanks for reviewing! I see your point, but I don't see when we would want a connection like that and AFAIK the test suite doesn't currently have a use for it.


    robot-visions commented at 5:48 PM on April 23, 2020:

    Nit: As a follow-up to @vasild 's comment, would it make sense to consider one of the following, to prevent possible confusion in the future:

    • Raise an assertion error if wait_for_verack=False, sync_with_ping=True
    • Instead of passing two boolean parameters, pass a single parameter like sync_behavior which can take in three values NONE, VERACK_ONLY, VERACK_AND_PING?
  4. jonatack force-pushed on Apr 1, 2020
  5. DrahtBot commented at 5:10 PM on April 1, 2020: member

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #18726 (test: check misbehavior more independently in p2p_filter.py by robot-visions)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  6. jonatack force-pushed on Apr 2, 2020
  7. DrahtBot added the label Needs rebase on Apr 2, 2020
  8. jonatack force-pushed on Apr 2, 2020
  9. in test/functional/test_framework/test_node.py:484 in 95aebf321c outdated
     479 | @@ -480,7 +480,10 @@ def add_p2p_connection(self, p2p_conn, *, wait_for_verack=True, **kwargs):
     480 |              #
     481 |              # So syncing here is redundant when we only want to send a message, but the cost is low (a few milliseconds)
     482 |              # in comparision to the upside of making tests less fragile and unexpected intermittent errors less likely.
     483 | -            p2p_conn.sync_with_ping()
     484 | +            #
     485 | +            # Connections may opt out by passing `sync_with_ping=False`.
    


    MarcoFalke commented at 10:37 PM on April 2, 2020:

    Instead of explaining how to opt out, it would help to explain why someone would want to opt out. Is this a performance improvement? I yes, then it should be quantified.

    Otherwise it seem like added code-complexity that makes tests more fragile and harder to read, write and maintain.


    jonatack commented at 1:39 PM on April 3, 2020:

    Good idea. Pushed a new version.

  10. DrahtBot removed the label Needs rebase on Apr 2, 2020
  11. jonatack force-pushed on Apr 3, 2020
  12. DrahtBot added the label Needs rebase on Apr 15, 2020
  13. test: allow p2p connections without sync_with_ping
    for cases where the add_p2p_connection is already followed with a call to
    sync_with_ping or send_with_ping, or where the test integrity appears better
    served by not performing the sync_with_ping, which was added as a default in
    fa906470.
    9de86e4f00
  14. test: avoid redundant sync with ping in p2p connections
    in cases where the add_p2p_connection is already followed with a call to
    sync_with_ping or send_with_ping, or where the test integrity appears better
    served by not performing the sync_with_ping, which was added as a default in
    fa906470.
    522bdf647e
  15. jonatack force-pushed on Apr 21, 2020
  16. jonatack commented at 1:41 PM on April 21, 2020: member

    Rebased.

  17. DrahtBot removed the label Needs rebase on Apr 21, 2020
  18. robot-visions commented at 5:53 PM on April 23, 2020: contributor

    Thanks for updating this! One question before I finish reviewing: am I correct in understanding that you looked through every use of add_p2p_connection and individually decided whether the special sync_with_ping=False behavior is needed?

  19. MarcoFalke commented at 6:32 PM on April 23, 2020: member

    Slightly tend to NACK. This is making the tests harder to read (a reader will ask themselves why some calls have the ping disabled explicitly and the call in the very next line does not have it disabled). Also, it is making the tests harder to write or change, because forgetting to update one of the disabled pings to be enabled, when needed, can easily be forgotten. There is no infrastructure in place to catch such mistakes (other than review).

    I think we should make tests easy to read and easy to write, not the opposite.

  20. jonatack commented at 11:31 AM on April 24, 2020: member

    Thanks for the feeback. Below I'll try to summarize the different aspects as I (correctly or not) see them.

    Full connections by default instead of partial connections

    add_p2p_connection was added in March 2017 with 5e5725cc2b5, which means that for the past 3 years the functional test suite using this method was running without forcing full p2p connections (which were made by calling sync_with_ping). If I understand correctly, the motivation for fa9064704524a0fd1fa9ea73e was to hopefully reduce spurious test failures in the CI. Nevertheless, ISTM we would ideally prefer to avoid sync_with_ping everywhere by default and could verify regularly if it can be reverted without increasing the number of false test negatives.

    Allowing the previous default of partial connections

    It seems we still need a way for tests to make partial connections. One reason is speed/performance: Waste not; gains may appear minor, but the functional suite will continue growing and its run time continue to increase, long-term discouraging people from running it and increasing our dependance on centralized third parties. A more immediately interesting reason is, are there tests that might now be false positives, because their partial connection was changed to a full one to reduce false negatives?

    Downside of allowing partial connections

    For 3 years, connections were partial by default and required an additional sync_with_ping to become full. Now, connections are full by default and would only require an additional argument be partial. The complexity is roughly equivalent with only the default state changed, but inevitably we need to be able to test various kinds of connections.

    In the worst case, a test that was using a partial connection might be modified to not longer need it without the author and reviewers noticing (if the changed test required a full connection, it would fail and be noticed/updated). In that worse case, the connection would function the way the functional test suite did for the previous 3 years. Only if the new test fails would it become an issue needing to be addressed (and the fix is trivial).

    Implementation of connection types

    I like @robot-visions' suggestion combining the states into one argument. Yes, I looked for cases where a partial connection is a better test or more practical e.g. followed by a sync already. There are likely more of them.

  21. jonatack commented at 11:38 AM on April 24, 2020: member

    Question: what changed since March 2017? An increasing number of spurious (maddening, to be sure) CI failures?

  22. MarcoFalke commented at 11:44 AM on April 24, 2020: member

    Yes, we have a lot of spurious ci failures. No one reports them as bugs or even tries to fix them (except me). Everyone blindly hits the restart button on travis and it is up to me to beat them and save the logs locally. We have bugs reported by travis that crash the whole node, when a miner submits a block: #18742

    I don't think making a handful of tests faster by a few microseconds is going to help in any notiecable way. And with the risk of making the test suite more fragile and missing actual failures, I don't think the unspecified gain [1] is worth the risk.

    [1] Performance improvements need benchmarks to be useful

  23. MarcoFalke commented at 11:50 AM on April 24, 2020: member

    Btw, calling it "partial connection" implies that this is a different kind of connection or something that the caller can exploit for a test in some way. This is not true. The verack is already in flight and it can't be erased from the wire or changed in any way. If the caller wanted to exploit that intermittent state for a test, the result would be racy. Races are the number one reason that our tests fail.

    If a test needs the verack to be not send (and requires a "partial connection" or whatever the right term for that is), it can use CNodeNoVerackIdle.

  24. jonatack commented at 11:55 AM on April 24, 2020: member

    Thanks for the feedback. I empathize with the burden of the CI failures you're dealing with and the need for robust tests and benchmarks. Robust > speed. Will think about this more.

  25. jonatack closed this on Apr 24, 2020

  26. DrahtBot locked this on Feb 15, 2022

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-14 21:14 UTC

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