in bft-lib/src/simulator.rs [296:378]
fn process_node_actions(
&mut self,
clock: GlobalTime,
author: Author,
actions: NodeUpdateActions<Context>,
) {
debug!(
"@{:?} Processing node actions for {:?}: {:?}",
clock, author, actions
);
// First, we must save the state of the node.
let mut node = self.simulated_node_mut(author);
block_on(node.node.save_node(&mut node.context))
.expect("saving nodes should not fail in simulator");
// Then, schedule the next call to `update_node`.
let new_scheduled_time = {
let new_scheduled_time = std::cmp::max(
GlobalTime::from_node_time(actions.next_scheduled_update, node.startup_time),
// Make sure we schedule the update strictly in the future so it does not get
// ignored by `ignore_scheduled_updates_until` below.
clock + Duration(1),
);
// We don't remove the previously scheduled updates but this will cancel them.
node.ignore_scheduled_updates_until = new_scheduled_time + Duration(-1);
new_scheduled_time
// scoping the mutable 'node' for the borrow checker
};
let event = Event::UpdateTimerEvent { author };
self.schedule_event(new_scheduled_time, event);
// Schedule sending notifications.
let mut receivers = Vec::new();
if actions.should_broadcast {
// TODO: broadcasting to all (past and future) nodes in the network is not entirely
// realistic. The pseudo-code should probably use `actions.should_send` instead to
// broadcast only to the nodes that a sender consider part of the epoch.
for index in 0..self.nodes.len() {
if index != author.0 {
receivers.push(Author(index));
}
}
} else {
for receiver in actions.should_send {
if receiver != author {
receivers.push(receiver);
}
}
}
receivers.shuffle(&mut self.rng);
let notification = {
let node = self.simulated_node(author);
node.node.create_notification(&node.context)
};
for receiver in receivers {
self.schedule_network_event(Event::DataSyncNotifyEvent {
sender: author,
receiver,
notification: notification.clone(),
});
}
// Schedule sending requests.
let mut senders = Vec::new();
if actions.should_query_all {
// TODO: similarly `should_query_all` is probably too coarse.
for index in 0..self.nodes.len() {
if index != author.0 {
senders.push(Author(index));
}
}
}
let request = {
let node = self.simulated_node(author);
node.node.create_request(&node.context)
};
let mut senders = senders.into_iter().collect::<Vec<_>>();
senders.shuffle(&mut self.rng);
for sender in senders {
self.schedule_network_event(Event::DataSyncRequestEvent {
receiver: author,
sender,
request: request.clone(),
});
}
}