Fuzz: extend CConnman tests #28584

pull vasild wants to merge 5 commits into bitcoin:master from vasild:fuzz_connman changing 14 files +251 −65
  1. vasild commented at 11:27 am on October 4, 2023: contributor

    Extend CConnman fuzz tests to also exercise the methods OpenNetworkConnection(), CreateNodeFromAcceptedSocket(), InitBinds() and SocketHandler().

    Previously fuzzing those methods would have resulted in real socket functions being called in the operating system which is undesirable during fuzzing. Now that #21878 is complete all those are mocked to a fuzzed socket and a fuzzed DNS resolver (see how CreateSock and g_dns_lookup are replaced in the first commit).

  2. DrahtBot commented at 11:27 am on October 4, 2023: contributor

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

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/28584.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK jonatack
    Concept ACK dergoegge
    Stale ACK brunoerg

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #30988 (Split CConnman by vasild)
    • #30882 (wip: Split fuzz binary (take 2) by dergoegge)
    • #30381 ([WIP] net: return result from addnode RPC by willcl-ark)
    • #29641 (scripted-diff: Use LogInfo over LogPrintf [WIP, NOMERGE, DRAFT] by maflcko)
    • #29415 (Broadcast own transactions only via short-lived Tor or I2P connections by vasild)

    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.

  3. DrahtBot added the label Tests on Oct 4, 2023
  4. dergoegge commented at 11:48 am on October 4, 2023: member
    Concept ACK
  5. dergoegge commented at 2:07 pm on October 4, 2023: member

    The cpu utilization of this target doesn’t look great, i suspect this is due to timeouts/sleeps e.g.: https://github.com/bitcoin/bitcoin/blob/db7b5dfcc502a8a81c51f56fe753990ae8b3a202/src/net.cpp#L2099

    Would be nice to address that (maybe in a follow up).

    Here is a preliminary coverage report: https://dergoegge.github.io/bitcoin-coverage/pr28584/fuzz.coverage/index.html (I’ll update this after fuzzing for longer). Looks good to me as the target alone now has more coverage (by line count) in net.cpp than our coverage on master with all targets.

  6. DrahtBot added the label CI failed on Oct 4, 2023
  7. brunoerg commented at 10:24 pm on October 4, 2023: contributor
    Concept ACK
  8. DrahtBot removed the label CI failed on Oct 5, 2023
  9. vasild commented at 10:33 am on October 5, 2023: contributor

    @dergoegge, thanks for looking into this!

    The cpu utilization of this target doesn’t look great

    How did you measure? I guess it should be possible to mock CConnman::interruptNet so that its sleep_for() method returns immediately.

  10. dergoegge commented at 10:48 am on October 5, 2023: member

    How did you measure?

    Eyeballing htop this target only achieves about 10% - 30% per core on my machine.

    I guess it should be possible to mock CConnman::interruptNet so that its sleep_for() method returns immediately.

    Sounds good to me.

  11. vasild commented at 11:50 am on October 5, 2023: contributor
    When I run FUZZ=connman ./src/test/fuzz/fuzz it is single CPU/single threaded and it stays at 98%-100% CPU all the time. It is the same in master. Does it get executed on >1 cores for you?
  12. dergoegge commented at 10:34 am on October 6, 2023: member

    When I run FUZZ=connman ./src/test/fuzz/fuzz it is single CPU/single threaded and it stays at 98%-100% CPU all the time.

    For how long did you run this? The fuzzer needs to first find inputs that trigger sleep_for for you to be able to observe the problem. I have tested this on two machines now and the result is always the same.

    Does it get executed on >1 cores for you?

    You can let libfuzzer run on multiple cores with either -jobs=<num cpus> or -fork=<num cpus>. I prefer fork since it also includes a minimization step.

  13. vasild commented at 9:40 am on October 11, 2023: contributor

    I guess it should be possible to mock CConnman::interruptNet so that its sleep_for() method returns immediately.

    Another use-case for that mock: #28635:

    If the test suite could mock the delay in ThreadOpenAddedConnections

  14. DrahtBot added the label Needs rebase on Jan 9, 2024
  15. vasild force-pushed on Jan 17, 2024
  16. DrahtBot removed the label Needs rebase on Jan 17, 2024
  17. vasild commented at 8:40 am on January 18, 2024: contributor
    20a9fc83bd...cd5bbb12e0: rebase due to conflicts
  18. in src/test/fuzz/connman.cpp:165 in b1b74a13ad outdated
    159@@ -160,6 +160,15 @@ FUZZ_TARGET(connman, .init = initialize_connman)
    160                     /*strDest=*/fuzzed_data_provider.ConsumeBool() ? nullptr : random_string.c_str(),
    161                     /*conn_type=*/conn_type,
    162                     /*use_v2transport=*/fuzzed_data_provider.ConsumeBool());
    163+            },
    164+            [&] {
    165+                connman.SetNetworkActive(true);
    


    brunoerg commented at 1:01 pm on February 2, 2024:
    In b1b74a13adb8e943d90fbe56c4a706b0ae91335a: nit: I don’t think to set network active here is a must, we could fuzz it with both network active and inactive.

    vasild commented at 1:38 pm on February 4, 2024:
    Right, done!
  19. in src/test/fuzz/util/net.h:105 in d923b86264 outdated
    100+{
    101+    std::vector<CService> ret;
    102+    const size_t size = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, max_vector_size);
    103+    ret.reserve(size);
    104+    for (size_t i = 0; i < size; ++i) {
    105+        ret.emplace_back(ConsumeNetAddr(fuzzed_data_provider),
    


    brunoerg commented at 1:19 pm on February 2, 2024:

    In d923b86264df93ad86c7bd557b9970e156585dc7: You could use ConsumeService into ConsumeServiceVector.

     0diff --git a/src/test/fuzz/util/net.h b/src/test/fuzz/util/net.h
     1index a97017555d..78e61b51d9 100644
     2--- a/src/test/fuzz/util/net.h
     3+++ b/src/test/fuzz/util/net.h
     4@@ -102,8 +102,7 @@ inline std::vector<CService> ConsumeServiceVector(FuzzedDataProvider& fuzzed_dat
     5     const size_t size = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, max_vector_size);
     6     ret.reserve(size);
     7     for (size_t i = 0; i < size; ++i) {
     8-        ret.emplace_back(ConsumeNetAddr(fuzzed_data_provider),
     9-                         fuzzed_data_provider.ConsumeIntegral<uint16_t>());
    10+        ret.emplace_back(ConsumeService(fuzzed_data_provider));
    11     }
    12     return ret;
    13 }
    

    vasild commented at 1:38 pm on February 4, 2024:
    Done, thanks!
  20. vasild force-pushed on Feb 4, 2024
  21. vasild commented at 1:38 pm on February 4, 2024: contributor
    cd5bbb12e0...5e3c80da14: address suggestions
  22. brunoerg approved
  23. brunoerg commented at 5:03 pm on February 5, 2024: contributor
    utACK 5e3c80da1473f90406b84c1ba14dc563ce4d2853
  24. DrahtBot requested review from dergoegge on Feb 5, 2024
  25. DrahtBot added the label CI failed on Mar 13, 2024
  26. DrahtBot commented at 11:59 pm on March 13, 2024: contributor

    🚧 At least one of the CI tasks failed. Make sure to run all tests locally, according to the documentation.

    Possibly this is due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    Leave a comment here, if you need help tracking down a confusing failure.

    Debug: https://github.com/bitcoin/bitcoin/runs/21199329709

  27. vasild force-pushed on Mar 27, 2024
  28. vasild commented at 6:01 pm on March 27, 2024: contributor
    5e3c80da14...6d9083b249: rebase due to silent merge conflict
  29. DrahtBot removed the label CI failed on Mar 28, 2024
  30. brunoerg approved
  31. brunoerg commented at 11:53 am on April 30, 2024: contributor
    reACK 6d9083b249376d503621da7980ef7ae02e690e0b
  32. DrahtBot added the label CI failed on Jun 22, 2024
  33. DrahtBot commented at 11:23 am on June 22, 2024: contributor

    🚧 At least one of the CI tasks failed. Make sure to run all tests locally, according to the documentation.

    Possibly this is due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    Leave a comment here, if you need help tracking down a confusing failure.

    Debug: https://github.com/bitcoin/bitcoin/runs/23166298024

  34. vasild force-pushed on Jun 25, 2024
  35. vasild commented at 3:39 pm on June 25, 2024: contributor
    6d9083b249...45f4dbe484: rebase due to conflicts
  36. DrahtBot removed the label CI failed on Jun 25, 2024
  37. vasild force-pushed on Jun 26, 2024
  38. vasild commented at 6:46 am on June 26, 2024: contributor
    45f4dbe484...655a2cf666: the previous push resolved the merge conflict in a too late commit, causing the “test each commit” CI job to fail
  39. vasild force-pushed on Sep 2, 2024
  40. vasild commented at 2:48 pm on September 2, 2024: contributor
    655a2cf666...99b1f88fe8: rebase to pick CMake
  41. DrahtBot added the label CI failed on Sep 12, 2024
  42. DrahtBot removed the label CI failed on Sep 15, 2024
  43. achow101 requested review from brunoerg on Oct 15, 2024
  44. DrahtBot added the label CI failed on Oct 25, 2024
  45. DrahtBot removed the label CI failed on Oct 25, 2024
  46. DrahtBot added the label Needs rebase on Oct 25, 2024
  47. fuzz: add CConnman::OpenNetworkConnection() to the tests
    Now that all network calls done by `CConnman::OpenNetworkConnection()`
    are done via `Sock` they can be redirected (mocked) to `FuzzedSocket`
    for testing.
    a6c77ce97c
  48. fuzz: add CConnman::CreateNodeFromAcceptedSocket() to the tests 652dcd0360
  49. fuzz: add CConnman::InitBinds() to the tests 0212a480d1
  50. fuzz: add CConnman::SocketHandler() to the tests 46b0323951
  51. vasild force-pushed on Nov 6, 2024
  52. vasild commented at 10:53 am on November 6, 2024: contributor

    99b1f88fe8...cf83f0c14c: rebase due to conflicts and mock the sleeps

    I guess it should be possible to mock CConnman::interruptNet so that its sleep_for() method returns immediately.

    Sounds good to me.

    Done. CThreadInterrupt can now be mocked in other tests as well. Thanks for the suggestion, @dergoegge!

  53. in src/test/fuzz/util/threadinterrupt.cpp:21 in cf83f0c14c outdated
    14+    return m_fuzzed_data_provider.ConsumeBool();
    15+}
    16+
    17+bool FuzzedThreadInterrupt::sleep_for(Clock::duration)
    18+{
    19+    return m_fuzzed_data_provider.ConsumeBool();
    


    dergoegge commented at 10:59 am on November 6, 2024:
    Perhaps in a follow up we can make mocktime accurate to the millisecond and then advance it here to simulate an actual sleep.

    vasild commented at 12:59 pm on November 6, 2024:

    I like simulating some time passage here.

    Changing static std::atomic<std::chrono::seconds> g_mock_time{}; to a finer precision is indeed out of the scope here.

    Following a discussion on IRC I checked that indeed the time is frozen already for fuzz tests so calling SetMockTime() here is not going to freeze it (since it is already frozen). I added:

    0SetMockTime(ConsumeTime(m_fuzzed_data_provider)); // Time could go backwards.
    

    It could end up increasing the time more than the argument to sleep_for() but this might happen during normal operation, so is a good exercise.

    It could end up with the time going backwards. If this is undesirable then this may be changed to something like:

    0SetMockTime(NodeClock::now() + ConsumeIntegralInRange(0, the_argument_to_sleep_for * 2));
    
  54. DrahtBot removed the label Needs rebase on Nov 6, 2024
  55. DrahtBot added the label CI failed on Nov 6, 2024
  56. DrahtBot commented at 12:43 pm on November 6, 2024: contributor

    🚧 At least one of the CI tasks failed. Debug: https://github.com/bitcoin/bitcoin/runs/32589451018

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

  57. fuzz: make it possible to mock (fuzz) CThreadInterrupt
    * Make the methods of `CThreadInterrupt` virtual and store a pointer to
      it in `CConnman`, thus making it possible to override with a mocked
      instance.
    * Initialize `CConnman::m_interrupt_net` from the constructor, making it
      possible for callers to supply mocked version.
    * Introduce `FuzzedThreadInterrupt` and `ConsumeThreadInterrupt()` and
      use them in `src/test/fuzz/connman.cpp` and `src/test/fuzz/i2p.cpp`.
    
    This improves the CPU utilization of the `connman` fuzz test.
    
    As a nice side effect, the `std::shared_ptr` used for
    `CConnman::m_interrupt_net` resolves the possible lifetime issues with
    it (see the removed comment for that variable).
    c97d49628a
  58. vasild force-pushed on Nov 6, 2024
  59. vasild commented at 1:00 pm on November 6, 2024: contributor
    cf83f0c...c97d496: simulate time passage from FuzzedThreadInterrupt::sleep_for() and (hopefully) fix CI
  60. DrahtBot removed the label CI failed on Nov 6, 2024
  61. jonatack commented at 10:20 pm on November 19, 2024: member
    utACK c97d49628a78aac9a65f2bd1ddc733b0b425090b
  62. DrahtBot requested review from dergoegge on Nov 19, 2024

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: 2024-11-21 18:12 UTC

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