added a config parameter to limit outbound p2p connections.#2974
added a config parameter to limit outbound p2p connections.#2974
Conversation
|
The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).
|
| for old := range pa.fails { | ||
| failedAddr = utils.Some(old) | ||
| break | ||
| } |
Check warning
Code scanning / CodeQL
Iteration over map Warning
| return | ||
| } | ||
| // Record the failure time. | ||
| now := time.Now() |
Check warning
Code scanning / CodeQL
Calling the system time Warning
| for old, pa := range p.addrs { | ||
| if len(pa.fails) < len(pa.addrs) { | ||
| continue | ||
| } | ||
| return old, true | ||
| } |
Check warning
Code scanning / CodeQL
Iteration over map Warning
| for id, peerAddrs := range p.addrs { | ||
| if _, ok := p.dialing[id]; ok { | ||
| continue | ||
| } | ||
| if _, ok := p.conns[id]; ok { | ||
| continue | ||
| } | ||
| if x, ok := bestPeer.Get(); !ok || before(peerAddrs.lastFail, x.lastFail) { | ||
| bestPeer = utils.Some(peerAddrs) | ||
| } | ||
| } |
Check warning
Code scanning / CodeQL
Iteration over map Warning
| for addr := range peer.addrs { | ||
| if x, ok := best.Get(); !ok || before(getOpt(peer.fails, addr), getOpt(peer.fails, x)) { | ||
| best = utils.Some(addr) | ||
| } | ||
| } |
Check warning
Code scanning / CodeQL
Iteration over map Warning
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2974 +/- ##
===========================================
+ Coverage 58.11% 68.45% +10.33%
===========================================
Files 2109 40 -2069
Lines 173394 3959 -169435
===========================================
- Hits 100771 2710 -98061
+ Misses 63675 1007 -62668
+ Partials 8948 242 -8706
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
wen-coding
left a comment
There was a problem hiding this comment.
I think this looks reasonable. However, if there is semantics change, I'd slightly prefer to split semantics change into another PR if possible. Just in case there is any emergency, it would be much easier to diagnose problems.
| MaxConnections uint16 `mapstructure:"max-connections"` | ||
|
|
||
| // MaxConnections limits the number of outbound peers. | ||
| // It should be significantly lower than MaxConnections, unless |
There was a problem hiding this comment.
nit: maybe we should give a guideline how much lower this should be compared to MaxConnections
There was a problem hiding this comment.
well, I don't know that yet :). I estimate 10 outbound, 50 total, but this is tbd.
| func (i *peerManagerInner[C]) TryStartDial(persistentPeer bool) (NodeAddress, bool) { | ||
| // Check concurrent dials limit. | ||
| if len(i.dialing) >= i.options.maxDials() { | ||
| if len(i.regular.dialing)+len(i.persistent.dialing) >= i.options.maxDials() { |
There was a problem hiding this comment.
should we cleanly split everything (including maxdials) between the two pool?
There was a problem hiding this comment.
probably, but that's more configuration. We can reconsider that later.
| if !i.isPersistent(id) { | ||
| delete(i.addrs, id) | ||
| } | ||
| if !i.isUnconditional[id] { |
There was a problem hiding this comment.
originally even when id is persistent we will close connection if it's not unconditional, we don't need this any more?
There was a problem hiding this comment.
all persistent peers are unconditional (see the old newPeerManager impl). In this pr I've merged the unconditional and persistent to be the same concept (see pr description) to simplify the situation a bit.
| return Map[K, V]{m.m.Set(key, value)} | ||
| } | ||
|
|
||
| func (m Map[K, V]) SetOpt(key K, mvalue utils.Option[V]) Map[K, V] { |
There was a problem hiding this comment.
nit: SetOpt sounds like it will do nothing if the key doesn't exist, how about SetOrDelete or something like that.
There was a problem hiding this comment.
It is dual to getopt. I've added documentation. I can change to SetOrDelete if you feel strongly about this.
| } | ||
|
|
||
| type poolConfig struct { | ||
| selfID types.NodeID |
There was a problem hiding this comment.
nit: would you use different selfID on different pools?
There was a problem hiding this comment.
No, but I want the pools to be self contained.
| isPersistent: map[types.NodeID]bool{}, | ||
| conns: utils.NewAtomicSend(im.NewMap[types.NodeID, C]()), | ||
|
|
||
| persistent: newPool[C](poolConfig{selfID: selfID}), |
There was a problem hiding this comment.
Where are the metrics? Should we split metrics by pool as well?
There was a problem hiding this comment.
there is a metric for the total number of connections, there is a log printed every 10s with number of connections (regular vs persistent) and there is network state exposed via net_info rpc endpoint. Metrics and the rpc endpoint need a revamp indeed but it is out of scope of this pr.
For a healthy p2p network nodes should provide more capacity than they consume. This PR adds a limit on the number of outbound connections, so that a node does not try to fill up ALL of the available connection slots that it has, but rather to establish just a reasonable number of connections and let other nodes connect to it. Additionally: