@@ -5,13 +5,14 @@ use ic_interfaces::{
5
5
} ;
6
6
use ic_logger:: { trace, ReplicaLogger } ;
7
7
use ic_test_utilities:: types:: ids:: node_test_id;
8
- use ic_types:: time:: Time ;
8
+ use ic_types:: { artifact :: Priority , time:: Time } ;
9
9
use rand:: seq:: SliceRandom ;
10
10
use std:: time:: Duration ;
11
11
12
12
fn execute_instance < ' a , ' b > (
13
13
instance : & ' b ConsensusInstance < ' a > ,
14
14
time_source : & dyn TimeSource ,
15
+ use_priority_fn : bool ,
15
16
logger : & ReplicaLogger ,
16
17
) -> Option < Time > {
17
18
let mut in_queue = instance. in_queue . borrow_mut ( ) ;
@@ -33,6 +34,24 @@ fn execute_instance<'a, 'b>(
33
34
match inp {
34
35
Input :: Message ( x) => match x. message {
35
36
InputMessage :: Consensus ( msg) => {
37
+ if use_priority_fn {
38
+ match instance
39
+ . driver
40
+ . consensus_priority
41
+ . borrow ( )
42
+ . get_priority ( & msg)
43
+ {
44
+ Priority :: Drop => return Some ( timestamp) ,
45
+ Priority :: Stash | Priority :: Later => {
46
+ instance
47
+ . buffered
48
+ . borrow_mut ( )
49
+ . push ( InputMessage :: Consensus ( msg) ) ;
50
+ return Some ( timestamp) ;
51
+ }
52
+ Priority :: Fetch | Priority :: FetchNow => ( ) ,
53
+ } ;
54
+ }
36
55
let mut pool = instance. driver . consensus_pool . write ( ) . unwrap ( ) ;
37
56
pool. insert ( UnvalidatedArtifact {
38
57
message : msg,
@@ -58,9 +77,25 @@ fn execute_instance<'a, 'b>(
58
77
}
59
78
} ,
60
79
// Repeat the polling
61
- Input :: TimerExpired ( x) => in_queue. push ( Input :: TimerExpired (
62
- x + Duration :: from_millis ( POLLING_INTERVAL ) ,
63
- ) ) ,
80
+ Input :: TimerExpired ( x) => {
81
+ if use_priority_fn {
82
+ let mut priority = instance. driver . consensus_priority . borrow_mut ( ) ;
83
+ if priority. last_updated + PRIORITY_FN_REFRESH_INTERVAL < timestamp {
84
+ priority. refresh (
85
+ & instance. driver . consensus_gossip ,
86
+ & * instance. driver . consensus_pool . read ( ) . unwrap ( ) ,
87
+ timestamp,
88
+ ) ;
89
+ }
90
+ let mut buffered = instance. buffered . borrow_mut ( ) ;
91
+ for message in buffered. drain ( ..) {
92
+ in_queue. push ( Input :: Message ( Message { message, timestamp } ) ) ;
93
+ }
94
+ }
95
+ in_queue. push ( Input :: TimerExpired (
96
+ x + Duration :: from_millis ( POLLING_INTERVAL ) ,
97
+ ) ) ;
98
+ }
64
99
}
65
100
// Move new messages into out_queue.
66
101
for message in instance. driver . step ( time_source) {
@@ -76,11 +111,13 @@ fn execute_instance<'a, 'b>(
76
111
/// timestamp(min(i)) value globally. This ensures that all input messages are
77
112
/// always executed in order, for all nodes.
78
113
#[ derive( Debug ) ]
79
- pub struct GlobalMessage ;
114
+ pub struct GlobalMessage {
115
+ use_priority_fn : bool ,
116
+ }
80
117
81
118
impl GlobalMessage {
82
- pub fn new ( ) -> Box < GlobalMessage > {
83
- Box :: new ( GlobalMessage )
119
+ pub fn new ( use_priority_fn : bool ) -> Box < GlobalMessage > {
120
+ Box :: new ( GlobalMessage { use_priority_fn } )
84
121
}
85
122
}
86
123
@@ -95,16 +132,20 @@ impl ExecutionStrategy for GlobalMessage {
95
132
let t_j = j. in_queue . borrow ( ) . peek ( ) . map ( |x| x. timestamp ( ) ) ;
96
133
compare_timestamp ( t_i, t_j)
97
134
} )
98
- . and_then ( |instance| execute_instance ( instance, runner. time_source ( ) , logger) )
135
+ . and_then ( |instance| {
136
+ execute_instance ( instance, runner. time_source ( ) , self . use_priority_fn , logger)
137
+ } )
99
138
}
100
139
}
101
140
102
141
#[ derive( Debug ) ]
103
- pub struct RandomExecute ;
142
+ pub struct RandomExecute {
143
+ use_priority_fn : bool ,
144
+ }
104
145
105
146
impl RandomExecute {
106
- pub fn new ( ) -> Box < RandomExecute > {
107
- Box :: new ( RandomExecute )
147
+ pub fn new ( use_priority_fn : bool ) -> Box < RandomExecute > {
148
+ Box :: new ( RandomExecute { use_priority_fn } )
108
149
}
109
150
}
110
151
@@ -115,7 +156,8 @@ impl ExecutionStrategy for RandomExecute {
115
156
let mut rng = runner. rng ( ) ;
116
157
instances. shuffle ( & mut * rng) ;
117
158
while let Some ( instance) = instances. pop ( ) {
118
- let result = execute_instance ( instance, runner. time_source ( ) , logger) ;
159
+ let result =
160
+ execute_instance ( instance, runner. time_source ( ) , self . use_priority_fn , logger) ;
119
161
if result. is_some ( ) {
120
162
return result;
121
163
}
@@ -125,11 +167,13 @@ impl ExecutionStrategy for RandomExecute {
125
167
}
126
168
127
169
#[ derive( Debug ) ]
128
- pub struct GlobalClock ;
170
+ pub struct GlobalClock {
171
+ use_priority_fn : bool ,
172
+ }
129
173
130
174
impl GlobalClock {
131
- pub fn new ( ) -> Box < GlobalClock > {
132
- Box :: new ( GlobalClock )
175
+ pub fn new ( use_priority_fn : bool ) -> Box < GlobalClock > {
176
+ Box :: new ( GlobalClock { use_priority_fn } )
133
177
}
134
178
}
135
179
@@ -144,6 +188,8 @@ impl ExecutionStrategy for GlobalClock {
144
188
let t_j = j. in_queue . borrow ( ) . peek ( ) . map ( |_| * j. clock . borrow ( ) ) ;
145
189
compare_timestamp ( t_i, t_j)
146
190
} )
147
- . and_then ( |instance| execute_instance ( instance, runner. time_source ( ) , logger) )
191
+ . and_then ( |instance| {
192
+ execute_instance ( instance, runner. time_source ( ) , self . use_priority_fn , logger)
193
+ } )
148
194
}
149
195
}
0 commit comments