@@ -68,6 +68,7 @@ use ssz::Encode;
68
68
use ssz_types:: { BitList , VariableList } ;
69
69
use thiserror:: Error ;
70
70
use tokio:: sync:: mpsc:: { self , UnboundedReceiver , UnboundedSender } ;
71
+ use tokio:: sync:: Mutex ;
71
72
72
73
/// Maximum number of ENRs in response to FindNodes.
73
74
pub const FIND_NODES_MAX_NODES : usize = 32 ;
@@ -317,11 +318,11 @@ pub struct OverlayService<TContentKey, TMetric, TValidator> {
317
318
/// Metrics reporting component
318
319
metrics : Option < OverlayMetrics > ,
319
320
/// Validator for overlay network content.
320
- validator : TValidator ,
321
+ validator : Arc < Mutex < TValidator > > ,
321
322
}
322
323
323
324
impl <
324
- TContentKey : OverlayContentKey + Send + Sync ,
325
+ TContentKey : ' static + OverlayContentKey + Send + Sync ,
325
326
TMetric : Metric + Send + Sync ,
326
327
TValidator : ' static + Validator < TContentKey > + Send + Sync ,
327
328
> OverlayService < TContentKey , TMetric , TValidator >
@@ -343,7 +344,7 @@ where
343
344
protocol : ProtocolId ,
344
345
utp_listener_sender : UnboundedSender < UtpListenerRequest > ,
345
346
enable_metrics : bool ,
346
- validator : TValidator ,
347
+ validator : Arc < Mutex < TValidator > > ,
347
348
query_timeout : Duration ,
348
349
query_peer_timeout : Duration ,
349
350
query_parallelism : usize ,
@@ -486,7 +487,7 @@ where
486
487
487
488
// Perform background processing.
488
489
match response. response {
489
- Ok ( response) => self . process_response( response, active_request. destination, active_request. request, active_request. query_id) . await ,
490
+ Ok ( response) => self . process_response( response, active_request. destination, active_request. request, active_request. query_id) ,
490
491
Err ( error) => self . process_request_failure( response. request_id, active_request. destination, error) ,
491
492
}
492
493
@@ -1108,7 +1109,7 @@ where
1108
1109
}
1109
1110
1110
1111
/// Processes a response to an outgoing request from some source node.
1111
- async fn process_response (
1112
+ fn process_response (
1112
1113
& mut self ,
1113
1114
response : Response ,
1114
1115
source : Enr ,
@@ -1171,7 +1172,6 @@ where
1171
1172
}
1172
1173
} ;
1173
1174
self . process_content ( content, source, find_content_request, query_id)
1174
- . await
1175
1175
}
1176
1176
Response :: Accept ( accept) => {
1177
1177
let offer_request = match request {
@@ -1182,18 +1182,15 @@ where
1182
1182
}
1183
1183
} ;
1184
1184
1185
- if let Err ( err) = self
1186
- . process_accept ( accept, source, offer_request. content_keys )
1187
- . await
1188
- {
1185
+ if let Err ( err) = self . process_accept ( accept, source, offer_request. content_keys ) {
1189
1186
error ! ( "Error processing ACCEPT response in overlay service: {err}" )
1190
1187
}
1191
1188
}
1192
1189
}
1193
1190
}
1194
1191
1195
1192
/// Process ACCEPT response
1196
- pub async fn process_accept (
1193
+ pub fn process_accept (
1197
1194
& self ,
1198
1195
response : Accept ,
1199
1196
enr : Enr ,
@@ -1227,17 +1224,17 @@ where
1227
1224
self . utp_listener_tx
1228
1225
. send ( utp_request) . map_err ( |err| anyhow ! ( "Unable to send Connect request to UtpListener when processing ACCEPT message: {err}" ) ) ?;
1229
1226
1230
- let mut conn = rx. await ?;
1231
- // Handle STATE packet for SYN
1232
- let mut buf = [ 0 ; BUF_SIZE ] ;
1233
- conn. recv ( & mut buf) . await ?;
1234
-
1235
1227
let content_items = self . provide_requested_content ( & response, content_keys_offered) ?;
1236
1228
1237
1229
let content_payload = ContentPayloadList :: new ( content_items)
1238
1230
. map_err ( |err| anyhow ! ( "Unable to build content payload: {err:?}" ) ) ?;
1239
1231
1240
1232
tokio:: spawn ( async move {
1233
+ let mut conn = rx. await . unwrap ( ) ;
1234
+ // Handle STATE packet for SYN
1235
+ let mut buf = [ 0 ; BUF_SIZE ] ;
1236
+ conn. recv ( & mut buf) . await . unwrap ( ) ;
1237
+
1241
1238
// send the content to the acceptor over a uTP stream
1242
1239
if let Err ( err) = conn. send_to ( & content_payload. as_ssz_bytes ( ) ) . await {
1243
1240
warn ! ( "Error sending content {err}" ) ;
@@ -1297,7 +1294,7 @@ where
1297
1294
}
1298
1295
1299
1296
/// Processes a Content response.
1300
- async fn process_content (
1297
+ fn process_content (
1301
1298
& mut self ,
1302
1299
content : Content ,
1303
1300
source : Enr ,
@@ -1315,8 +1312,7 @@ where
1315
1312
self . protocol, id
1316
1313
) ,
1317
1314
Content :: Content ( content) => {
1318
- self . process_received_content ( content. clone ( ) , request)
1319
- . await ;
1315
+ self . process_received_content ( content. clone ( ) , request) ;
1320
1316
// TODO: Should we only advance the query if the content has been validated?
1321
1317
if let Some ( query_id) = query_id {
1322
1318
self . advance_find_content_query_with_content ( & query_id, source, content. into ( ) ) ;
@@ -1332,7 +1328,7 @@ where
1332
1328
}
1333
1329
}
1334
1330
1335
- async fn process_received_content ( & mut self , content : ByteList , request : FindContent ) {
1331
+ fn process_received_content ( & mut self , content : ByteList , request : FindContent ) {
1336
1332
let content_key = match TContentKey :: try_from ( request. content_key ) {
1337
1333
Ok ( val) => val,
1338
1334
Err ( msg) => {
@@ -1344,19 +1340,23 @@ where
1344
1340
match should_store {
1345
1341
Ok ( val) => {
1346
1342
if val {
1347
- // validate content before storing
1348
- if let Err ( err) = self
1349
- . validator
1350
- . validate_content ( & content_key, & content. to_vec ( ) )
1351
- . await
1352
- {
1353
- error ! ( "Unable to validate received content: {err:?}" ) ;
1354
- return ;
1355
- } ;
1343
+ let validator = Arc :: clone ( & self . validator ) ;
1344
+ let storage = Arc :: clone ( & self . storage ) ;
1345
+ // Spawn task that validates content before storing.
1346
+ // Allows for non-blocking requests to this/other overlay services.
1347
+ tokio:: spawn ( async move {
1348
+ let mut lock = validator. lock ( ) . await ;
1349
+ if let Err ( err) =
1350
+ lock. validate_content ( & content_key, & content. to_vec ( ) ) . await
1351
+ {
1352
+ error ! ( "Unable to validate received content: {err:?}" ) ;
1353
+ return ;
1354
+ } ;
1356
1355
1357
- if let Err ( err) = self . storage . write ( ) . store ( & content_key, & content. into ( ) ) {
1358
- error ! ( "Content received, but not stored: {err}" )
1359
- }
1356
+ if let Err ( err) = storage. write ( ) . store ( & content_key, & content. into ( ) ) {
1357
+ error ! ( "Content received, but not stored: {err}" )
1358
+ }
1359
+ } ) ;
1360
1360
} else {
1361
1361
debug ! (
1362
1362
"Content received, but not stored: Content is already stored or its distance falls outside current radius."
@@ -1993,7 +1993,7 @@ mod tests {
1993
1993
let ( request_tx, request_rx) = mpsc:: unbounded_channel ( ) ;
1994
1994
let ( response_tx, response_rx) = mpsc:: unbounded_channel ( ) ;
1995
1995
let metrics = None ;
1996
- let validator = MockValidator { } ;
1996
+ let validator = Arc :: new ( Mutex :: new ( MockValidator { } ) ) ;
1997
1997
1998
1998
let service = OverlayService {
1999
1999
discovery,
0 commit comments