11use std:: {
2- collections:: { BTreeMap , BTreeSet , BinaryHeap , HashMap , HashSet } ,
2+ cmp:: Reverse ,
3+ collections:: { BTreeMap , BTreeSet , BinaryHeap , HashMap , HashSet , VecDeque } ,
4+ hash:: Hash ,
35 sync:: Arc ,
46 time:: Duration ,
57} ;
@@ -14,7 +16,7 @@ use tracing::{info, trace};
1416
1517use crate :: {
1618 clock:: { ClockBarrier , FutureEvent , Timestamp } ,
17- config:: { NodeConfiguration , NodeId , RelayStrategy , SimConfiguration } ,
19+ config:: { DiffusionStrategy , NodeConfiguration , NodeId , RelayStrategy , SimConfiguration } ,
1820 events:: EventTracker ,
1921 model:: {
2022 Block , CpuTaskId , Endorsement , EndorserBlock , EndorserBlockId , InputBlock ,
@@ -166,11 +168,59 @@ enum VoteBundleState {
166168 Received ( Arc < VoteBundle > ) ,
167169}
168170
169- #[ derive( Default ) ]
170171struct PeerInputBlockRequests {
171- pending : PriorityQueue < InputBlockId , Timestamp > ,
172+ pending : PendingQueue < InputBlockId > ,
172173 active : HashSet < InputBlockId > ,
173174}
175+ enum PendingQueue < T : Hash + Eq > {
176+ PeerOrder ( VecDeque < T > ) ,
177+ FreshestFirst ( PriorityQueue < T , Timestamp > ) ,
178+ OldestFirst ( PriorityQueue < T , Reverse < Timestamp > > ) ,
179+ }
180+ impl < T : Hash + Eq > PendingQueue < T > {
181+ fn new ( strategy : DiffusionStrategy ) -> Self {
182+ match strategy {
183+ DiffusionStrategy :: PeerOrder => Self :: PeerOrder ( VecDeque :: new ( ) ) ,
184+ DiffusionStrategy :: FreshestFirst => Self :: FreshestFirst ( PriorityQueue :: new ( ) ) ,
185+ DiffusionStrategy :: OldestFirst => Self :: OldestFirst ( PriorityQueue :: new ( ) ) ,
186+ }
187+ }
188+ fn push ( & mut self , value : T , timestamp : Timestamp ) {
189+ match self {
190+ Self :: PeerOrder ( queue) => queue. push_back ( value) ,
191+ Self :: FreshestFirst ( queue) => {
192+ queue. push ( value, timestamp) ;
193+ }
194+ Self :: OldestFirst ( queue) => {
195+ queue. push ( value, Reverse ( timestamp) ) ;
196+ }
197+ }
198+ }
199+ fn pop ( & mut self ) -> Option < T > {
200+ match self {
201+ Self :: PeerOrder ( queue) => queue. pop_back ( ) ,
202+ Self :: FreshestFirst ( queue) => queue. pop ( ) . map ( |( value, _) | value) ,
203+ Self :: OldestFirst ( queue) => queue. pop ( ) . map ( |( value, _) | value) ,
204+ }
205+ }
206+ }
207+
208+ impl PeerInputBlockRequests {
209+ fn new ( config : & SimConfiguration ) -> Self {
210+ Self {
211+ pending : PendingQueue :: new ( config. ib_diffusion_strategy ) ,
212+ active : HashSet :: new ( ) ,
213+ }
214+ }
215+
216+ fn queue ( & mut self , id : InputBlockId , timestamp : Timestamp ) {
217+ self . pending . push ( id, timestamp) ;
218+ }
219+
220+ fn next ( & mut self ) -> Option < InputBlockId > {
221+ self . pending . pop ( )
222+ }
223+ }
174224
175225impl Node {
176226 #[ allow( clippy:: too_many_arguments) ]
@@ -873,7 +923,11 @@ impl Node {
873923 _ => return Ok ( ( ) ) ,
874924 } ;
875925 // Do we have capacity to request this block?
876- let reqs = self . leios . ib_requests . entry ( from) . or_default ( ) ;
926+ let reqs = self
927+ . leios
928+ . ib_requests
929+ . entry ( from)
930+ . or_insert ( PeerInputBlockRequests :: new ( & self . sim_config ) ) ;
877931 if reqs. active . len ( ) < self . sim_config . max_ib_requests_per_peer {
878932 // If so, make the request
879933 self . leios
@@ -883,7 +937,7 @@ impl Node {
883937 self . send_to ( from, SimulationMessage :: RequestIB ( id) ) ?;
884938 } else {
885939 // If not, just track that this peer has this IB when we're ready
886- reqs. pending . push ( id, header. timestamp ) ;
940+ reqs. queue ( id, header. timestamp ) ;
887941 }
888942 Ok ( ( ) )
889943 }
@@ -926,11 +980,15 @@ impl Node {
926980 }
927981
928982 // Mark that this IB is no longer pending
929- let reqs = self . leios . ib_requests . entry ( from) . or_default ( ) ;
983+ let reqs = self
984+ . leios
985+ . ib_requests
986+ . entry ( from)
987+ . or_insert ( PeerInputBlockRequests :: new ( & self . sim_config ) ) ;
930988 reqs. active . remove ( & id) ;
931989
932990 // We now have capacity to request one more IB from this peer
933- while let Some ( ( id , _ ) ) = reqs. pending . pop ( ) {
991+ while let Some ( id ) = reqs. next ( ) {
934992 let header = match self . leios . ibs . get ( & id) {
935993 Some ( InputBlockState :: Pending ( header) ) => header,
936994 Some ( InputBlockState :: Requested ( header) )
0 commit comments