fn process_node_actions()

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(),
            });
        }
    }