Files
nanoreth/crates/net/network/tests/it/geth.rs
2023-07-04 10:15:52 +00:00

129 lines
4.6 KiB
Rust

use crate::clique::{CliqueGethInstance, CliqueMiddleware};
use ethers_core::{
types::{transaction::eip2718::TypedTransaction, Eip1559TransactionRequest, H160, U64},
utils::Geth,
};
use ethers_providers::Middleware;
use reth_network::{
test_utils::{unused_tcp_and_udp_port, unused_tcp_udp, NetworkEventStream},
NetworkConfig, NetworkManager,
};
use reth_network_api::Peers;
use reth_primitives::{ChainSpec, Genesis, PeerId, SealedHeader};
use reth_provider::test_utils::NoopProvider;
use secp256k1::SecretKey;
use std::{net::SocketAddr, sync::Arc};
#[tokio::test(flavor = "multi_thread")]
#[cfg_attr(not(feature = "geth-tests"), ignore)]
async fn can_peer_with_geth() {
reth_tracing::init_test_tracing();
let (clique, chainspec) = init_geth().await;
let geth_p2p_port = clique.instance.p2p_port().unwrap();
// === initialize reth networking stack ===
let secret_key = SecretKey::new(&mut rand::thread_rng());
let (reth_p2p, reth_disc) = unused_tcp_udp();
tracing::info!(
%reth_p2p,
%reth_disc,
"setting up reth networking stack in keepalive test"
);
let config = NetworkConfig::<Arc<NoopProvider>>::builder(secret_key)
.listener_addr(reth_p2p)
.discovery_addr(reth_disc)
.chain_spec(chainspec)
.build(Arc::new(NoopProvider::default()));
let network = NetworkManager::new(config).await.unwrap();
let handle = network.handle().clone();
tokio::task::spawn(network);
// create networkeventstream to get the next session established event easily
let mut events = NetworkEventStream::new(handle.event_listener());
let geth_socket = SocketAddr::new([127, 0, 0, 1].into(), geth_p2p_port);
// get the peer id we should be expecting
let geth_peer_id: PeerId = clique.provider.peer_id().await.unwrap();
// add geth as a peer then wait for `PeerAdded` and `SessionEstablished` events.
handle.add_peer(geth_peer_id, geth_socket);
// wait for the session to be established
let peer_id = events.peer_added_and_established().await.unwrap();
assert_eq!(geth_peer_id, peer_id);
}
async fn init_geth() -> (CliqueGethInstance, Arc<ChainSpec>) {
// first create a signer that we will fund so we can make transactions
let chain_id = 13337u64;
let data_dir = tempfile::tempdir().expect("should be able to create temp geth datadir");
let dir_path = data_dir.path();
tracing::info!(
data_dir=?dir_path,
"initializing geth instance"
);
// this creates a funded geth
let clique_geth = Geth::new()
.chain_id(chain_id)
.p2p_port(unused_tcp_and_udp_port())
.data_dir(dir_path.to_str().unwrap());
// build the funded geth
let mut clique = CliqueGethInstance::new(clique_geth, None).await;
let geth_p2p_port =
clique.instance.p2p_port().expect("geth should be configured with a p2p port");
tracing::info!(
p2p_port=%geth_p2p_port,
rpc_port=%clique.instance.port(),
"configured clique geth instance in keepalive test"
);
// don't print logs, but drain the stderr
clique.prevent_blocking().await;
// get geth to start producing blocks - use a blank password
let clique_private_key = clique
.instance
.clique_private_key()
.clone()
.expect("clique should be configured with a private key");
clique.provider.enable_mining(clique_private_key, "".into()).await.unwrap();
// === check that we have the same genesis hash ===
// get the chainspec from the genesis we configured for geth
let chainspec = ChainSpec::from(Genesis::from(
clique.instance.genesis().clone().expect("clique should be configured with a genesis"),
));
let remote_genesis = SealedHeader::from(&clique.provider.remote_genesis_block().await.unwrap());
let local_genesis = chainspec.genesis_header().seal(chainspec.genesis_hash());
assert_eq!(local_genesis, remote_genesis, "genesis blocks should match, we computed {local_genesis:#?} but geth computed {remote_genesis:#?}");
// === create many blocks ===
let nonces = 0..1000u64;
let txs = nonces.map(|nonce| {
// create a tx that just sends to the zero addr
TypedTransaction::Eip1559(
Eip1559TransactionRequest::new().to(H160::zero()).value(1u64).nonce(nonce),
)
});
tracing::info!("generated transactions for blocks");
// finally send the txs to geth
clique.provider.send_requests(txs).await.unwrap();
let block = clique.provider.get_block_number().await.unwrap();
assert!(block > U64::zero());
(clique, Arc::new(chainspec))
}