1818 ./ p2p_metrics,
1919 ./ [eth1_discovery, p2p_peers]
2020
21- export sets, tables
21+ from eth/ common/ base import ForkID
22+
23+ export sets, tables, CompatibleForkIdProc
2224
2325logScope:
2426 topics = " p2p peer_pool"
3032
3133 WorkerFuture = Future [void ].Raising ([CancelledError ])
3234
35+ ForkIdProc * = proc (): ForkID {.noSideEffect , raises : [].}
36+
3337 # Usually Network generic param is instantiated with EthereumNode
3438 PeerPoolRef * [Network ] = ref object
3539 network: Network
4044 running: bool
4145 discovery: Eth1Discovery
4246 workers: seq [WorkerFuture ]
47+ forkId: ForkIdProc
48+ lastForkId: ForkID
49+ connectTimer: Future [void ].Raising ([CancelledError ])
50+ updateTimer: Future [void ].Raising ([CancelledError ])
4351 connectingNodes* : HashSet [Node ]
4452 connectedNodes* : Table [Node , PeerRef [Network ]]
4553 observers* : Table [int , PeerObserverRef [Network ]]
5260const
5361 lookupInterval = 5
5462 connectLoopSleep = chronos.milliseconds (2000 )
63+ updateLoopSleep = chronos.seconds (15 )
5564 maxConcurrentConnectionRequests = 40
5665 sleepBeforeTryingARandomBootnode = chronos.milliseconds (3000 )
5766
@@ -188,23 +197,55 @@ proc maybeConnectToMorePeers(p: PeerPoolRef) {.async: (raises: [CancelledError])
188197 return
189198 await p.connectToNode (n)
190199
200+ func updateForkID (p: PeerPoolRef ) =
201+ if p.forkId.isNil:
202+ return
203+
204+ let forkId = p.forkId ()
205+ if p.lastForkId == forkId:
206+ return
207+
208+ p.discovery.updateForkID (forkId)
209+ p.lastForkId = forkId
210+
191211proc run (p: PeerPoolRef ) {.async : (raises: [CancelledError ]).} =
192212 trace " Running PeerPool..."
193213
214+ # initial cycle
215+ p.updateForkID ()
194216 await p.discovery.start ()
217+ await p.maybeConnectToMorePeers ()
218+
195219 p.running = true
196220 while p.running:
197221 debug " Amount of peers" , amount = p.connectedNodes.len ()
198- await p.maybeConnectToMorePeers ()
199- await sleepAsync (connectLoopSleep)
222+
223+ # Create or replenish timer
224+ if p.connectTimer.isNil or p.connectTimer.finished:
225+ p.connectTimer = sleepAsync (connectLoopSleep)
226+
227+ if p.updateTimer.isNil or p.updateTimer.finished:
228+ p.updateTimer = sleepAsync (updateLoopSleep)
229+
230+ let
231+ res = await one (p.connectTimer, p.updateTimer)
232+
233+ if res == p.connectTimer:
234+ await p.maybeConnectToMorePeers ()
235+
236+ if res == p.updateTimer:
237+ p.updateForkID ()
200238
201239# ------------------------------------------------------------------------------
202240# Private functions
203241# ------------------------------------------------------------------------------
204242
205243func newPeerPool * [Network](
206244 network: Network ,
207- discovery: Eth1Discovery , minPeers = 10 ): PeerPoolRef [Network ] =
245+ discovery: Eth1Discovery ,
246+ minPeers = 10 ,
247+ forkId = ForkIdProc (nil ),
248+ ): PeerPoolRef [Network ] =
208249 new result
209250 result .network = network
210251 result .minPeers = minPeers
@@ -213,6 +254,7 @@ func newPeerPool*[Network](
213254 result .connectedNodes = initTable [Node , PeerRef [Network ]]()
214255 result .connectingNodes = initHashSet [Node ]()
215256 result .observers = initTable [int , PeerObserverRef [Network ]]()
257+ result .forkId = forkId
216258
217259proc addObserver * (p: PeerPoolRef , observerId: int , observer: PeerObserverRef ) =
218260 doAssert (observerId notin p.observers)
0 commit comments