use crate::testutils::{
test_framework::TestFramework,
test_node::{NodeId, NodeType, TestNode},
};
use aptos_config::{
config::NodeConfig,
network_id::{NetworkId, PeerNetworkId},
};
use rand::{rngs::StdRng, SeedableRng};
use std::{collections::HashMap, marker::PhantomData};
pub struct TestFrameworkBuilder<Framework: TestFramework<Node>, Node: TestNode> {
owners: u32,
nodes: HashMap<NodeId, Node>,
rng: StdRng,
_framework_marker: PhantomData<Framework>,
}
impl<Framework: TestFramework<Node>, Node: TestNode> TestFrameworkBuilder<Framework, Node> {
pub fn new(owners: u32) -> Self {
Self {
owners,
nodes: HashMap::new(),
rng: StdRng::from_seed([0u8; 32]),
_framework_marker: PhantomData::default(),
}
}
pub fn build(self) -> Framework {
TestFramework::new(self.nodes)
}
pub fn add_validator(mut self, owner: u32) -> Self {
let config = NodeConfig::random_with_template(
owner,
&NodeConfig::default_for_validator(),
&mut self.rng,
);
let peer_id = config
.validator_network
.as_ref()
.expect("Validator must have a validator network")
.peer_id();
self.add_node(
owner,
NodeType::Validator,
config,
&[
PeerNetworkId::new(NetworkId::Validator, peer_id),
PeerNetworkId::new(NetworkId::Vfn, peer_id),
],
)
}
pub fn add_vfn(mut self, owner: u32) -> Self {
let config = NodeConfig::random_with_template(
owner,
&NodeConfig::default_for_validator_full_node(),
&mut self.rng,
);
let peer_id = config
.full_node_networks
.iter()
.find(|network| network.network_id == NetworkId::Public)
.expect("Vfn must have a public network")
.peer_id();
self.add_node(
owner,
NodeType::ValidatorFullNode,
config,
&[
PeerNetworkId::new(NetworkId::Vfn, peer_id),
PeerNetworkId::new(NetworkId::Public, peer_id),
],
)
}
pub fn add_pfn(mut self, owner: u32) -> Self {
let config = NodeConfig::random_with_template(
owner,
&NodeConfig::default_for_public_full_node(),
&mut self.rng,
);
let peer_id = config
.full_node_networks
.iter()
.find(|network| network.network_id == NetworkId::Public)
.expect("Pfn must have a public network")
.peer_id();
self.add_node(
owner,
NodeType::PublicFullNode,
config,
&[PeerNetworkId::new(NetworkId::Public, peer_id)],
)
}
fn add_node(
mut self,
owner: u32,
node_type: NodeType,
config: NodeConfig,
peer_network_ids: &[PeerNetworkId],
) -> Self {
assert!(owner < self.owners);
let node_id = NodeId { owner, node_type };
assert!(!self.nodes.contains_key(&node_id));
let mut node = Framework::build_node(node_id, config, peer_network_ids);
for (other_node_id, other_node) in self.nodes.iter_mut() {
if let Some(network_id) = other_node.find_common_network(&node) {
if network_id == NetworkId::Vfn && owner != other_node_id.owner {
continue;
}
add_inbound_peer_handle_to_node(network_id, other_node, &node);
add_inbound_peer_handle_to_node(network_id, &mut node, other_node);
}
}
self.nodes.insert(node_id, node);
self
}
pub fn single_validator() -> Node {
let mut test_framework: Framework = TestFrameworkBuilder::new(1).add_validator(0).build();
test_framework.take_node(NodeId::validator(0))
}
pub fn single_vfn() -> Node {
let mut test_framework: Framework = TestFrameworkBuilder::new(1).add_vfn(0).build();
test_framework.take_node(NodeId::vfn(0))
}
pub fn single_pfn() -> Node {
let mut test_framework: Framework = TestFrameworkBuilder::new(1).add_pfn(0).build();
test_framework.take_node(NodeId::pfn(0))
}
}
fn add_inbound_peer_handle_to_node<Node: TestNode>(
network_id: NetworkId,
sending_node: &mut Node,
receiving_node: &Node,
) {
sending_node.add_inbound_handle_for_peer(
receiving_node.peer_network_id(network_id),
receiving_node.get_inbound_handle(network_id),
);
}