11use chain_core:: property:: FromStr ;
2+ use chain_crypto:: Ed25519 ;
23use chain_impl_mockchain:: {
3- certificate:: { VotePlan , VoteTallyPayload } ,
4+ certificate:: { UpdateProposal , UpdateVote , VotePlan , VoteTallyPayload } ,
5+ chaintypes:: ConsensusVersion ,
6+ fragment:: FragmentId ,
47 vote:: Choice ,
58} ;
69use chain_time:: TimeEra ;
710use jormungandr_automation:: {
811 jormungandr:: { MemPoolCheck , RemoteJormungandr } ,
912 testing:: { SyncNode , VoteCastCounter , VotePlanBuilder } ,
1013} ;
11- use jormungandr_lib:: { crypto:: hash:: Hash , interfaces:: BlockDate as BlockDateDto } ;
14+ use jormungandr_lib:: {
15+ crypto:: { hash:: Hash , key:: KeyPair } ,
16+ interfaces:: { BlockContentMaxSize , BlockDate as BlockDateDto , ConfigParam , ConfigParams } ,
17+ } ;
1218use jortestkit:: load:: { Request , RequestFailure , RequestGenerator } ;
1319use rand:: RngCore ;
1420use rand_core:: OsRng ;
@@ -26,6 +32,8 @@ pub struct FragmentGenerator<'a, S: SyncNode + Send> {
2632 active_stake_pools : Vec < StakePool > ,
2733 vote_plans_for_casting : Vec < VotePlan > ,
2834 vote_plans_for_tally : Vec < VotePlan > ,
35+ update_proposals_for_casting : Vec < FragmentId > ,
36+ bft_leader : Option < KeyPair < Ed25519 > > ,
2937 node : RemoteJormungandr ,
3038 rand : OsRng ,
3139 vote_cast_register : Option < VoteCastCounter > ,
@@ -34,30 +42,39 @@ pub struct FragmentGenerator<'a, S: SyncNode + Send> {
3442 stake_pools_count : usize ,
3543 vote_plans_for_tally_count : usize ,
3644 vote_plans_for_casting_count : usize ,
45+ update_proposals_for_casting_count : usize ,
46+ fragment_options_count : usize ,
3747}
3848
3949impl < ' a , S : SyncNode + Send > FragmentGenerator < ' a , S > {
4050 #[ allow( clippy:: too_many_arguments) ]
4151 pub fn new (
4252 sender : Wallet ,
4353 receiver : Wallet ,
54+ bft_leader : Option < KeyPair < Ed25519 > > ,
4455 node : RemoteJormungandr ,
4556 slots_per_epoch : u32 ,
4657 stake_pools_count : usize ,
4758 vote_plans_for_tally_count : usize ,
4859 vote_plans_for_casting_count : usize ,
60+ update_proposals_for_casting_count : usize ,
4961 fragment_sender : FragmentSender < ' a , S > ,
5062 ) -> Self {
5163 assert ! ( vote_plans_for_casting_count > 1 ) ;
5264 assert ! ( stake_pools_count > 1 ) ;
5365 assert ! ( vote_plans_for_tally_count > 1 ) ;
66+ if bft_leader. is_some ( ) {
67+ assert ! ( update_proposals_for_casting_count > 1 ) ;
68+ }
5469
5570 Self {
5671 sender,
5772 receiver,
5873 active_stake_pools : vec ! [ ] ,
5974 vote_plans_for_casting : vec ! [ ] ,
6075 vote_plans_for_tally : vec ! [ ] ,
76+ update_proposals_for_casting : vec ! [ ] ,
77+ bft_leader,
6178 node,
6279 vote_cast_register : None ,
6380 rand : OsRng ,
@@ -66,6 +83,8 @@ impl<'a, S: SyncNode + Send> FragmentGenerator<'a, S> {
6683 stake_pools_count,
6784 vote_plans_for_tally_count,
6885 vote_plans_for_casting_count,
86+ update_proposals_for_casting_count,
87+ fragment_options_count : 0 ,
6988 }
7089 }
7190
@@ -79,6 +98,56 @@ impl<'a, S: SyncNode + Send> FragmentGenerator<'a, S> {
7998 let settings = self . node . rest ( ) . settings ( ) . unwrap ( ) ;
8099 let block0_hash = Hash :: from_str ( & settings. block0_hash ) . unwrap ( ) ;
81100 let fees = settings. fees ;
101+ if settings. consensus_version == ConsensusVersion :: Bft . to_string ( ) {
102+ assert ! (
103+ self . bft_leader. is_some( ) ,
104+ "Consensus version bft, bft leader needed"
105+ ) ;
106+ self . fragment_options_count = 12 ;
107+
108+ let update_proposals: Vec < UpdateProposal > = iter:: from_fn ( || {
109+ Some ( UpdateProposal :: new (
110+ ConfigParams :: new ( vec ! [ ConfigParam :: BlockContentMaxSize (
111+ BlockContentMaxSize :: from( self . rand. next_u32( ) ) ,
112+ ) ] )
113+ . into ( ) ,
114+ self . bft_leader
115+ . as_ref ( )
116+ . unwrap ( )
117+ . identifier ( )
118+ . into_public_key ( )
119+ . into ( ) ,
120+ ) )
121+ } )
122+ . take ( self . update_proposals_for_casting_count )
123+ . collect ( ) ;
124+
125+ for update_proposal in update_proposals {
126+ fragments. push (
127+ FragmentBuilder :: new ( & block0_hash, & fees, self . fragment_sender . date ( ) )
128+ . update_proposal (
129+ & self . sender ,
130+ update_proposal,
131+ & self
132+ . bft_leader
133+ . as_ref ( )
134+ . unwrap ( )
135+ . signing_key ( )
136+ . into_secret_key ( ) ,
137+ ) ,
138+ ) ;
139+ self . sender . confirm_transaction ( ) ;
140+ }
141+ self . update_proposals_for_casting = fragments. iter ( ) . map ( |f| f. hash ( ) ) . collect ( ) ;
142+ }
143+
144+ if settings. consensus_version == ConsensusVersion :: GenesisPraos . to_string ( ) {
145+ assert ! (
146+ self . bft_leader. is_none( ) ,
147+ "Consesus version genesis praos, bft leader will be ignored"
148+ ) ;
149+ self . fragment_options_count = 10 ;
150+ }
82151
83152 let stake_pools: Vec < StakePool > = iter:: from_fn ( || Some ( StakePool :: new ( & self . sender ) ) )
84153 . take ( self . stake_pools_count )
@@ -116,6 +185,7 @@ impl<'a, S: SyncNode + Send> FragmentGenerator<'a, S> {
116185 ) ;
117186 self . sender . confirm_transaction ( ) ;
118187 }
188+
119189 for vote_plan_for_casting in & votes_plan_for_casting {
120190 fragments. push (
121191 FragmentBuilder :: new ( & block0_hash, & fees, self . fragment_sender . date ( ) )
@@ -155,14 +225,15 @@ impl<'a, S: SyncNode + Send> FragmentGenerator<'a, S> {
155225
156226 pub fn send_all ( & mut self ) -> Result < Vec < MemPoolCheck > , FragmentSenderError > {
157227 let mut checks = Vec :: new ( ) ;
158- for i in 0 ..10 {
228+
229+ for i in 0 ..self . fragment_options_count {
159230 checks. push ( self . send_one ( i as u8 ) ?) ;
160231 }
161232 Ok ( checks)
162233 }
163234
164235 pub fn send_one ( & mut self , option : u8 ) -> Result < MemPoolCheck , FragmentSenderError > {
165- match option % 10 {
236+ match option % self . fragment_options_count as u8 {
166237 0 => self . fragment_sender . send_transaction (
167238 & mut self . sender ,
168239 & self . receiver ,
@@ -280,6 +351,54 @@ impl<'a, S: SyncNode + Send> FragmentGenerator<'a, S> {
280351 VoteTallyPayload :: Public ,
281352 )
282353 }
354+ 10 => {
355+ let change_params = ConfigParams :: new ( vec ! [ ConfigParam :: BlockContentMaxSize (
356+ BlockContentMaxSize :: from( self . rand. next_u32( ) ) ,
357+ ) ] ) ;
358+
359+ let update_proposal = UpdateProposal :: new (
360+ change_params. into ( ) ,
361+ self . bft_leader
362+ . as_ref ( )
363+ . unwrap ( )
364+ . identifier ( )
365+ . into_public_key ( )
366+ . into ( ) ,
367+ ) ;
368+
369+ self . fragment_sender . send_update_proposal (
370+ & mut self . sender ,
371+ & self . bft_leader . as_ref ( ) . unwrap ( ) . signing_key ( ) . into ( ) ,
372+ update_proposal,
373+ & self . node ,
374+ )
375+ }
376+ 11 => {
377+ let index = self . rand . next_u32 ( ) as usize % self . update_proposals_for_casting . len ( ) ;
378+ let update_proposal = self . update_proposals_for_casting . get ( index) . unwrap ( ) ;
379+
380+ let update_vote = UpdateVote :: new (
381+ * update_proposal,
382+ self . bft_leader
383+ . as_ref ( )
384+ . unwrap ( )
385+ . identifier ( )
386+ . into_public_key ( )
387+ . into ( ) ,
388+ ) ;
389+
390+ self . fragment_sender . send_update_vote (
391+ & mut self . sender ,
392+ & self
393+ . bft_leader
394+ . as_ref ( )
395+ . unwrap ( )
396+ . signing_key ( )
397+ . into_secret_key ( ) ,
398+ update_vote,
399+ & self . node ,
400+ )
401+ }
283402 _ => unreachable ! ( ) ,
284403 }
285404 }
0 commit comments