@@ -2,11 +2,17 @@ use std::collections::VecDeque;
2
2
3
3
use openmina_core:: { bug_condition, fuzz_maybe, fuzzed_maybe, Substate , SubstateAccess } ;
4
4
5
- use crate :: P2pLimits ;
6
-
7
- use self :: p2p_network_yamux_state:: { YamuxFlags , YamuxFrame , YamuxFrameInner , YamuxStreamState } ;
8
-
9
- use super :: { super :: * , * } ;
5
+ use crate :: {
6
+ yamux:: p2p_network_yamux_state:: { YamuxFrame , YamuxFrameInner } ,
7
+ Data , Limit , P2pLimits , P2pNetworkAuthState , P2pNetworkConnectionError ,
8
+ P2pNetworkConnectionMuxState , P2pNetworkNoiseAction , P2pNetworkSchedulerAction ,
9
+ P2pNetworkSchedulerState , P2pNetworkSelectAction , P2pNetworkStreamState , SelectKind ,
10
+ } ;
11
+
12
+ use super :: {
13
+ p2p_network_yamux_state:: { YamuxStreamState , MAX_WINDOW_SIZE } ,
14
+ P2pNetworkYamuxAction , P2pNetworkYamuxState , YamuxFlags , YamuxPing ,
15
+ } ;
10
16
11
17
impl P2pNetworkYamuxState {
12
18
/// Handles the main reducer logic for Yamux protocol actions. It processes incoming and outgoing
@@ -130,12 +136,12 @@ impl P2pNetworkYamuxState {
130
136
}
131
137
132
138
match & frame. inner {
133
- YamuxFrameInner :: Data ( data ) => {
139
+ YamuxFrameInner :: Data ( _ ) => {
134
140
if let Some ( stream) = yamux_state. streams . get_mut ( & frame. stream_id ) {
135
141
// must not underflow
136
142
// TODO: check it and disconnect peer that violates flow rules
137
143
stream. window_ours =
138
- stream. window_ours . saturating_sub ( data . len ( ) as u32 ) ;
144
+ stream. window_ours . saturating_sub ( frame . len_as_u32 ( ) ) ;
139
145
}
140
146
}
141
147
YamuxFrameInner :: WindowUpdate { difference } => {
@@ -150,18 +156,12 @@ impl P2pNetworkYamuxState {
150
156
// have some fresh space in the window
151
157
// try send as many frames as can
152
158
let mut window = stream. window_theirs ;
153
- while let Some ( mut frame) = stream. pending . pop_front ( ) {
154
- let len = frame. len ( ) as u32 ;
159
+ while let Some ( frame) = stream. pending . pop_front ( ) {
160
+ let len = frame. len_as_u32 ( ) ;
161
+ pending_outgoing. push_back ( frame) ;
155
162
if let Some ( new_window) = window. checked_sub ( len) {
156
- pending_outgoing. push_back ( frame) ;
157
163
window = new_window;
158
164
} else {
159
- if let Some ( remaining) = frame. split_at ( ( len - window) as usize )
160
- {
161
- stream. pending . push_front ( remaining) ;
162
- }
163
- pending_outgoing. push_back ( frame) ;
164
-
165
165
break ;
166
166
}
167
167
}
@@ -231,11 +231,11 @@ impl P2pNetworkYamuxState {
231
231
}
232
232
match & frame. inner {
233
233
YamuxFrameInner :: Data ( data) => {
234
- // here we are very permissive
235
- // always when our window is smaller 64 kb, just increase it by 256 kb
236
- // if we need fine grained back pressure, it should be implemented here
237
- if stream . window_ours < 64 * 1024 {
238
- let difference = 256 * 1024 ;
234
+ // when our window size is less than half of the max window size send window update
235
+ if stream . window_ours < stream . max_window_size / 2 {
236
+ let difference =
237
+ stream . max_window_size . saturating_mul ( 2 ) . min ( 1024 * 1024 ) ;
238
+
239
239
dispatcher. push ( P2pNetworkYamuxAction :: OutgoingFrame {
240
240
addr,
241
241
frame : YamuxFrame {
@@ -285,48 +285,39 @@ impl P2pNetworkYamuxState {
285
285
return Ok ( ( ) ) ;
286
286
} ;
287
287
match & mut frame. inner {
288
- YamuxFrameInner :: Data ( data) => {
289
- stream. window_theirs = stream
290
- . window_theirs
291
- . checked_sub ( data. len ( ) as u32 )
292
- . unwrap_or_default ( ) ;
293
-
294
- // TODO: code bellow include splitting the frame so that data which doesn't fit inside the window doesn't get sent, this breaks the bootstrap to rust
295
-
296
- // if let Some(new_window) =
297
- // stream.window_theirs.checked_sub(data.len() as u32)
298
- // {
299
- // // their window is big enough, decrease the size
300
- // // and send the whole frame
301
- // stream.window_theirs = new_window;
302
- // } else if stream.window_theirs != 0 && stream.pending.is_empty() {
303
- // // their window is not big enough, but has some space,
304
- // // and the queue is empty,
305
- // // do not send the whole frame,
306
- // // split it and put remaining in the queue,
307
- // if let Some(remaining) = frame.split_at(stream.window_theirs as usize) {
308
- // stream.pending.push_back(remaining);
309
- // }
310
- // // the window will be zero after sending
311
- // stream.window_theirs = 0;
312
- // } else {
313
- // // either the window cannot accept any byte,
314
- // // or the queue is already not empty
315
- // // in both cases the whole frame goes in the queue and nothing to send
316
- // stream.pending.push_back(frame);
317
- // if stream.pending.iter().map(YamuxFrame::len).sum::<usize>()
318
- // > yamux_state.pending_outgoing_limit
319
- // {
320
- // let dispatcher = state_context.into_dispatcher();
321
- // let error = P2pNetworkConnectionError::YamuxOverflow(stream_id);
322
- // dispatcher.push(P2pNetworkSchedulerAction::Error { addr, error });
323
- // }
324
-
325
- // return Ok(());
326
- // }
288
+ YamuxFrameInner :: Data ( _) => {
289
+ if let Some ( new_window) =
290
+ stream. window_theirs . checked_sub ( frame. len_as_u32 ( ) )
291
+ {
292
+ // their window is big enough, decrease the size
293
+ // and send the whole frame
294
+ stream. window_theirs = new_window;
295
+ } else {
296
+ // their window is not big enough
297
+ // split the frame to send as much as you can and put the rest in the queue
298
+ if let Some ( remaining) = frame. split_at ( stream. window_theirs as usize ) {
299
+ stream. pending . push_front ( remaining) ;
300
+ }
301
+
302
+ // the window will be zero after sending
303
+ stream. window_theirs = 0 ;
304
+
305
+ // if size of pending that is above the limit, ignore the peer
306
+ if stream. pending . iter ( ) . map ( YamuxFrame :: len) . sum :: < usize > ( )
307
+ > yamux_state. pending_outgoing_limit
308
+ {
309
+ let dispatcher = state_context. into_dispatcher ( ) ;
310
+ let error = P2pNetworkConnectionError :: YamuxOverflow ( stream_id) ;
311
+ dispatcher. push ( P2pNetworkSchedulerAction :: Error { addr, error } ) ;
312
+ return Ok ( ( ) ) ;
313
+ }
314
+ }
327
315
}
328
316
YamuxFrameInner :: WindowUpdate { difference } => {
329
317
stream. window_ours = stream. window_ours . saturating_add ( * difference) ;
318
+ if stream. window_ours > stream. max_window_size {
319
+ stream. max_window_size = stream. window_ours . min ( MAX_WINDOW_SIZE ) ;
320
+ }
330
321
}
331
322
_ => { }
332
323
}
0 commit comments