---
# System prepended metadata

title: Untitled

---


Notes for delivery:
- how to simulate a bad network 


```
#[test]
	fn custom_node_setup_works() {
		// build a node with the default network id
		let default_node = setup_core_builder();

		// custom node configuration
		let mut custom_network_id = "/custom-protocol/1.0".to_string();
		let mut custom_transport = TransportOpts::TcpQuic {
			tcp_config: TcpConfig::Custom {
				ttl: 10,
				nodelay: true,
				backlog: 10,
			},
		};
		let mut custom_keep_alive_duration = 20;
		let mut custom_ip_address = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));

		// pass in the custom node configuration and assert it works as expected
		let custom_node = default_node
			.with_network_id(custom_network_id.clone())
			.with_transports(custom_transport.clone())
			.with_idle_connection_timeout(custom_keep_alive_duration.clone())
			.listen_on(custom_ip_address.clone());

		// assert that the custom network id is '/custom/protocol/1.0'
		assert_eq!(custom_node.network_id(), custom_network_id);

		// assert that the custom transport is 'TcpQuic'
		assert_eq!(custom_node.transport, custom_transport);

		// assert that the custom keep alive duration is 20
		assert_eq!(custom_node.keep_alive_duration, custom_keep_alive_duration);
	}


	#[test]
	fn kademlia_read_works() {

		// e.g. if a record is not found, it should return a specific message
		
		// build a node with the default network id
		let default_node = setup_core_builder();

		// pass in the custom kademlia configuration and assert it works as expected
		let custom_node = default_node.with_kademlia(kad::Config::default());

	}
	
	#[test]
	fn node_setup_with_custom_ping_works(){
		// e.g. if the node is unreachable after a specific amount of time, it should be
		// disconnected if 10th inteval is configured, if failed 9th time, test decay as each ping
		// comes in

		// build a node with the default network id
		let default_node = setup_core_builder();

		// custom ping configuration
		let custom_ping = PingConfig {
			interval: Duration::from_secs(5),
			timeout: Duration::from_secs(10),
			err_policy: PingErrorPolicy::DisconnectAfterMaxErrors(10),
		};

		// pass in the custom ping configuration and assert it works as expected
		let custom_node = default_node.with_ping(custom_ping.clone());

		let ping_from_custom_node = custom_node.ping;

		// The peer will be disconnected after 20 successive timeout errors are recorded

		println!("❤️❤️❤️❤️❤️{:?}", ping_from_custom_node.1);
	}

	// TODO: add test for timeout after 5 trials from `received_from_network`
	#[test]
	fn timeout_works_as_expected() {
		// TODO
	}

	// TODO: test that the decay on duration works as expected until a node disconnects
	#[test]
	fn decay_works_as_expected() {

		// test with a Ping event
		// CoreEvent::Ping(ping::Event {
		// 	peer,
		// 	connection: _,
		// 	result,
		// }
	}
    
    
    
    ```
    
    ```rust
    /// Used to create a deterministic node.
pub async fn setup_node(peer_id: PeerId, ports: (u16, u16)) -> Core<Ping> {
	use std::collections::HashMap;
	// App state
	let app_state = Ping;

	// Custom ping configuration
	let custom_ping = PingConfig {
		interval: Duration::from_secs(3),
		timeout: Duration::from_secs(5),
		err_policy: PingErrorPolicy::DisconnectAfterMaxErrors(3),
	};

	// Set up bootnode to query node 1
	let mut bootnode = HashMap::new();
	bootnode.insert(
		peer_id.to_base58(),
		format!("/ip4/127.0.0.1/tcp/{}", ports.0),
	);

	println!("Second node here!");

	// First, we want to configure our node
	let config = BootstrapConfig::new().with_bootnodes(bootnode);

	// Set up network by passing in a default handler or application state
	CoreBuilder::with_config(config, app_state)
		.with_ping(custom_ping)
		.build()
		.await
		.unwrap()
}

/// Used to create a node to peer with node_1.
pub async fn setup_node_2(node_1_ports: (Port, Port), ports: (Port, Port)) -> Core<AppState> {
	let app_state = AppState;

	// Our test keypair for the node_1
	let mut protobuf = vec![
		8, 1, 18, 64, 34, 116, 25, 74, 122, 174, 130, 2, 98, 221, 17, 247, 176, 102, 205, 3, 27,
		202, 193, 27, 6, 104, 216, 158, 235, 38, 141, 58, 64, 81, 157, 155, 36, 193, 50, 147, 85,
		72, 64, 174, 65, 132, 232, 78, 231, 224, 88, 38, 55, 78, 178, 65, 42, 97, 39, 152, 42, 164,
		148, 159, 36, 170, 109, 178,
	];

	// The PeerId of the first node
	let peer_id = Keypair::from_protobuf_encoding(&protobuf)
		.unwrap()
		.public()
		.to_peer_id();

	// Set up bootnode to query node 1
	let mut bootnode = HashMap::new();
	bootnode.insert(
		peer_id.to_base58(),
		format!("/ip4/127.0.0.1/tcp/{}", ports.0),
	);

	println!("Second node here!");

	// First, we want to configure our node
	let config = BootstrapConfig::new()
		.with_bootnodes(bootnode)
		.with_tcp(ports.0)
		.with_udp(ports.1);

	// Set up network
	CoreBuilder::with_config(config, app_state)
		.build()
		.await
		.unwrap()
}
```