[net] De-duplicate connection eviction logic #11524

pull tjps wants to merge 1 commits into bitcoin:master from tjps:tjps_eviction changing 1 files +20 −29
  1. tjps commented at 8:03 AM on October 19, 2017: contributor

    While reviewing the safeguards against deliberate node isolation on the network by malicious actors, I found a good de-duplication candidate.

    I think this form is much more legible (the type of cutoffs notwithstanding). ReverseCompareNodeTimeConnected is not included in the list since the cutoff size is a function of the remaining number of nodes in the candidate eviction set.

  2. fanquake added the label P2P on Oct 19, 2017
  3. fanquake added the label Refactoring on Oct 19, 2017
  4. practicalswift commented at 10:08 AM on October 19, 2017: contributor

    Concept ACK. Nice cleanup!

  5. promag commented at 2:38 PM on October 19, 2017: member

    Concept ACK.

    I would prefer to abstract the loop body into a function, and call it 4 times with the given arguments.

    It should be easier to test and IMO understand.

  6. ryanofsky commented at 2:14 PM on October 20, 2017: member

    utACK b52635e0b9db58095c21de1af5f5a0c74a85b63c. Change is an an improvement over existing code, but this can be simplified more. There is no need for std::function indirection, and no need for looping. All you need here is a plain generic function:

    //! Remove last n elements from container after sorting, and return true if it is non-empty.
    template<typename Container, typename Compare>
    bool EraseLastN(Container& container, int n, Compare compare);
    

    and

    if (!(EraseLastN(vEvictionCandidates, 4, CompareNetGroupKeyed) ||
        !(EraseLastN(vEvictionCandidates, 8, ReverseCompareNodeMinPingTime) ||
        !(EraseLastN(vEvictionCandidates, 4, CompareNodeTXTime) ||
        !(EraseLastN(vEvictionCandidates, 4, CompareNodeBlockTime)) {
        return false
    };
    

    You might also want to use std::partial_sort instead of std::sort in the new code since a full sort isn't necessary.

  7. sipa commented at 2:16 PM on October 21, 2017: member

    Concept ACK; I prefer @ryanofsky's suggestion as well.

  8. meshcollider commented at 10:07 AM on October 22, 2017: contributor

    Concept ACK, nice cleanup. I too prefer @ryanofsky's version plus your comments :)

  9. tjps commented at 12:56 AM on October 25, 2017: contributor

    @ryanofsky - I was unaware of std::partial_sort, and while it seems perfectly suited to this use case, all the benchmarks I found comparing it to std::sort seemed to indicate it was slower. I'll leave it using std::sort for now.

    Also since removeLastKElements is a no-op on an empty vector, I left it as a void return type and skipped the chained conditional return checks. I think this makes the code more readable.

  10. tjps commented at 6:47 PM on October 26, 2017: contributor

    Updated diff to include a little DRY/readability improvement at the end of the same function.

  11. in src/net.cpp:968 in 0bd38149bd outdated
     961 | @@ -962,6 +962,16 @@ static bool CompareNodeTXTime(const NodeEvictionCandidate &a, const NodeEviction
     962 |      return a.nTimeConnected > b.nTimeConnected;
     963 |  }
     964 |  
     965 | +
     966 | +//! Sort an array by the specified comparator, then remove the last K elements.
     967 | +template<typename T>
     968 | +static void removeLastKElements(std::vector<T> &elements, bool(*comparator)(const T&, const T&), size_t k)
    


    ryanofsky commented at 6:26 PM on October 31, 2017:

    Maybe don't require comparator to be function pointer. It'd be nice to allow comparator to be a lambda or function class:

    template<typename T, typename Compare>
    static void removeLastKElements(std::vector<T> &elements, Compare comp, size_t k)
    {
        std::sort(elements.begin(), elements.end(), comp);
        ...
    }
    

    tjps commented at 8:25 PM on November 1, 2017:

    That's a good point, should have pulled that from your example. Old habits die hard.

  12. in src/net.cpp:971 in 0bd38149bd outdated
     966 | +//! Sort an array by the specified comparator, then remove the last K elements.
     967 | +template<typename T>
     968 | +static void removeLastKElements(std::vector<T> &elements, bool(*comparator)(const T&, const T&), size_t k)
     969 | +{
     970 | +    std::sort(elements.begin(), elements.end(), comparator);
     971 | +    size_t cutSize = std::min(k, elements.size());
    


    ryanofsky commented at 6:30 PM on October 31, 2017:

    Naming convention in new code would call this cut_size. I would probably just inline this variable, though. Also I think it's a little weird how the code is using "remove" "cut" and "erase" interchangeably. I don't see why you wouldn't want to be consistent and just say "erase" everywhere.


    tjps commented at 8:38 PM on November 1, 2017:

    I like k to refer to the K in the function name. I agree that the naming should be more consistent, switching to 'erase' across the board.

  13. ryanofsky commented at 6:32 PM on October 31, 2017: member

    utACK 0bd38149bde46779b5d0823344c1187372062d13. Still looks good. Feel free to ignore new nitpicky comments.

  14. in src/net.cpp:972 in efa5756823 outdated
     967 | +template<typename T, typename Comparator>
     968 | +static void eraseLastKElements(std::vector<T> &elements, Comparator comparator, size_t k)
     969 | +{
     970 | +    std::sort(elements.begin(), elements.end(), comparator);
     971 | +    size_t eraseSize = std::min(k, elements.size());
     972 | +    elements.erase(elements.end() - eraseSize, elements.end());
    


    TheBlueMatt commented at 4:43 PM on November 6, 2017:

    Technically this introduces undefined behavior - we no longer return early if we're gonna call erase(end()), which is undefined.


    ryanofsky commented at 4:55 PM on November 6, 2017:

    Technically this introduces undefined behavior - we no longer return early if we're gonna call erase(end()), which is undefined.

    This seems to be fine according to http://en.cppreference.com/w/cpp/container/vector/erase: "The iterator first does not need to be dereferenceable if first==last: erasing an empty range is a no-op."


    TheBlueMatt commented at 5:29 PM on November 6, 2017:

    Oops, indeed, somehow I missed that line.

  15. TheBlueMatt commented at 5:29 PM on November 6, 2017: member

    utACK efa57568236cd7b3a80419e09e9babd546cbbda3

  16. sipa commented at 6:43 PM on November 7, 2017: member

    utACK efa57568236cd7b3a80419e09e9babd546cbbda3, but can you follow the function naming convention (EraseLastKElements)?

  17. [net] De-duplicate connection eviction logic 5ce7cb9518
  18. tjps commented at 11:34 PM on November 7, 2017: contributor

    @sipa whoops, of course. Updated the function name.

  19. sipa commented at 11:36 PM on November 7, 2017: member

    re-utACK 5ce7cb95180b7d8873dae91d8370bc7ea69cd2a7, only change is the function name.

  20. laanwj commented at 7:46 AM on November 8, 2017: member

    utACK 5ce7cb9

  21. laanwj merged this on Nov 8, 2017
  22. laanwj closed this on Nov 8, 2017

  23. fanquake referenced this in commit 5ef3b6967b on Nov 8, 2017
  24. MarcoFalke commented at 8:07 PM on November 8, 2017: member

    post merge utACK 5ce7cb95180b7d8873dae91d8370bc7ea69cd2a7

  25. tjps deleted the branch on Nov 17, 2017
  26. PastaPastaPasta referenced this in commit 93317dec9d on Dec 22, 2019
  27. PastaPastaPasta referenced this in commit 6c1d63db65 on Jan 2, 2020
  28. PastaPastaPasta referenced this in commit dd280d9d5e on Jan 4, 2020
  29. PastaPastaPasta referenced this in commit d239fcf3b4 on Jan 12, 2020
  30. PastaPastaPasta referenced this in commit 74c18363b7 on Jan 12, 2020
  31. PastaPastaPasta referenced this in commit 26a20a9782 on Jan 12, 2020
  32. PastaPastaPasta referenced this in commit fac46bd865 on Jan 12, 2020
  33. PastaPastaPasta referenced this in commit f0f23731a8 on Jan 12, 2020
  34. PastaPastaPasta referenced this in commit 266204fa27 on Jan 12, 2020
  35. PastaPastaPasta referenced this in commit 8d97491d29 on Jan 16, 2020
  36. PastaPastaPasta referenced this in commit 2db55b476f on Jan 22, 2020
  37. PastaPastaPasta referenced this in commit 24cd658431 on Jan 29, 2020
  38. PastaPastaPasta referenced this in commit 96339f110c on Jan 29, 2020
  39. ckti referenced this in commit abfb04c9f9 on Mar 28, 2021
  40. gades referenced this in commit a66424315e on Jun 25, 2021
  41. 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-22 06:15 UTC

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