1
+ use crate :: units:: TestingDagUnit ;
1
2
use crate :: {
2
3
creation:: Creator as GenericCreator ,
3
4
dag:: ReconstructedUnit ,
@@ -9,6 +10,7 @@ use crate::{
9
10
NodeCount , NodeIndex , NodeMap , Round , SessionId , Signed ,
10
11
} ;
11
12
use aleph_bft_mock:: { Data , Hash64 , Hasher64 , Keychain , Signature } ;
13
+ use rand:: prelude:: IteratorRandom ;
12
14
13
15
type ControlHash = GenericControlHash < Hasher64 > ;
14
16
type Creator = GenericCreator < Hasher64 > ;
@@ -149,10 +151,10 @@ fn parent_map<U: Unit<Hasher = Hasher64>>(parents: &Vec<U>) -> NodeMap<Hash64> {
149
151
pub fn random_unit_with_parents < U : Unit < Hasher = Hasher64 > > (
150
152
creator : NodeIndex ,
151
153
parents : & Vec < U > ,
154
+ round : Round ,
152
155
) -> FullUnit {
153
156
let representative_parent = parents. last ( ) . expect ( "there are parents" ) ;
154
157
let session_id = representative_parent. session_id ( ) ;
155
- let round = representative_parent. round ( ) + 1 ;
156
158
let parent_map = parent_map ( parents) ;
157
159
let control_hash = ControlHash :: new ( & parent_map) ;
158
160
preunit_to_full_unit ( PreUnit :: new ( creator, round, control_hash) , session_id)
@@ -162,9 +164,10 @@ pub fn random_reconstructed_unit_with_parents<U: Unit<Hasher = Hasher64>>(
162
164
creator : NodeIndex ,
163
165
parents : & Vec < U > ,
164
166
keychain : & Keychain ,
167
+ round : Round ,
165
168
) -> DagUnit {
166
169
ReconstructedUnit :: with_parents (
167
- full_unit_to_signed_unit ( random_unit_with_parents ( creator, parents) , keychain) ,
170
+ full_unit_to_signed_unit ( random_unit_with_parents ( creator, parents, round ) , keychain) ,
168
171
parent_map ( parents) ,
169
172
)
170
173
. expect ( "correct parents" )
@@ -176,18 +179,20 @@ pub fn random_full_parent_units_up_to(
176
179
session_id : SessionId ,
177
180
) -> Vec < Vec < FullUnit > > {
178
181
let mut result = vec ! [ random_initial_units( n_members, session_id) ] ;
179
- for _ in 0 .. round {
182
+ for r in 1 ..= round {
180
183
let units = n_members
181
184
. into_iterator ( )
182
185
. map ( |node_id| {
183
- random_unit_with_parents ( node_id, result. last ( ) . expect ( "previous round present" ) )
186
+ random_unit_with_parents ( node_id, result. last ( ) . expect ( "previous round present" ) , r )
184
187
} )
185
188
. collect ( ) ;
186
189
result. push ( units) ;
187
190
}
188
191
result
189
192
}
190
193
194
+ /// Constructs a DAG so that in each round (except round 0) it has all N parents, where N is number
195
+ /// of nodes in the DAG
191
196
pub fn random_full_parent_reconstrusted_units_up_to (
192
197
round : Round ,
193
198
n_members : NodeCount ,
@@ -197,18 +202,70 @@ pub fn random_full_parent_reconstrusted_units_up_to(
197
202
let mut result = vec ! [ random_initial_reconstructed_units(
198
203
n_members, session_id, keychains,
199
204
) ] ;
200
- for _ in 0 .. round {
205
+ for r in 1 ..= round {
201
206
let units = n_members
202
207
. into_iterator ( )
203
208
. map ( |node_id| {
204
209
random_reconstructed_unit_with_parents (
205
210
node_id,
206
211
result. last ( ) . expect ( "previous round present" ) ,
207
212
& keychains[ node_id. 0 ] ,
213
+ r,
208
214
)
209
215
} )
210
216
. collect ( ) ;
211
217
result. push ( units) ;
212
218
}
213
219
result
214
220
}
221
+
222
+ /// Constructs a DAG so that in each round (except round 0) it has at least 2N/3 + 1 parents, where
223
+ /// N is number of nodes in the DAG. At least one node from N/3 group has some non-direct parents.
224
+ pub fn minimal_reconstructed_dag_units_up_to (
225
+ round : Round ,
226
+ n_members : NodeCount ,
227
+ session_id : SessionId ,
228
+ keychains : & [ Keychain ] ,
229
+ ) -> ( Vec < Vec < DagUnit > > , DagUnit ) {
230
+ let mut rng = rand:: thread_rng ( ) ;
231
+ let threshold = n_members. consensus_threshold ( ) . 0 ;
232
+
233
+ let mut dag = vec ! [ random_initial_reconstructed_units(
234
+ n_members, session_id, keychains,
235
+ ) ] ;
236
+ let inactive_node_first_and_last_seen_unit = dag
237
+ . last ( )
238
+ . expect ( "previous round present" )
239
+ . last ( )
240
+ . expect ( "there is at least one node" )
241
+ . clone ( ) ;
242
+ let inactive_node = inactive_node_first_and_last_seen_unit. creator ( ) ;
243
+ for r in 1 ..=round {
244
+ let mut parents: Vec < TestingDagUnit > = dag
245
+ . last ( )
246
+ . expect ( "previous round present" )
247
+ . clone ( )
248
+ . into_iter ( )
249
+ . filter ( |unit| unit. creator ( ) != inactive_node)
250
+ . choose_multiple ( & mut rng, threshold)
251
+ . into_iter ( )
252
+ . collect ( ) ;
253
+ if r == round {
254
+ let ancestor_unit = dag
255
+ . first ( )
256
+ . expect ( "first round present" )
257
+ . get ( inactive_node. 0 )
258
+ . expect ( "inactive node unit present" ) ;
259
+ parents. push ( ancestor_unit. clone ( ) ) ;
260
+ }
261
+ let units = n_members
262
+ . into_iterator ( )
263
+ . filter ( |node_id| node_id != & inactive_node)
264
+ . map ( |node_id| {
265
+ random_reconstructed_unit_with_parents ( node_id, & parents, & keychains[ node_id. 0 ] , r)
266
+ } )
267
+ . collect ( ) ;
268
+ dag. push ( units) ;
269
+ }
270
+ ( dag, inactive_node_first_and_last_seen_unit)
271
+ }
0 commit comments