macro_rules! panorama {
($($obs:expr),*) => {{
use crate::components::consensus::highway_core::state::Panorama;
Panorama::from(vec![$($obs.into()),*])
}};
}
macro_rules! add_unit {
($state: ident, $creator: expr, $val: expr; $($obs:expr),*) => {{
add_unit!($state, $creator, $val; $($obs),*;)
}};
($state: ident, $creator: expr, $val: expr; $($obs:expr),*; $($ends:expr),*) => {{
#[allow(unused_imports)] use crate::{
components::consensus::highway_core::{
state::{self, tests::TestSecret},
highway::{SignedWireUnit, WireUnit},
highway_testing::TEST_INSTANCE_ID,
},
};
#[allow(unused_imports)] use casper_types::{TimeDiff, Timestamp};
let creator = $creator;
let panorama = panorama!($($obs),*);
let seq_number = panorama.next_seq_num(&$state, creator);
let maybe_parent_hash = panorama[creator].correct();
let r_len = maybe_parent_hash.map_or_else(
|| $state.params().init_round_len(),
|vh| $state.unit(vh).round_len(),
);
let value = Option::from($val);
let two_units_limit = maybe_parent_hash
.and_then(|ph| $state.unit(ph).previous())
.map(|pph| $state.unit(pph))
.map(|unit| unit.round_id() + unit.round_len());
let mut timestamp = panorama
.iter_correct(&$state)
.map(|unit| unit.timestamp + TimeDiff::from_millis(1))
.chain(two_units_limit)
.max()
.unwrap_or($state.params().start_timestamp());
if value.is_some() {
timestamp = state::round_id(timestamp + r_len - TimeDiff::from_millis(1), r_len);
while $state.leader(timestamp) != creator {
timestamp += r_len;
}
}
let round_exp = (r_len / $state.params().min_round_length()).trailing_zeros() as u8;
let wunit = WireUnit {
panorama,
creator,
instance_id: TEST_INSTANCE_ID,
value,
seq_number,
timestamp,
round_exp,
endorsed: vec![$($ends),*].into_iter().collect(),
};
let hwunit = wunit.into_hashed();
let hash = hwunit.hash();
let swunit = SignedWireUnit::new(hwunit, &TestSecret(($creator).0));
$state.add_unit(swunit).map(|()| hash)
}};
($state: ident, $creator: expr, $time: expr, $round_exp: expr, $val: expr; $($obs:expr),*) => {{
add_unit!($state, $creator, $time, $round_exp, $val; $($obs),*; std::collections::BTreeSet::new())
}};
($state: ident, $creator: expr, $time: expr, $round_exp: expr, $val: expr; $($obs:expr),*; $($ends:expr),*) => {{
use crate::components::consensus::highway_core::{
state::tests::TestSecret,
highway::{SignedWireUnit, WireUnit},
highway_testing::TEST_INSTANCE_ID,
};
let creator = $creator;
let panorama = panorama!($($obs),*);
let seq_number = panorama.next_seq_num(&$state, creator);
let wunit = WireUnit {
panorama,
creator,
instance_id: TEST_INSTANCE_ID,
value: ($val).into(),
seq_number,
timestamp: ($time).into(),
round_exp: $round_exp,
endorsed: $($ends.into()),*
};
let hwunit = wunit.into_hashed();
let hash = hwunit.hash();
let swunit = SignedWireUnit::new(hwunit, &TestSecret(($creator).0));
$state.add_unit(swunit).map(|()| hash)
}};
}
macro_rules! endorse {
($state: ident, $vote: expr; $($creators: expr),*) => {
let creators = vec![$($creators.into()),*];
for creator in creators.into_iter() {
endorse!($state, creator, $vote);
}
};
($state: ident, $creator: expr, $vote: expr) => {{
use crate::components::consensus::highway_core::endorsement::{
Endorsement, SignedEndorsement,
};
let endorsement: Endorsement<TestContext> = Endorsement::new($vote, ($creator));
let signature = TestSecret(($creator).0).sign(&endorsement.hash());
let endorsements = SignedEndorsement::new(endorsement, signature).into();
let evidence = $state.find_conflicting_endorsements(&endorsements, &TEST_INSTANCE_ID);
$state.add_endorsements(endorsements);
for ev in evidence {
$state.add_evidence(ev);
}
}};
}