Change simulation Node
trait current_view
method return View
(#259)
This commit is contained in:
parent
0866dfc8af
commit
6dee12704d
@ -317,9 +317,8 @@ impl<L: UpdateableLeaderSelection, O: Overlay<LeaderSelection = L>> Node for Car
|
|||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn current_view(&self) -> usize {
|
fn current_view(&self) -> View {
|
||||||
let view: i64 = self.event_builder.current_view.into();
|
self.event_builder.current_view
|
||||||
view as usize
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn state(&self) -> &CarnotState {
|
fn state(&self) -> &CarnotState {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// std
|
// std
|
||||||
|
use consensus_engine::View;
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
// crates
|
// crates
|
||||||
@ -13,9 +14,9 @@ use super::{CommitteeId, OverlayGetter, OverlayState, SharedState, ViewOverlay};
|
|||||||
|
|
||||||
#[derive(Debug, Default, Serialize)]
|
#[derive(Debug, Default, Serialize)]
|
||||||
pub struct DummyState {
|
pub struct DummyState {
|
||||||
pub current_view: usize,
|
pub current_view: View,
|
||||||
pub message_count: usize,
|
pub message_count: usize,
|
||||||
pub view_state: BTreeMap<usize, DummyViewState>,
|
pub view_state: BTreeMap<View, DummyViewState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Serialize)]
|
#[derive(Debug, Default, Serialize)]
|
||||||
@ -40,12 +41,12 @@ pub enum Intent {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Vote {
|
pub struct Vote {
|
||||||
pub view: usize,
|
pub view: View,
|
||||||
pub intent: Intent,
|
pub intent: Intent,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vote {
|
impl Vote {
|
||||||
pub fn new(id: usize, intent: Intent) -> Self {
|
pub fn new(id: View, intent: Intent) -> Self {
|
||||||
Self { view: id, intent }
|
Self { view: id, intent }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,8 +58,8 @@ impl Vote {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<usize> for Vote {
|
impl From<View> for Vote {
|
||||||
fn from(id: usize) -> Self {
|
fn from(id: View) -> Self {
|
||||||
Self {
|
Self {
|
||||||
view: id,
|
view: id,
|
||||||
intent: Default::default(),
|
intent: Default::default(),
|
||||||
@ -68,17 +69,17 @@ impl From<usize> for Vote {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
pub view: usize,
|
pub view: View,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Block {
|
impl Block {
|
||||||
pub fn new(id: usize) -> Self {
|
pub fn new(id: View) -> Self {
|
||||||
Self { view: id }
|
Self { view: id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<usize> for Block {
|
impl From<View> for Block {
|
||||||
fn from(id: usize) -> Self {
|
fn from(id: View) -> Self {
|
||||||
Self { view: id }
|
Self { view: id }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,12 +99,12 @@ struct LocalView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LocalView {
|
impl LocalView {
|
||||||
pub fn new<O: OverlayGetter>(node_id: NodeId, view_id: usize, overlays: O) -> Self {
|
pub fn new<O: OverlayGetter>(node_id: NodeId, view_id: View, overlays: O) -> Self {
|
||||||
let view = overlays
|
let view = overlays
|
||||||
.get_view(view_id)
|
.get_view(view_id)
|
||||||
.expect("simulation generated enough views");
|
.expect("simulation generated enough views");
|
||||||
let next_view = overlays
|
let next_view = overlays
|
||||||
.get_view(view_id + 1)
|
.get_view(view_id.next())
|
||||||
.expect("simulation generated enough views");
|
.expect("simulation generated enough views");
|
||||||
|
|
||||||
let parents = get_parent_nodes(node_id, &view);
|
let parents = get_parent_nodes(node_id, &view);
|
||||||
@ -152,7 +153,7 @@ pub enum DummyRole {
|
|||||||
impl DummyNode {
|
impl DummyNode {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
view_id: usize,
|
view_id: View,
|
||||||
overlay_state: SharedState<OverlayState>,
|
overlay_state: SharedState<OverlayState>,
|
||||||
network_interface: InMemoryNetworkInterface<DummyMessage>,
|
network_interface: InMemoryNetworkInterface<DummyMessage>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -177,7 +178,7 @@ impl DummyNode {
|
|||||||
.for_each(|address| self.send_message(*address, message.clone()))
|
.for_each(|address| self.send_message(*address, message.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_view(&mut self, view: usize) {
|
fn update_view(&mut self, view: View) {
|
||||||
self.state.view_state.insert(
|
self.state.view_state.insert(
|
||||||
view,
|
view,
|
||||||
DummyViewState {
|
DummyViewState {
|
||||||
@ -190,7 +191,7 @@ impl DummyNode {
|
|||||||
self.local_view = LocalView::new(self.id(), view, self.overlay_state.clone());
|
self.local_view = LocalView::new(self.id(), view, self.overlay_state.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_vote_sent(&self, view: usize) -> bool {
|
fn is_vote_sent(&self, view: View) -> bool {
|
||||||
self.state
|
self.state
|
||||||
.view_state
|
.view_state
|
||||||
.get(&view)
|
.get(&view)
|
||||||
@ -198,7 +199,7 @@ impl DummyNode {
|
|||||||
.vote_sent
|
.vote_sent
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_vote_sent(&mut self, view: usize) {
|
fn set_vote_sent(&mut self, view: View) {
|
||||||
let view_state = self
|
let view_state = self
|
||||||
.state
|
.state
|
||||||
.view_state
|
.view_state
|
||||||
@ -207,7 +208,7 @@ impl DummyNode {
|
|||||||
view_state.vote_sent = true;
|
view_state.vote_sent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_vote_count(&self, view: usize) -> usize {
|
fn get_vote_count(&self, view: View) -> usize {
|
||||||
self.state
|
self.state
|
||||||
.view_state
|
.view_state
|
||||||
.get(&view)
|
.get(&view)
|
||||||
@ -215,7 +216,7 @@ impl DummyNode {
|
|||||||
.vote_received_count
|
.vote_received_count
|
||||||
}
|
}
|
||||||
|
|
||||||
fn increment_vote_count(&mut self, view: usize) {
|
fn increment_vote_count(&mut self, view: View) {
|
||||||
let view_state = self
|
let view_state = self
|
||||||
.state
|
.state
|
||||||
.view_state
|
.view_state
|
||||||
@ -251,7 +252,7 @@ impl DummyNode {
|
|||||||
&self.local_view.current_roots,
|
&self.local_view.current_roots,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
let new_view_id = self.current_view() + 1;
|
let new_view_id = self.current_view().next();
|
||||||
self.broadcast(
|
self.broadcast(
|
||||||
&self.overlay_state.get_all_nodes(),
|
&self.overlay_state.get_all_nodes(),
|
||||||
DummyMessage::Proposal(new_view_id.into()),
|
DummyMessage::Proposal(new_view_id.into()),
|
||||||
@ -355,7 +356,7 @@ impl Node for DummyNode {
|
|||||||
self.node_id
|
self.node_id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn current_view(&self) -> usize {
|
fn current_view(&self) -> View {
|
||||||
self.state.current_view
|
self.state.current_view
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -424,6 +425,7 @@ mod tests {
|
|||||||
time::{Duration, SystemTime, UNIX_EPOCH},
|
time::{Duration, SystemTime, UNIX_EPOCH},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use consensus_engine::View;
|
||||||
use crossbeam::channel;
|
use crossbeam::channel;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use rand::{
|
use rand::{
|
||||||
@ -484,7 +486,12 @@ mod tests {
|
|||||||
);
|
);
|
||||||
(
|
(
|
||||||
*node_id,
|
*node_id,
|
||||||
DummyNode::new(*node_id, 0, overlay_state.clone(), network_interface),
|
DummyNode::new(
|
||||||
|
*node_id,
|
||||||
|
View::new(0),
|
||||||
|
overlay_state.clone(),
|
||||||
|
network_interface,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
@ -496,11 +503,11 @@ mod tests {
|
|||||||
overlay_count: usize,
|
overlay_count: usize,
|
||||||
leader_count: usize,
|
leader_count: usize,
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
) -> BTreeMap<usize, ViewOverlay> {
|
) -> BTreeMap<View, ViewOverlay> {
|
||||||
(0..overlay_count)
|
(0..overlay_count)
|
||||||
.map(|view_id| {
|
.map(|view_id| {
|
||||||
(
|
(
|
||||||
view_id,
|
View::new(view_id as i64),
|
||||||
ViewOverlay {
|
ViewOverlay {
|
||||||
leaders: overlay.leaders(node_ids, leader_count, rng).collect(),
|
leaders: overlay.leaders(node_ids, leader_count, rng).collect(),
|
||||||
layout: overlay.layout(node_ids, rng),
|
layout: overlay.layout(node_ids, rng),
|
||||||
@ -511,13 +518,13 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn send_initial_votes(
|
fn send_initial_votes(
|
||||||
overlays: &BTreeMap<usize, ViewOverlay>,
|
overlays: &BTreeMap<View, ViewOverlay>,
|
||||||
committee_size: usize,
|
committee_size: usize,
|
||||||
nodes: &HashMap<NodeId, DummyNode>,
|
nodes: &HashMap<NodeId, DummyNode>,
|
||||||
) {
|
) {
|
||||||
let initial_vote = Vote::new(1, Intent::FromRootToLeader);
|
let initial_vote = Vote::new(View::new(1), Intent::FromRootToLeader);
|
||||||
overlays
|
overlays
|
||||||
.get(&1)
|
.get(&View::new(1))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.leaders
|
.leaders
|
||||||
.iter()
|
.iter()
|
||||||
@ -557,15 +564,15 @@ mod tests {
|
|||||||
all_nodes: node_ids.clone(),
|
all_nodes: node_ids.clone(),
|
||||||
overlay: SimulationOverlay::Tree(overlay),
|
overlay: SimulationOverlay::Tree(overlay),
|
||||||
overlays: BTreeMap::from([
|
overlays: BTreeMap::from([
|
||||||
(0, view.clone()),
|
(View::new(0), view.clone()),
|
||||||
(1, view.clone()),
|
(View::new(1), view.clone()),
|
||||||
(2, view.clone()),
|
(View::new(2), view.clone()),
|
||||||
(3, view),
|
(View::new(3), view),
|
||||||
]),
|
]),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let mut nodes = init_dummy_nodes(&node_ids, &mut network, overlay_state);
|
let mut nodes = init_dummy_nodes(&node_ids, &mut network, overlay_state);
|
||||||
let initial_vote = Vote::new(1, Intent::FromRootToLeader);
|
let initial_vote = Vote::new(View::new(1), Intent::FromRootToLeader);
|
||||||
|
|
||||||
// Using any node as the sender for initial proposal to leader nodes.
|
// Using any node as the sender for initial proposal to leader nodes.
|
||||||
nodes[&NodeId::from_index(0)].send_message(
|
nodes[&NodeId::from_index(0)].send_message(
|
||||||
@ -581,7 +588,7 @@ mod tests {
|
|||||||
network.collect_messages();
|
network.collect_messages();
|
||||||
|
|
||||||
for (_, node) in nodes.iter() {
|
for (_, node) in nodes.iter() {
|
||||||
assert_eq!(node.current_view(), 0);
|
assert_eq!(node.current_view(), View::new(0));
|
||||||
}
|
}
|
||||||
let elapsed = Duration::from_millis(100);
|
let elapsed = Duration::from_millis(100);
|
||||||
// 1. Leaders receive vote and broadcast new Proposal(Block) to all nodes.
|
// 1. Leaders receive vote and broadcast new Proposal(Block) to all nodes.
|
||||||
@ -601,19 +608,19 @@ mod tests {
|
|||||||
|
|
||||||
// All nodes should be updated to the proposed blocks view.
|
// All nodes should be updated to the proposed blocks view.
|
||||||
for (_, node) in nodes.iter() {
|
for (_, node) in nodes.iter() {
|
||||||
assert_eq!(node.current_view(), 1);
|
assert_eq!(node.current_view(), View::new(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Root and Internal haven't sent their votes yet.
|
// Root and Internal haven't sent their votes yet.
|
||||||
assert!(!nodes[&NodeId::from_index(0)].state().view_state[&1].vote_sent); // Root
|
assert!(!nodes[&NodeId::from_index(0)].state().view_state[&View::new(1)].vote_sent); // Root
|
||||||
assert!(!nodes[&NodeId::from_index(1)].state().view_state[&1].vote_sent); // Internal
|
assert!(!nodes[&NodeId::from_index(1)].state().view_state[&View::new(1)].vote_sent); // Internal
|
||||||
assert!(!nodes[&NodeId::from_index(2)].state().view_state[&1].vote_sent); // Internal
|
assert!(!nodes[&NodeId::from_index(2)].state().view_state[&View::new(1)].vote_sent); // Internal
|
||||||
|
|
||||||
// Leaves should have thier vote sent.
|
// Leaves should have thier vote sent.
|
||||||
assert!(nodes[&NodeId::from_index(3)].state().view_state[&1].vote_sent); // Leaf
|
assert!(nodes[&NodeId::from_index(3)].state().view_state[&View::new(1)].vote_sent); // Leaf
|
||||||
assert!(nodes[&NodeId::from_index(4)].state().view_state[&1].vote_sent); // Leaf
|
assert!(nodes[&NodeId::from_index(4)].state().view_state[&View::new(1)].vote_sent); // Leaf
|
||||||
assert!(nodes[&NodeId::from_index(5)].state().view_state[&1].vote_sent); // Leaf
|
assert!(nodes[&NodeId::from_index(5)].state().view_state[&View::new(1)].vote_sent); // Leaf
|
||||||
assert!(nodes[&NodeId::from_index(6)].state().view_state[&1].vote_sent); // Leaf
|
assert!(nodes[&NodeId::from_index(6)].state().view_state[&View::new(1)].vote_sent); // Leaf
|
||||||
|
|
||||||
// 3. Internal nodes send vote to root node.
|
// 3. Internal nodes send vote to root node.
|
||||||
network.dispatch_after(elapsed);
|
network.dispatch_after(elapsed);
|
||||||
@ -623,15 +630,15 @@ mod tests {
|
|||||||
network.collect_messages();
|
network.collect_messages();
|
||||||
|
|
||||||
// Root hasn't sent its votes yet.
|
// Root hasn't sent its votes yet.
|
||||||
assert!(!nodes[&NodeId::from_index(0)].state().view_state[&1].vote_sent); // Root
|
assert!(!nodes[&NodeId::from_index(0)].state().view_state[&View::new(1)].vote_sent); // Root
|
||||||
|
|
||||||
// Internal and leaves should have thier vote sent.
|
// Internal and leaves should have thier vote sent.
|
||||||
assert!(nodes[&NodeId::from_index(1)].state().view_state[&1].vote_sent); // Internal
|
assert!(nodes[&NodeId::from_index(1)].state().view_state[&View::new(1)].vote_sent); // Internal
|
||||||
assert!(nodes[&NodeId::from_index(2)].state().view_state[&1].vote_sent); // Internal
|
assert!(nodes[&NodeId::from_index(2)].state().view_state[&View::new(1)].vote_sent); // Internal
|
||||||
assert!(nodes[&NodeId::from_index(3)].state().view_state[&1].vote_sent); // Leaf
|
assert!(nodes[&NodeId::from_index(3)].state().view_state[&View::new(1)].vote_sent); // Leaf
|
||||||
assert!(nodes[&NodeId::from_index(4)].state().view_state[&1].vote_sent); // Leaf
|
assert!(nodes[&NodeId::from_index(4)].state().view_state[&View::new(1)].vote_sent); // Leaf
|
||||||
assert!(nodes[&NodeId::from_index(5)].state().view_state[&1].vote_sent); // Leaf
|
assert!(nodes[&NodeId::from_index(5)].state().view_state[&View::new(1)].vote_sent); // Leaf
|
||||||
assert!(nodes[&NodeId::from_index(6)].state().view_state[&1].vote_sent); // Leaf
|
assert!(nodes[&NodeId::from_index(6)].state().view_state[&View::new(1)].vote_sent); // Leaf
|
||||||
|
|
||||||
// 4. Root node send vote to next view leader nodes.
|
// 4. Root node send vote to next view leader nodes.
|
||||||
network.dispatch_after(elapsed);
|
network.dispatch_after(elapsed);
|
||||||
@ -641,13 +648,13 @@ mod tests {
|
|||||||
network.collect_messages();
|
network.collect_messages();
|
||||||
|
|
||||||
// Root has sent its votes.
|
// Root has sent its votes.
|
||||||
assert!(nodes[&NodeId::from_index(0)].state().view_state[&1].vote_sent); // Root
|
assert!(nodes[&NodeId::from_index(0)].state().view_state[&View::new(1)].vote_sent); // Root
|
||||||
assert!(nodes[&NodeId::from_index(1)].state().view_state[&1].vote_sent); // Internal
|
assert!(nodes[&NodeId::from_index(1)].state().view_state[&View::new(1)].vote_sent); // Internal
|
||||||
assert!(nodes[&NodeId::from_index(2)].state().view_state[&1].vote_sent); // Internal
|
assert!(nodes[&NodeId::from_index(2)].state().view_state[&View::new(1)].vote_sent); // Internal
|
||||||
assert!(nodes[&NodeId::from_index(3)].state().view_state[&1].vote_sent); // Leaf
|
assert!(nodes[&NodeId::from_index(3)].state().view_state[&View::new(1)].vote_sent); // Leaf
|
||||||
assert!(nodes[&NodeId::from_index(4)].state().view_state[&1].vote_sent); // Leaf
|
assert!(nodes[&NodeId::from_index(4)].state().view_state[&View::new(1)].vote_sent); // Leaf
|
||||||
assert!(nodes[&NodeId::from_index(5)].state().view_state[&1].vote_sent); // Leaf
|
assert!(nodes[&NodeId::from_index(5)].state().view_state[&View::new(1)].vote_sent); // Leaf
|
||||||
assert!(nodes[&NodeId::from_index(6)].state().view_state[&1].vote_sent); // Leaf
|
assert!(nodes[&NodeId::from_index(6)].state().view_state[&View::new(1)].vote_sent); // Leaf
|
||||||
|
|
||||||
// 5. Leaders receive vote and broadcast new Proposal(Block) to all nodes.
|
// 5. Leaders receive vote and broadcast new Proposal(Block) to all nodes.
|
||||||
network.dispatch_after(elapsed);
|
network.dispatch_after(elapsed);
|
||||||
@ -658,7 +665,7 @@ mod tests {
|
|||||||
|
|
||||||
// All nodes should be in an old view
|
// All nodes should be in an old view
|
||||||
for (_, node) in nodes.iter() {
|
for (_, node) in nodes.iter() {
|
||||||
assert_eq!(node.current_view(), 1); // old
|
assert_eq!(node.current_view(), View::new(1)); // old
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. a) All nodes received proposal block.
|
// 6. a) All nodes received proposal block.
|
||||||
@ -671,19 +678,19 @@ mod tests {
|
|||||||
|
|
||||||
// All nodes should be updated to the proposed blocks view.
|
// All nodes should be updated to the proposed blocks view.
|
||||||
for (_, node) in nodes.iter() {
|
for (_, node) in nodes.iter() {
|
||||||
assert_eq!(node.current_view(), 2); // new
|
assert_eq!(node.current_view(), View::new(2)); // new
|
||||||
}
|
}
|
||||||
|
|
||||||
// Root and Internal haven't sent their votes yet.
|
// Root and Internal haven't sent their votes yet.
|
||||||
assert!(!nodes[&NodeId::from_index(0)].state().view_state[&2].vote_sent); // Root
|
assert!(!nodes[&NodeId::from_index(0)].state().view_state[&View::new(2)].vote_sent); // Root
|
||||||
assert!(!nodes[&NodeId::from_index(1)].state().view_state[&2].vote_sent); // Internal
|
assert!(!nodes[&NodeId::from_index(1)].state().view_state[&View::new(2)].vote_sent); // Internal
|
||||||
assert!(!nodes[&NodeId::from_index(2)].state().view_state[&2].vote_sent); // Internal
|
assert!(!nodes[&NodeId::from_index(2)].state().view_state[&View::new(2)].vote_sent); // Internal
|
||||||
|
|
||||||
// Leaves should have thier vote sent.
|
// Leaves should have thier vote sent.
|
||||||
assert!(nodes[&NodeId::from_index(3)].state().view_state[&2].vote_sent); // Leaf
|
assert!(nodes[&NodeId::from_index(3)].state().view_state[&View::new(2)].vote_sent); // Leaf
|
||||||
assert!(nodes[&NodeId::from_index(4)].state().view_state[&2].vote_sent); // Leaf
|
assert!(nodes[&NodeId::from_index(4)].state().view_state[&View::new(2)].vote_sent); // Leaf
|
||||||
assert!(nodes[&NodeId::from_index(5)].state().view_state[&2].vote_sent); // Leaf
|
assert!(nodes[&NodeId::from_index(5)].state().view_state[&View::new(2)].vote_sent); // Leaf
|
||||||
assert!(nodes[&NodeId::from_index(6)].state().view_state[&2].vote_sent);
|
assert!(nodes[&NodeId::from_index(6)].state().view_state[&View::new(2)].vote_sent);
|
||||||
// Leaf
|
// Leaf
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -722,7 +729,7 @@ mod tests {
|
|||||||
network.collect_messages();
|
network.collect_messages();
|
||||||
|
|
||||||
for (_, node) in nodes.iter() {
|
for (_, node) in nodes.iter() {
|
||||||
assert_eq!(node.current_view(), 0);
|
assert_eq!(node.current_view(), View::new(0));
|
||||||
}
|
}
|
||||||
let elapsed = Duration::from_millis(100);
|
let elapsed = Duration::from_millis(100);
|
||||||
for _ in 0..7 {
|
for _ in 0..7 {
|
||||||
@ -734,7 +741,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (_, node) in nodes.iter() {
|
for (_, node) in nodes.iter() {
|
||||||
assert_eq!(node.current_view(), 2);
|
assert_eq!(node.current_view(), View::new(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -772,7 +779,7 @@ mod tests {
|
|||||||
network.collect_messages();
|
network.collect_messages();
|
||||||
|
|
||||||
for (_, node) in nodes.iter() {
|
for (_, node) in nodes.iter() {
|
||||||
assert_eq!(node.current_view(), 0);
|
assert_eq!(node.current_view(), View::new(0));
|
||||||
}
|
}
|
||||||
let elapsed = Duration::from_millis(100);
|
let elapsed = Duration::from_millis(100);
|
||||||
for _ in 0..7 {
|
for _ in 0..7 {
|
||||||
@ -784,7 +791,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (_, node) in nodes.iter() {
|
for (_, node) in nodes.iter() {
|
||||||
assert_eq!(node.current_view(), 2);
|
assert_eq!(node.current_view(), View::new(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -832,7 +839,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (_, node) in nodes.read().iter() {
|
for (_, node) in nodes.read().iter() {
|
||||||
assert_eq!(node.current_view(), 2);
|
assert_eq!(node.current_view(), View::new(2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use consensus_engine::View;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
@ -5,7 +6,7 @@ use super::{Node, NodeId};
|
|||||||
|
|
||||||
#[derive(Debug, Default, Copy, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Default, Copy, Clone, Serialize, Deserialize)]
|
||||||
pub struct DummyStreamingState {
|
pub struct DummyStreamingState {
|
||||||
pub current_view: usize,
|
pub current_view: View,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This node implementation only used for testing different streaming implementation purposes.
|
/// This node implementation only used for testing different streaming implementation purposes.
|
||||||
@ -35,7 +36,7 @@ impl<S> Node for DummyStreamingNode<S> {
|
|||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn current_view(&self) -> usize {
|
fn current_view(&self) -> View {
|
||||||
self.state.current_view
|
self.state.current_view
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,6 +45,6 @@ impl<S> Node for DummyStreamingNode<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn step(&mut self, _: Duration) {
|
fn step(&mut self, _: Duration) {
|
||||||
self.state.current_view += 1;
|
self.state.current_view = self.state.current_view.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ pub mod dummy;
|
|||||||
pub mod dummy_streaming;
|
pub mod dummy_streaming;
|
||||||
|
|
||||||
// std
|
// std
|
||||||
|
use consensus_engine::View;
|
||||||
use std::{
|
use std::{
|
||||||
collections::BTreeMap,
|
collections::BTreeMap,
|
||||||
ops::{Deref, DerefMut},
|
ops::{Deref, DerefMut},
|
||||||
@ -126,16 +127,16 @@ pub type SharedState<S> = Arc<RwLock<S>>;
|
|||||||
pub struct OverlayState {
|
pub struct OverlayState {
|
||||||
pub all_nodes: Vec<NodeId>,
|
pub all_nodes: Vec<NodeId>,
|
||||||
pub overlay: SimulationOverlay,
|
pub overlay: SimulationOverlay,
|
||||||
pub overlays: BTreeMap<usize, ViewOverlay>,
|
pub overlays: BTreeMap<View, ViewOverlay>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait OverlayGetter {
|
pub trait OverlayGetter {
|
||||||
fn get_view(&self, index: usize) -> Option<ViewOverlay>;
|
fn get_view(&self, index: View) -> Option<ViewOverlay>;
|
||||||
fn get_all_nodes(&self) -> Vec<NodeId>;
|
fn get_all_nodes(&self) -> Vec<NodeId>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OverlayGetter for SharedState<OverlayState> {
|
impl OverlayGetter for SharedState<OverlayState> {
|
||||||
fn get_view(&self, index: usize) -> Option<ViewOverlay> {
|
fn get_view(&self, index: View) -> Option<ViewOverlay> {
|
||||||
let overlay_state = self.read();
|
let overlay_state = self.read();
|
||||||
overlay_state.overlays.get(&index).cloned()
|
overlay_state.overlays.get(&index).cloned()
|
||||||
}
|
}
|
||||||
@ -151,8 +152,7 @@ pub trait Node {
|
|||||||
type State;
|
type State;
|
||||||
|
|
||||||
fn id(&self) -> NodeId;
|
fn id(&self) -> NodeId;
|
||||||
// TODO: View must be view whenever we integrate consensus engine
|
fn current_view(&self) -> View;
|
||||||
fn current_view(&self) -> usize;
|
|
||||||
fn state(&self) -> &Self::State;
|
fn state(&self) -> &Self::State;
|
||||||
fn step(&mut self, elapsed: Duration);
|
fn step(&mut self, elapsed: Duration);
|
||||||
}
|
}
|
||||||
@ -166,8 +166,8 @@ impl Node for usize {
|
|||||||
NodeId::from_index(*self)
|
NodeId::from_index(*self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn current_view(&self) -> usize {
|
fn current_view(&self) -> View {
|
||||||
*self
|
View::new(*self as i64)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn state(&self) -> &Self::State {
|
fn state(&self) -> &Self::State {
|
||||||
|
@ -83,6 +83,7 @@ mod tests {
|
|||||||
settings::SimulationSettings,
|
settings::SimulationSettings,
|
||||||
streaming::StreamProducer,
|
streaming::StreamProducer,
|
||||||
};
|
};
|
||||||
|
use consensus_engine::View;
|
||||||
use crossbeam::channel;
|
use crossbeam::channel;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use rand::rngs::mock::StepRng;
|
use rand::rngs::mock::StepRng;
|
||||||
@ -124,7 +125,12 @@ mod tests {
|
|||||||
node_message_sender,
|
node_message_sender,
|
||||||
network_message_receiver,
|
network_message_receiver,
|
||||||
);
|
);
|
||||||
DummyNode::new(*node_id, 0, overlay_state.clone(), network_interface)
|
DummyNode::new(
|
||||||
|
*node_id,
|
||||||
|
View::new(0),
|
||||||
|
overlay_state.clone(),
|
||||||
|
network_interface,
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
@ -147,7 +153,7 @@ mod tests {
|
|||||||
let overlay_state = Arc::new(RwLock::new(OverlayState {
|
let overlay_state = Arc::new(RwLock::new(OverlayState {
|
||||||
all_nodes: node_ids.clone(),
|
all_nodes: node_ids.clone(),
|
||||||
overlay: SimulationOverlay::Tree(overlay),
|
overlay: SimulationOverlay::Tree(overlay),
|
||||||
overlays: BTreeMap::from([(0, view.clone()), (1, view)]),
|
overlays: BTreeMap::from([(View::new(0), view.clone()), (View::new(1), view)]),
|
||||||
}));
|
}));
|
||||||
let nodes = init_dummy_nodes(&node_ids, &mut network, overlay_state)
|
let nodes = init_dummy_nodes(&node_ids, &mut network, overlay_state)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -173,7 +179,7 @@ mod tests {
|
|||||||
|
|
||||||
let nodes = runner.nodes.read();
|
let nodes = runner.nodes.read();
|
||||||
for node in nodes.iter() {
|
for node in nodes.iter() {
|
||||||
assert_eq!(node.current_view(), 0);
|
assert_eq!(node.current_view(), View::new(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,10 +202,10 @@ mod tests {
|
|||||||
all_nodes: node_ids.clone(),
|
all_nodes: node_ids.clone(),
|
||||||
overlay: SimulationOverlay::Tree(overlay),
|
overlay: SimulationOverlay::Tree(overlay),
|
||||||
overlays: BTreeMap::from([
|
overlays: BTreeMap::from([
|
||||||
(0, view.clone()),
|
(View::new(0), view.clone()),
|
||||||
(1, view.clone()),
|
(View::new(1), view.clone()),
|
||||||
(42, view.clone()),
|
(View::new(42), view.clone()),
|
||||||
(43, view),
|
(View::new(43), view),
|
||||||
]),
|
]),
|
||||||
}));
|
}));
|
||||||
let nodes = init_dummy_nodes(&node_ids, &mut network, overlay_state.clone());
|
let nodes = init_dummy_nodes(&node_ids, &mut network, overlay_state.clone());
|
||||||
@ -207,7 +213,7 @@ mod tests {
|
|||||||
for node in nodes.iter() {
|
for node in nodes.iter() {
|
||||||
// All nodes send one message to NodeId(1).
|
// All nodes send one message to NodeId(1).
|
||||||
// Nodes can send messages to themselves.
|
// Nodes can send messages to themselves.
|
||||||
node.send_message(node_ids[1], DummyMessage::Proposal(42.into()));
|
node.send_message(node_ids[1], DummyMessage::Proposal(View::new(42).into()));
|
||||||
}
|
}
|
||||||
network.collect_messages();
|
network.collect_messages();
|
||||||
|
|
||||||
|
@ -112,6 +112,8 @@ where
|
|||||||
mod tests {
|
mod tests {
|
||||||
use std::{collections::HashMap, time::Duration};
|
use std::{collections::HashMap, time::Duration};
|
||||||
|
|
||||||
|
use consensus_engine::View;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
network::{
|
network::{
|
||||||
behaviour::NetworkBehaviour,
|
behaviour::NetworkBehaviour,
|
||||||
@ -130,7 +132,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
struct IORecord {
|
struct IORecord {
|
||||||
states: HashMap<NodeId, usize>,
|
states: HashMap<NodeId, View>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, T: Serialize> TryFrom<&SimulationState<S, T>> for IORecord {
|
impl<S, T: Serialize> TryFrom<&SimulationState<S, T>> for IORecord {
|
||||||
|
@ -116,6 +116,8 @@ where
|
|||||||
mod tests {
|
mod tests {
|
||||||
use std::{collections::HashMap, time::Duration};
|
use std::{collections::HashMap, time::Duration};
|
||||||
|
|
||||||
|
use consensus_engine::View;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
network::{
|
network::{
|
||||||
behaviour::NetworkBehaviour,
|
behaviour::NetworkBehaviour,
|
||||||
@ -134,7 +136,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
struct NaiveRecord {
|
struct NaiveRecord {
|
||||||
states: HashMap<NodeId, usize>,
|
states: HashMap<NodeId, View>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, T: Serialize> TryFrom<&SimulationState<S, T>> for NaiveRecord {
|
impl<S, T: Serialize> TryFrom<&SimulationState<S, T>> for NaiveRecord {
|
||||||
|
@ -101,6 +101,8 @@ where
|
|||||||
mod tests {
|
mod tests {
|
||||||
use std::{collections::HashMap, time::Duration};
|
use std::{collections::HashMap, time::Duration};
|
||||||
|
|
||||||
|
use consensus_engine::View;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
network::{
|
network::{
|
||||||
behaviour::NetworkBehaviour,
|
behaviour::NetworkBehaviour,
|
||||||
@ -119,7 +121,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
struct RuntimeRecord {
|
struct RuntimeRecord {
|
||||||
states: HashMap<NodeId, usize>,
|
states: HashMap<NodeId, View>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, T: Serialize> TryFrom<&SimulationState<S, T>> for RuntimeRecord {
|
impl<S, T: Serialize> TryFrom<&SimulationState<S, T>> for RuntimeRecord {
|
||||||
|
@ -101,6 +101,8 @@ where
|
|||||||
mod tests {
|
mod tests {
|
||||||
use std::{collections::HashMap, time::Duration};
|
use std::{collections::HashMap, time::Duration};
|
||||||
|
|
||||||
|
use consensus_engine::View;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
network::{
|
network::{
|
||||||
behaviour::NetworkBehaviour,
|
behaviour::NetworkBehaviour,
|
||||||
@ -119,7 +121,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
struct SettingsRecord {
|
struct SettingsRecord {
|
||||||
states: HashMap<NodeId, usize>,
|
states: HashMap<NodeId, View>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, T: Serialize> TryFrom<&SimulationState<S, T>> for SettingsRecord {
|
impl<S, T: Serialize> TryFrom<&SimulationState<S, T>> for SettingsRecord {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::warding::{SimulationState, SimulationWard};
|
use crate::warding::{SimulationState, SimulationWard};
|
||||||
|
use consensus_engine::View;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// MinMaxView. It monitors the gap between a min view and max view, triggers when surpassing
|
/// MinMaxView. It monitors the gap between a min view and max view, triggers when surpassing
|
||||||
@ -6,14 +7,14 @@ use serde::{Deserialize, Serialize};
|
|||||||
#[derive(Debug, Serialize, Deserialize, Copy, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Copy, Clone)]
|
||||||
#[serde(transparent)]
|
#[serde(transparent)]
|
||||||
pub struct MinMaxViewWard {
|
pub struct MinMaxViewWard {
|
||||||
max_gap: usize,
|
max_gap: View,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, T> SimulationWard<S, T> for MinMaxViewWard {
|
impl<S, T> SimulationWard<S, T> for MinMaxViewWard {
|
||||||
type SimulationState = SimulationState<S, T>;
|
type SimulationState = SimulationState<S, T>;
|
||||||
fn analyze(&mut self, state: &Self::SimulationState) -> bool {
|
fn analyze(&mut self, state: &Self::SimulationState) -> bool {
|
||||||
let mut min = usize::MAX;
|
let mut min = View::new(i64::MAX);
|
||||||
let mut max = 0;
|
let mut max = View::new(0);
|
||||||
let nodes = state.nodes.read();
|
let nodes = state.nodes.read();
|
||||||
for node in nodes.iter() {
|
for node in nodes.iter() {
|
||||||
let view = node.current_view();
|
let view = node.current_view();
|
||||||
@ -28,12 +29,15 @@ impl<S, T> SimulationWard<S, T> for MinMaxViewWard {
|
|||||||
mod test {
|
mod test {
|
||||||
use crate::warding::minmax::MinMaxViewWard;
|
use crate::warding::minmax::MinMaxViewWard;
|
||||||
use crate::warding::{SimulationState, SimulationWard};
|
use crate::warding::{SimulationState, SimulationWard};
|
||||||
|
use consensus_engine::View;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rebase_threshold() {
|
fn rebase_threshold() {
|
||||||
let mut minmax = MinMaxViewWard { max_gap: 5 };
|
let mut minmax = MinMaxViewWard {
|
||||||
|
max_gap: View::new(5),
|
||||||
|
};
|
||||||
let state = SimulationState {
|
let state = SimulationState {
|
||||||
nodes: Arc::new(RwLock::new(vec![Box::new(10)])),
|
nodes: Arc::new(RwLock::new(vec![Box::new(10)])),
|
||||||
};
|
};
|
||||||
|
@ -44,7 +44,8 @@ impl<S, T> SimulationWard<S, T> for StalledViewWard {
|
|||||||
fn checksum<S, T>(nodes: &[BoxedNode<S, T>]) -> u32 {
|
fn checksum<S, T>(nodes: &[BoxedNode<S, T>]) -> u32 {
|
||||||
let mut hash = crc32fast::Hasher::new();
|
let mut hash = crc32fast::Hasher::new();
|
||||||
for node in nodes.iter() {
|
for node in nodes.iter() {
|
||||||
hash.update(&node.current_view().to_be_bytes());
|
let view: i64 = node.current_view().into();
|
||||||
|
hash.update(&(view as usize).to_be_bytes());
|
||||||
// TODO: hash messages in the node
|
// TODO: hash messages in the node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::warding::{SimulationState, SimulationWard};
|
use crate::warding::{SimulationState, SimulationWard};
|
||||||
|
use consensus_engine::View;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// Time to finality ward. It monitors the amount of rounds of the simulations, triggers when surpassing
|
/// Time to finality ward. It monitors the amount of rounds of the simulations, triggers when surpassing
|
||||||
@ -6,7 +7,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
#[derive(Debug, Serialize, Deserialize, Copy, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Copy, Clone)]
|
||||||
#[serde(transparent)]
|
#[serde(transparent)]
|
||||||
pub struct MaxViewWard {
|
pub struct MaxViewWard {
|
||||||
max_view: usize,
|
max_view: View,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, T> SimulationWard<S, T> for MaxViewWard {
|
impl<S, T> SimulationWard<S, T> for MaxViewWard {
|
||||||
@ -24,12 +25,15 @@ impl<S, T> SimulationWard<S, T> for MaxViewWard {
|
|||||||
mod test {
|
mod test {
|
||||||
use crate::warding::ttf::MaxViewWard;
|
use crate::warding::ttf::MaxViewWard;
|
||||||
use crate::warding::{SimulationState, SimulationWard};
|
use crate::warding::{SimulationState, SimulationWard};
|
||||||
|
use consensus_engine::View;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rebase_threshold() {
|
fn rebase_threshold() {
|
||||||
let mut ttf = MaxViewWard { max_view: 10 };
|
let mut ttf = MaxViewWard {
|
||||||
|
max_view: View::new(10),
|
||||||
|
};
|
||||||
|
|
||||||
let node = 11;
|
let node = 11;
|
||||||
let state = SimulationState {
|
let state = SimulationState {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user