Skip to content

Commit 7588dad

Browse files
authored
Update fragment generator (#4105)
* add update proposal and update vote fragments * fix tests * fix test * fix consensus version * fix fmt * fix block test
1 parent fd29e9f commit 7588dad

File tree

6 files changed

+144
-6
lines changed

6 files changed

+144
-6
lines changed

testing/jormungandr-integration-tests/src/jormungandr/explorer/block.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,13 @@ pub fn explorer_block_test() {
7272
let mut fragment_generator = FragmentGenerator::new(
7373
sender,
7474
receiver,
75+
None,
7576
jormungandr.to_remote(),
7677
time_era.slots_per_epoch(),
7778
2,
7879
2,
7980
2,
81+
0,
8082
fragment_sender,
8183
);
8284

testing/jormungandr-integration-tests/src/jormungandr/fragments.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,13 @@ pub fn send_all_fragments() {
5858
let mut fragment_generator = FragmentGenerator::new(
5959
sender,
6060
receiver,
61+
None,
6162
jormungandr.to_remote(),
6263
time_era.slots_per_epoch(),
6364
2,
6465
2,
6566
2,
67+
0,
6668
fragment_sender,
6769
);
6870

testing/jormungandr-integration-tests/src/jormungandr/mempool.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use assert_fs::{
44
TempDir,
55
};
66
use chain_core::property::{FromStr, Serialize};
7+
use chain_crypto::Ed25519;
78
use chain_impl_mockchain::{
89
block::BlockDate,
910
chaintypes::ConsensusVersion,
@@ -16,7 +17,7 @@ use hersir::{
1617
};
1718
use jormungandr_automation::{
1819
jormungandr::{ConfigurationBuilder, FragmentNode, LeadershipMode, MemPoolCheck, Starter},
19-
testing::time,
20+
testing::{keys::create_new_key_pair, time},
2021
};
2122
use jormungandr_lib::interfaces::{
2223
BlockDate as BlockDateDto, InitialToken, InitialUTxO, Mempool, PersistentLog, SlotDuration,
@@ -36,13 +37,15 @@ pub fn dump_send_correct_fragments() {
3637
let persistent_log_path = temp_dir.child("persistent_log");
3738
let receiver = thor::Wallet::default();
3839
let sender = thor::Wallet::default();
40+
let first_bft_leader = create_new_key_pair::<Ed25519>();
3941

4042
let jormungandr = startup::start_bft(
4143
vec![&sender, &receiver],
4244
ConfigurationBuilder::new()
4345
.with_slots_per_epoch(60)
4446
.with_block_content_max_size(100000.into())
4547
.with_slot_duration(1)
48+
.with_consensus_leaders_ids(vec![first_bft_leader.identifier().into()])
4649
.with_mempool(Mempool {
4750
pool_max_entries: 1_000_000usize.into(),
4851
log_max_entries: 1_000_000usize.into(),
@@ -72,11 +75,13 @@ pub fn dump_send_correct_fragments() {
7275
let mut fragment_generator = FragmentGenerator::new(
7376
sender,
7477
receiver,
78+
Some(first_bft_leader),
7579
jormungandr.to_remote(),
7680
time_era.slots_per_epoch(),
7781
2,
7882
2,
7983
2,
84+
2,
8085
fragment_sender,
8186
);
8287

testing/jormungandr-integration-tests/src/non_functional/fragment.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,13 @@ pub fn fragment_load_test() {
5050
let mut request_generator = FragmentGenerator::new(
5151
faucet,
5252
receiver,
53+
None,
5354
jormungandr.to_remote(),
5455
60,
5556
30,
5657
30,
5758
30,
59+
0,
5860
FragmentSender::new(
5961
jormungandr.genesis_block_hash(),
6062
jormungandr.fees(),

testing/mjolnir/src/mjolnir_lib/fragment/standard/all.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@ use crate::{
33
mjolnir_lib::{args::parse_shift, build_monitor, MjolnirError},
44
};
55
use chain_addr::Discrimination;
6+
use chain_crypto::Ed25519;
67
use chain_impl_mockchain::block::BlockDate;
7-
use jormungandr_automation::{jormungandr::RemoteJormungandrBuilder, testing::time};
8+
use jormungandr_automation::{
9+
jormungandr::RemoteJormungandrBuilder,
10+
testing::{keys::create_new_key_pair, time},
11+
};
812
use jormungandr_lib::crypto::hash::Hash;
913
use jortestkit::{
1014
load::ConfigurationBuilder,
@@ -103,14 +107,18 @@ impl AllFragments {
103107
FragmentSenderSetup::no_verify(),
104108
);
105109

110+
let bft_secret_alice = create_new_key_pair::<Ed25519>();
111+
106112
let mut generator = FragmentGenerator::new(
107113
faucet,
108114
receiver,
115+
Some(bft_secret_alice),
109116
remote_jormungandr,
110117
settings.slots_per_epoch,
111118
30,
112119
30,
113120
30,
121+
30,
114122
fragment_sender,
115123
);
116124

testing/mjolnir/src/mjolnir_lib/generators/fragment_generator.rs

Lines changed: 123 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
use chain_core::property::FromStr;
2+
use chain_crypto::Ed25519;
23
use chain_impl_mockchain::{
3-
certificate::{VotePlan, VoteTallyPayload},
4+
certificate::{UpdateProposal, UpdateVote, VotePlan, VoteTallyPayload},
5+
chaintypes::ConsensusVersion,
6+
fragment::FragmentId,
47
vote::Choice,
58
};
69
use chain_time::TimeEra;
710
use 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+
};
1218
use jortestkit::load::{Request, RequestFailure, RequestGenerator};
1319
use rand::RngCore;
1420
use 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

3949
impl<'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

Comments
 (0)