Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

addrmgr: Mitigate high CPU use when attempts become large. #3047

Merged
merged 2 commits into from
Jan 21, 2023

Conversation

chappjc
Copy link
Member

@chappjc chappjc commented Jan 20, 2023

This PR contains two commits aimed at avoiding debilitating CPU use by the AddrManager when a KnownAddress' attempts becomes large. On testnet, the dex native SPV wallet reproducibly becomes crippled without these changes, causing both high CPU use and peering timeouts as the GetAddress method blocks for long periods.

addrmgr: break after selecting random address

This adds a missing break statement to the range over the map of
addresses used to select a random entry from the map.  Previously
the loop would continue needlessly until the entire map was traversed.
This is a minor optimization.
addrmgr: set min value and optimize address chance

This updates the (*KnownAddress).chance method in the following ways:
1. Apply a lower limit to the return value.  Using 0.01  as this minimum
   prevents tiny chance values from causing excessive iterations in
   (*AddrManager).GetAddress, currently the only caller.
2. Replace an inefficient loop with a single math.Pow.

These changes are mitigations to excessive CPU use in the GetAddress
method that manifest when the number of attempts for a KnownAddress
becomes large.  However, this method and much of addrmgr should be
rewritten in the future since there are some ad hoc and questionable
approaches to candidate address selection.

This adds a missing break statement to the range over the map of
addresses used to select a random entry from the map.  Previously
the loop would continue needlessly until the entire map was traversed.
This is a minor optimization.
This updates the (*KnownAddress).chance method in the following ways:
1. Apply a lower limit to the return value.  Using 0.01  as this minimum
   prevents tiny chance values from causing excessive iterations in
   (*AddrManager).GetAddress, currently the only caller.
2. Replace an inefficient loop with a single math.Pow.

These changes are mitigations to excessive CPU use in the GetAddress
method that manifest when the number of attempts for a KnownAddress
becomes large.  However, this method and much of addrmgr should be
rewritten in the future since there are some ad hoc and questionable
approaches to candidate address selection.
@@ -69,19 +70,18 @@ func (ka *KnownAddress) chance() float64 {
lastAttempt = 0
}

c := 1.0
// Apply a lower limit to the value returned.
const minChance = 0.01
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only thing I'm uncertain about is this const value. I haven't tested this on mainnet, but I don't see how this limit could be too high.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any issue with it considering the total number of peers. If there were several million nodes it would probably be too high, but that isn't the case.

@davecgh davecgh changed the title addrmgr: mitigate high CPU use when attempts become large addrmgr: Mitigate high CPU use when attempts become large. Jan 21, 2023
@davecgh davecgh merged commit 3bc18a3 into decred:master Jan 21, 2023
@chappjc chappjc deleted the less-derp-addrmgr branch January 21, 2023 14:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants