Skip to content

Commit

Permalink
Update fragment generator (#4105)
Browse files Browse the repository at this point in the history
* add update proposal and update vote fragments

* fix tests

* fix test

* fix consensus version

* fix fmt

* fix block test
  • Loading branch information
kukkok3 authored Sep 30, 2022
1 parent fd29e9f commit 7588dad
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,13 @@ pub fn explorer_block_test() {
let mut fragment_generator = FragmentGenerator::new(
sender,
receiver,
None,
jormungandr.to_remote(),
time_era.slots_per_epoch(),
2,
2,
2,
0,
fragment_sender,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ pub fn send_all_fragments() {
let mut fragment_generator = FragmentGenerator::new(
sender,
receiver,
None,
jormungandr.to_remote(),
time_era.slots_per_epoch(),
2,
2,
2,
0,
fragment_sender,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use assert_fs::{
TempDir,
};
use chain_core::property::{FromStr, Serialize};
use chain_crypto::Ed25519;
use chain_impl_mockchain::{
block::BlockDate,
chaintypes::ConsensusVersion,
Expand All @@ -16,7 +17,7 @@ use hersir::{
};
use jormungandr_automation::{
jormungandr::{ConfigurationBuilder, FragmentNode, LeadershipMode, MemPoolCheck, Starter},
testing::time,
testing::{keys::create_new_key_pair, time},
};
use jormungandr_lib::interfaces::{
BlockDate as BlockDateDto, InitialToken, InitialUTxO, Mempool, PersistentLog, SlotDuration,
Expand All @@ -36,13 +37,15 @@ pub fn dump_send_correct_fragments() {
let persistent_log_path = temp_dir.child("persistent_log");
let receiver = thor::Wallet::default();
let sender = thor::Wallet::default();
let first_bft_leader = create_new_key_pair::<Ed25519>();

let jormungandr = startup::start_bft(
vec![&sender, &receiver],
ConfigurationBuilder::new()
.with_slots_per_epoch(60)
.with_block_content_max_size(100000.into())
.with_slot_duration(1)
.with_consensus_leaders_ids(vec![first_bft_leader.identifier().into()])
.with_mempool(Mempool {
pool_max_entries: 1_000_000usize.into(),
log_max_entries: 1_000_000usize.into(),
Expand Down Expand Up @@ -72,11 +75,13 @@ pub fn dump_send_correct_fragments() {
let mut fragment_generator = FragmentGenerator::new(
sender,
receiver,
Some(first_bft_leader),
jormungandr.to_remote(),
time_era.slots_per_epoch(),
2,
2,
2,
2,
fragment_sender,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,13 @@ pub fn fragment_load_test() {
let mut request_generator = FragmentGenerator::new(
faucet,
receiver,
None,
jormungandr.to_remote(),
60,
30,
30,
30,
0,
FragmentSender::new(
jormungandr.genesis_block_hash(),
jormungandr.fees(),
Expand Down
10 changes: 9 additions & 1 deletion testing/mjolnir/src/mjolnir_lib/fragment/standard/all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ use crate::{
mjolnir_lib::{args::parse_shift, build_monitor, MjolnirError},
};
use chain_addr::Discrimination;
use chain_crypto::Ed25519;
use chain_impl_mockchain::block::BlockDate;
use jormungandr_automation::{jormungandr::RemoteJormungandrBuilder, testing::time};
use jormungandr_automation::{
jormungandr::RemoteJormungandrBuilder,
testing::{keys::create_new_key_pair, time},
};
use jormungandr_lib::crypto::hash::Hash;
use jortestkit::{
load::ConfigurationBuilder,
Expand Down Expand Up @@ -103,14 +107,18 @@ impl AllFragments {
FragmentSenderSetup::no_verify(),
);

let bft_secret_alice = create_new_key_pair::<Ed25519>();

let mut generator = FragmentGenerator::new(
faucet,
receiver,
Some(bft_secret_alice),
remote_jormungandr,
settings.slots_per_epoch,
30,
30,
30,
30,
fragment_sender,
);

Expand Down
127 changes: 123 additions & 4 deletions testing/mjolnir/src/mjolnir_lib/generators/fragment_generator.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
use chain_core::property::FromStr;
use chain_crypto::Ed25519;
use chain_impl_mockchain::{
certificate::{VotePlan, VoteTallyPayload},
certificate::{UpdateProposal, UpdateVote, VotePlan, VoteTallyPayload},
chaintypes::ConsensusVersion,
fragment::FragmentId,
vote::Choice,
};
use chain_time::TimeEra;
use jormungandr_automation::{
jormungandr::{MemPoolCheck, RemoteJormungandr},
testing::{SyncNode, VoteCastCounter, VotePlanBuilder},
};
use jormungandr_lib::{crypto::hash::Hash, interfaces::BlockDate as BlockDateDto};
use jormungandr_lib::{
crypto::{hash::Hash, key::KeyPair},
interfaces::{BlockContentMaxSize, BlockDate as BlockDateDto, ConfigParam, ConfigParams},
};
use jortestkit::load::{Request, RequestFailure, RequestGenerator};
use rand::RngCore;
use rand_core::OsRng;
Expand All @@ -26,6 +32,8 @@ pub struct FragmentGenerator<'a, S: SyncNode + Send> {
active_stake_pools: Vec<StakePool>,
vote_plans_for_casting: Vec<VotePlan>,
vote_plans_for_tally: Vec<VotePlan>,
update_proposals_for_casting: Vec<FragmentId>,
bft_leader: Option<KeyPair<Ed25519>>,
node: RemoteJormungandr,
rand: OsRng,
vote_cast_register: Option<VoteCastCounter>,
Expand All @@ -34,30 +42,39 @@ pub struct FragmentGenerator<'a, S: SyncNode + Send> {
stake_pools_count: usize,
vote_plans_for_tally_count: usize,
vote_plans_for_casting_count: usize,
update_proposals_for_casting_count: usize,
fragment_options_count: usize,
}

impl<'a, S: SyncNode + Send> FragmentGenerator<'a, S> {
#[allow(clippy::too_many_arguments)]
pub fn new(
sender: Wallet,
receiver: Wallet,
bft_leader: Option<KeyPair<Ed25519>>,
node: RemoteJormungandr,
slots_per_epoch: u32,
stake_pools_count: usize,
vote_plans_for_tally_count: usize,
vote_plans_for_casting_count: usize,
update_proposals_for_casting_count: usize,
fragment_sender: FragmentSender<'a, S>,
) -> Self {
assert!(vote_plans_for_casting_count > 1);
assert!(stake_pools_count > 1);
assert!(vote_plans_for_tally_count > 1);
if bft_leader.is_some() {
assert!(update_proposals_for_casting_count > 1);
}

Self {
sender,
receiver,
active_stake_pools: vec![],
vote_plans_for_casting: vec![],
vote_plans_for_tally: vec![],
update_proposals_for_casting: vec![],
bft_leader,
node,
vote_cast_register: None,
rand: OsRng,
Expand All @@ -66,6 +83,8 @@ impl<'a, S: SyncNode + Send> FragmentGenerator<'a, S> {
stake_pools_count,
vote_plans_for_tally_count,
vote_plans_for_casting_count,
update_proposals_for_casting_count,
fragment_options_count: 0,
}
}

Expand All @@ -79,6 +98,56 @@ impl<'a, S: SyncNode + Send> FragmentGenerator<'a, S> {
let settings = self.node.rest().settings().unwrap();
let block0_hash = Hash::from_str(&settings.block0_hash).unwrap();
let fees = settings.fees;
if settings.consensus_version == ConsensusVersion::Bft.to_string() {
assert!(
self.bft_leader.is_some(),
"Consensus version bft, bft leader needed"
);
self.fragment_options_count = 12;

let update_proposals: Vec<UpdateProposal> = iter::from_fn(|| {
Some(UpdateProposal::new(
ConfigParams::new(vec![ConfigParam::BlockContentMaxSize(
BlockContentMaxSize::from(self.rand.next_u32()),
)])
.into(),
self.bft_leader
.as_ref()
.unwrap()
.identifier()
.into_public_key()
.into(),
))
})
.take(self.update_proposals_for_casting_count)
.collect();

for update_proposal in update_proposals {
fragments.push(
FragmentBuilder::new(&block0_hash, &fees, self.fragment_sender.date())
.update_proposal(
&self.sender,
update_proposal,
&self
.bft_leader
.as_ref()
.unwrap()
.signing_key()
.into_secret_key(),
),
);
self.sender.confirm_transaction();
}
self.update_proposals_for_casting = fragments.iter().map(|f| f.hash()).collect();
}

if settings.consensus_version == ConsensusVersion::GenesisPraos.to_string() {
assert!(
self.bft_leader.is_none(),
"Consesus version genesis praos, bft leader will be ignored"
);
self.fragment_options_count = 10;
}

let stake_pools: Vec<StakePool> = iter::from_fn(|| Some(StakePool::new(&self.sender)))
.take(self.stake_pools_count)
Expand Down Expand Up @@ -116,6 +185,7 @@ impl<'a, S: SyncNode + Send> FragmentGenerator<'a, S> {
);
self.sender.confirm_transaction();
}

for vote_plan_for_casting in &votes_plan_for_casting {
fragments.push(
FragmentBuilder::new(&block0_hash, &fees, self.fragment_sender.date())
Expand Down Expand Up @@ -155,14 +225,15 @@ impl<'a, S: SyncNode + Send> FragmentGenerator<'a, S> {

pub fn send_all(&mut self) -> Result<Vec<MemPoolCheck>, FragmentSenderError> {
let mut checks = Vec::new();
for i in 0..10 {

for i in 0..self.fragment_options_count {
checks.push(self.send_one(i as u8)?);
}
Ok(checks)
}

pub fn send_one(&mut self, option: u8) -> Result<MemPoolCheck, FragmentSenderError> {
match option % 10 {
match option % self.fragment_options_count as u8 {
0 => self.fragment_sender.send_transaction(
&mut self.sender,
&self.receiver,
Expand Down Expand Up @@ -280,6 +351,54 @@ impl<'a, S: SyncNode + Send> FragmentGenerator<'a, S> {
VoteTallyPayload::Public,
)
}
10 => {
let change_params = ConfigParams::new(vec![ConfigParam::BlockContentMaxSize(
BlockContentMaxSize::from(self.rand.next_u32()),
)]);

let update_proposal = UpdateProposal::new(
change_params.into(),
self.bft_leader
.as_ref()
.unwrap()
.identifier()
.into_public_key()
.into(),
);

self.fragment_sender.send_update_proposal(
&mut self.sender,
&self.bft_leader.as_ref().unwrap().signing_key().into(),
update_proposal,
&self.node,
)
}
11 => {
let index = self.rand.next_u32() as usize % self.update_proposals_for_casting.len();
let update_proposal = self.update_proposals_for_casting.get(index).unwrap();

let update_vote = UpdateVote::new(
*update_proposal,
self.bft_leader
.as_ref()
.unwrap()
.identifier()
.into_public_key()
.into(),
);

self.fragment_sender.send_update_vote(
&mut self.sender,
&self
.bft_leader
.as_ref()
.unwrap()
.signing_key()
.into_secret_key(),
update_vote,
&self.node,
)
}
_ => unreachable!(),
}
}
Expand Down

0 comments on commit 7588dad

Please sign in to comment.