-
Notifications
You must be signed in to change notification settings - Fork 57
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
chore: capping mechanism for relay and service connections #3184
base: master
Are you sure you want to change the base?
Conversation
You can find the image built from this PR at
Built from a379b02 |
2e420e4
to
fa97a4f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thanks so much!
Added just a couple questions/comments
@@ -993,6 +999,24 @@ proc new*( | |||
# Leave by default 20% of connections for service peers | |||
maxRelayPeersValue = maxConnections - (maxConnections div 5) | |||
|
|||
var maxServicePeersValue = 0 | |||
var d_low = 4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we shouldn't hardcode this and take it directly from WakuRelay
# relay has higher priority then service peers | ||
else: | ||
maxServicePeersValue = | ||
max(maxConnections - maxRelayPeersValue, maxConnections div 5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the logic of this line? Why the maxConnections div 5
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My logic is to reserve 20% for service peers if the user does not provide maxService, as we discuss in nwaku pm we need to change whole logic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR doesn't compile snif snif :s
Re-thinking about this, I suggest doing the following:
We need to keep maxConnections
config param because this needs to be passed to the nim-libp2p-Switch object.
On the other hand, I would only add an additional parameter, named protoConnWeights
, a.k.a. proto-conn-weights
, with the following logic:
If proto-conn-weights
is not passed, then we apply the internal limits of 70% for relay, and the other 30% is evenly distributed for other protocols.
If proto-conn-weights=relay:80;services:20
, we apply the internal limits of 80% for relay, and the other 20% is evenly distributed for other protocols.
We need to make sure the relay limit is bigger than DHigh ( we can create a
public Constant
in waku_relay/protocol.nim
)
nwaku/waku/waku_relay/protocol.nim
Line 73 in 09f05fe
dHigh = 8, |
wdyt @NagyZoltanPeter , @gabrielmer , @darshankabariya ?
@@ -993,6 +995,20 @@ proc new*( | |||
# Leave by default 20% of connections for service peers | |||
maxRelayPeersValue = maxConnections - (maxConnections div 5) | |||
|
|||
var maxServicePeersValue = 0 | |||
var d_low = 4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will need to use the d_low value extracted from waku_relay
. Perhaps defining a const in waku_relay
and use that value
My bad, I pushed the code without a local build. I’ll update this PR until we finalize it. |
At the moment, we have parameters like Instead, I believe users generally don’t think in terms of absolute numbers for services and relays. From a psychological perspective, they might find it more intuitive to think in percentages—e.g., 80% for services, 20% for relays. My suggestion is to simplify this structure. We should keep If users don’t provide this percentage, we could default to a ratio, as Ivan suggested. I believe this would simplify the experience while maintaining flexibility. |
I like your idea! IMO I feel we still need hardcoded minimum still so that you can't, by mistake brick your node. |
Same opinion here, having 2 params, a maximum and a ratio to know how many to allocate for each should make things simple yet customizable :) |
Thanks @gabrielmer @SionoiS for reply ! i also like suggestion. If this approach looks good to you, I can begin the implementation. Just to confirm, we're only discussing the deprecation of the external configuration parameter, correct? I believe we still need to maxRelayPeer and maxServicePeer within the peerManager. Regarding your thoughts on the ratio, I have an idea: instead of using a float, we could represent it as a string, like 0.33 becoming 40:60 or 0.43 as 30:70. it's just need calculator 😂for some ratio, Let me know what you guys think, and I’ll implement accordingly. |
02fd08c
to
ab0c1d4
Compare
Yes! That would only be for the external configuration, we would then translate it into Regarding the format, I'm pretty neutral about it - no strong opinions. Would like to hear what others think :)) |
If that's simpler go for it! No strong opinion here either. |
d5a12ef
to
049fbea
Compare
Just leaving a comment to inform, this PR is ready to be merged. Thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work! I think we are getting even closer ;P
Kindly review my comments and let me know if something isn't clear or I'm missing anything
Thanks again 🙌 !
|
||
ok((float(relayRatio / total), float(serviceRatio / total))) | ||
except Exception: | ||
err("Invalid number format in ratio") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
err("Invalid number format in ratio") | |
return err("Invalid number format in ratio: " & getCurrentExceptionMsg()) |
if total == 0: | ||
return err("Total ratio cannot be zero") | ||
|
||
ok((float(relayRatio / total), float(serviceRatio / total))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick comment: I think is better to always use the return
keyword
ok((float(relayRatio / total), float(serviceRatio / total))) | |
return ok((float(relayRatio / total), float(serviceRatio / total))) |
@@ -49,3 +49,24 @@ proc parseCorrectMsgSize*(input: string): uint64 = | |||
let ret = parseMsgSize(input).valueOr: | |||
return 0 | |||
return ret | |||
|
|||
proc parseRelayServiceRatio*(ratio: string): Result[(float, float), string] = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to have a comment to explain the parameter and the returning values
try: | ||
let elements = ratio.split(":") | ||
if elements.len != 2: | ||
return err("Invalid format for relay ratio expected relay:service") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return err("Invalid format for relay ratio expected relay:service") | |
return err("Invalid format for relay ratio expected relay:service, found: " & ratio) |
serviceRatio = parseInt(elements[1]) | ||
|
||
if relayRatio < 0 or serviceRatio < 0: | ||
return err("Relay and service ratios must be non-negative integers") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return err("Relay and service ratios must be non-negative integers") | |
return err("Relay and service ratios must be non-negative integers. Found this: " & ratio) |
waku/factory/builder.nim
Outdated
let relayServiceRatio = parseRelayServiceRatio(relayServiceRatio) | ||
if relayServiceRatio.isErr: | ||
warn "Invalid relay service ratio", ratio = relayServiceRatio | ||
return | ||
|
||
let (relayRatio, serviceRatio) = relayServiceRatio.get |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let relayServiceRatio = parseRelayServiceRatio(relayServiceRatio) | |
if relayServiceRatio.isErr: | |
warn "Invalid relay service ratio", ratio = relayServiceRatio | |
return | |
let (relayRatio, serviceRatio) = relayServiceRatio.get | |
let (relayRatio, serviceRatio) = parseRelayServiceRatio(relayServiceRatio).valueOr: | |
error "Invalid relay service ratio", ratio = relayServiceRatio, error = error | |
return ## we should stop the execution in this point but for further PR's |
var relayPeers = int(ceil(float(maxConnections) * relayRatio)) | ||
var servicePeers = int(floor(float(maxConnections) * serviceRatio)) | ||
|
||
if maxRelayPeers.isSome() or maxServicePeers.isSome(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe not needed this if
statement?
if relayPeers + servicePeers > maxConnections: | ||
warn "Max number of connections can't be greater than maxRelayPeers + maxServicePeers", | ||
maxConnections = maxConnections, | ||
maxRelayPeers = relayPeers, | ||
maxServicePeers = servicePeers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This block shouldn't be needed because we should validate that on startup
maxRelayPeers = relayPeers, | ||
maxServicePeers = servicePeers | ||
|
||
let minRelayPeers = 8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The value is correct nowadays:)
However, instead of using this hard-coded value, we should extract this value from the dHigh
configured in WakuRelay
.
Then, we should have something like:
let minRelayPeers = 8 | |
let minRelayPeers = WakuRelay.getDHigh() |
And, in waku_relay/protocol.nim
, we should create the following simple proc that exposes the dHigh configured value:
proc getDHigh*(T: type WakuRelay): int =
return GossipsubParameters.dHigh
if relayPeers < minRelayPeers: | ||
let newMaxConnections = int(float(minRelayPeers) / relayRatio) | ||
warn "fullfill the minimum criteria you need to increase the max number of connections", | ||
newMaxConnections = newMaxConnections |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this validation should be made earlier and, in case not configured properly, immediately stop the execution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this validation should be made earlier and, in case not configured properly, immediately stop the execution.
Thanks for all the comments! I've tried to address all of them all but instead of replying to each one individually (I’m just afraid it will scatter our discussion.), bcz I agree with most of your comments and have updated the PR accordingly.
However, regarding this suggestion:
I couldn't find a way to validate it earlier. While it's possible to add the validation in the parse function, doing so would require the maxConnection value within that function, which could overcomplicate the logic and violate the single responsibility principle.
Thank you very much !
eb617de
to
36f4473
Compare
a414c70
to
dbf8a0a
Compare
This PR prevents nodes from becoming isolated from the network by implementing a capping mechanism for service and relay peers. This ensures there is always room available for relay peers at any given time.
close #3163