@@ -23,9 +23,8 @@ use ethportal_api::{
2323} ;
2424use lru:: LruCache ;
2525use parking_lot:: RwLock ;
26- use tokio:: sync:: { mpsc, RwLock as TokioRwLock } ;
26+ use tokio:: sync:: mpsc;
2727use tracing:: { debug, info, warn} ;
28- use trin_validation:: oracle:: HeaderOracle ;
2928use utp_rs:: {
3029 peer:: { ConnectionPeer , Peer } ,
3130 udp:: AsyncUdpSocket ,
@@ -159,6 +158,11 @@ impl Discovery {
159158
160159 let discv5_config = ConfigBuilder :: new ( listen_config)
161160 . request_timeout ( Duration :: from_secs ( 3 ) )
161+ // Set the session cache capacity to match our node address cache capacity. If our cache
162+ // is smaller then the session cache capacity, it can lead to problems where we can't
163+ // send replies to nodes that we have a session with, as we wouldn't have enough room in
164+ // to store all the Enr's from all of our current established connections.
165+ . session_cache_capacity ( portal_config. discv5_session_cache_capacity )
162166 . build ( ) ;
163167 let discv5 = Discv5 :: new ( enr, enr_key, discv5_config)
164168 . map_err ( |e| format ! ( "Failed to create discv5 instance: {e}" ) ) ?;
@@ -173,7 +177,9 @@ impl Discovery {
173177 . map_err ( |e| format ! ( "Failed to add bootnode enr: {e}" ) ) ?;
174178 }
175179
176- let node_addr_cache = LruCache :: new ( portal_config. node_addr_cache_capacity ) ;
180+ // We set the cache capacity to double the node address cache capacity pad for
181+ // inconsistencies between the two caches.
182+ let node_addr_cache = LruCache :: new ( portal_config. discv5_session_cache_capacity * 2 ) ;
177183 let node_addr_cache = Arc :: new ( RwLock :: new ( node_addr_cache) ) ;
178184
179185 Ok ( Self {
@@ -213,16 +219,6 @@ impl Discovery {
213219 let _ = talk_req_tx. send ( talk_req) . await ;
214220 }
215221 Event :: SessionEstablished ( enr, socket_addr) => {
216- // TODO: this is a temporary fix to prevent caching of eth2 nodes
217- // and will be updated to a more stable solution as soon as it
218- // validates the theory of what is causing the issue on mainnet.
219- if enr. get_decodable :: < String > ( ENR_PORTAL_CLIENT_KEY ) . is_none ( ) {
220- debug ! (
221- enr = ?enr,
222- "discv5 session established with node that does not have a portal client key, not caching"
223- ) ;
224- continue ;
225- }
226222 if let Some ( old) = node_addr_cache. write ( ) . put (
227223 enr. node_id ( ) ,
228224 NodeAddress {
@@ -290,8 +286,20 @@ impl Discovery {
290286 }
291287
292288 /// Looks up the ENR for `node_id`.
289+ ///
290+ /// First, it checks the cache for the `NodeAddress` and returns the `Enr` if found.
291+ /// If not found, it queries the Discv5 routing table for the `node_id` and returns the `Enr` if
292+ /// found.
293293 pub fn find_enr ( & self , node_id : & NodeId ) -> Option < Enr > {
294- self . discv5 . find_enr ( node_id)
294+ if let Some ( enr) = self . cached_node_addr ( node_id) {
295+ return Some ( enr. enr ) ;
296+ }
297+
298+ if let Some ( enr) = self . discv5 . find_enr ( node_id) {
299+ return Some ( enr) ;
300+ }
301+
302+ None
295303 }
296304
297305 /// Adds `enr` to the discv5 routing table.
@@ -363,24 +371,16 @@ impl Discovery {
363371pub struct Discv5UdpSocket {
364372 talk_request_receiver : mpsc:: UnboundedReceiver < TalkRequest > ,
365373 discv5 : Arc < Discovery > ,
366- enr_cache : Arc < TokioRwLock < LruCache < NodeId , Enr > > > ,
367- header_oracle : Arc < TokioRwLock < HeaderOracle > > ,
368374}
369375
370376impl Discv5UdpSocket {
371377 pub fn new (
372378 discv5 : Arc < Discovery > ,
373379 talk_request_receiver : mpsc:: UnboundedReceiver < TalkRequest > ,
374- header_oracle : Arc < TokioRwLock < HeaderOracle > > ,
375- enr_cache_capacity : usize ,
376380 ) -> Self {
377- let enr_cache = LruCache :: new ( enr_cache_capacity) ;
378- let enr_cache = Arc :: new ( TokioRwLock :: new ( enr_cache) ) ;
379381 Self {
380382 discv5,
381383 talk_request_receiver,
382- enr_cache,
383- header_oracle,
384384 }
385385 }
386386}
@@ -437,16 +437,15 @@ impl AsyncUdpSocket<UtpPeer> for Discv5UdpSocket {
437437 let peer_id = * peer. id ( ) ;
438438 let peer_enr = peer. peer ( ) . cloned ( ) ;
439439 let discv5 = Arc :: clone ( & self . discv5 ) ;
440- let enr_cache = Arc :: clone ( & self . enr_cache ) ;
441- let header_oracle = Arc :: clone ( & self . header_oracle ) ;
442440 let data = buf. to_vec ( ) ;
443441 tokio:: spawn ( async move {
444442 let enr = match peer_enr {
445443 Some ( enr) => enr. 0 ,
446- None => match find_enr ( & peer_id, & discv5, enr_cache, header_oracle) . await {
447- Ok ( enr) => enr,
448- Err ( err) => {
449- warn ! ( %err, "unable to send uTP talk request, ENR not found" ) ;
444+ None => match discv5. find_enr ( & peer_id) {
445+ Some ( enr) => enr,
446+ None => {
447+ debug ! ( node_id = %peer_id, "uTP packet to unknown target" ) ;
448+ warn ! ( "unable to send uTP talk request, ENR not found for talk req destination" ) ;
450449 return ;
451450 }
452451 } ,
@@ -483,54 +482,3 @@ impl AsyncUdpSocket<UtpPeer> for Discv5UdpSocket {
483482 }
484483 }
485484}
486-
487- async fn find_enr (
488- node_id : & NodeId ,
489- discv5 : & Arc < Discovery > ,
490- enr_cache : Arc < TokioRwLock < LruCache < NodeId , Enr > > > ,
491- header_oracle : Arc < TokioRwLock < HeaderOracle > > ,
492- ) -> io:: Result < Enr > {
493- if let Some ( cached_enr) = enr_cache. write ( ) . await . get ( node_id) . cloned ( ) {
494- return Ok ( cached_enr) ;
495- }
496-
497- if let Some ( enr) = discv5. find_enr ( node_id) {
498- enr_cache. write ( ) . await . put ( * node_id, enr. clone ( ) ) ;
499- return Ok ( enr) ;
500- }
501-
502- if let Some ( enr) = discv5. cached_node_addr ( node_id) {
503- enr_cache. write ( ) . await . put ( * node_id, enr. enr . clone ( ) ) ;
504- return Ok ( enr. enr ) ;
505- }
506-
507- let history_jsonrpc_tx = header_oracle. read ( ) . await . history_jsonrpc_tx ( ) ;
508- if let Ok ( history_jsonrpc_tx) = history_jsonrpc_tx {
509- if let Ok ( enr) = HeaderOracle :: history_get_enr ( node_id, history_jsonrpc_tx) . await {
510- enr_cache. write ( ) . await . put ( * node_id, enr. clone ( ) ) ;
511- return Ok ( enr) ;
512- }
513- }
514-
515- let state_jsonrpc_tx = header_oracle. read ( ) . await . state_jsonrpc_tx ( ) ;
516- if let Ok ( state_jsonrpc_tx) = state_jsonrpc_tx {
517- if let Ok ( enr) = HeaderOracle :: state_get_enr ( node_id, state_jsonrpc_tx) . await {
518- enr_cache. write ( ) . await . put ( * node_id, enr. clone ( ) ) ;
519- return Ok ( enr) ;
520- }
521- }
522-
523- let beacon_jsonrpc_tx = header_oracle. read ( ) . await . beacon_jsonrpc_tx ( ) ;
524- if let Ok ( beacon_jsonrpc_tx) = beacon_jsonrpc_tx {
525- if let Ok ( enr) = HeaderOracle :: beacon_get_enr ( node_id, beacon_jsonrpc_tx) . await {
526- enr_cache. write ( ) . await . put ( * node_id, enr. clone ( ) ) ;
527- return Ok ( enr) ;
528- }
529- }
530-
531- debug ! ( node_id = %node_id, "uTP packet to unknown target" ) ;
532- Err ( io:: Error :: new (
533- io:: ErrorKind :: Other ,
534- "ENR not found for talk req destination" ,
535- ) )
536- }
0 commit comments