reth_seismic_node/
utils.rs

1//! test utils for the e2e tests
2
3/// Test utils for the seismic rpc api
4pub mod test_utils {
5    use alloy_primitives::Address;
6    use alloy_rpc_types::{Block, Header, Transaction, TransactionReceipt};
7    use jsonrpsee::http_client::HttpClient;
8    use reth_rpc_eth_api::EthApiClient;
9    use reth_seismic_chainspec::SEISMIC_DEV;
10    use serde_json::Value;
11    use std::{path::PathBuf, process::Stdio};
12    use tokio::{
13        io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
14        process::Command,
15        sync::mpsc,
16    };
17
18    pub use reth_seismic_primitives::test_utils::{
19        client_decrypt, client_encrypt, get_ciphertext, get_client_io_sk, get_encryption_nonce,
20        get_network_public_key, get_plaintext, get_seismic_elements, get_seismic_tx,
21        get_signed_seismic_tx, get_signed_seismic_tx_bytes, get_signed_seismic_tx_encoding,
22        get_signed_seismic_tx_typed_data, get_signing_private_key, get_unsigned_seismic_tx_request,
23        get_unsigned_seismic_tx_typed_data, get_wrong_private_key, sign_seismic_tx, sign_tx,
24    };
25
26    // use reth_seismic_evm::engine::SeismicEngineValidator;
27    /// Seismic reth test command
28    #[derive(Debug)]
29    pub struct SeismicRethTestCommand();
30    impl SeismicRethTestCommand {
31        /// Run the seismic reth test command
32        pub async fn run(tx: mpsc::Sender<()>, mut shutdown_rx: mpsc::Receiver<()>) {
33            let output = Command::new("cargo")
34                .arg("metadata")
35                .arg("--format-version=1")
36                .output()
37                .await
38                .unwrap();
39            let metadata: Value = serde_json::from_slice(&output.stdout).unwrap();
40            let workspace_root = metadata.get("workspace_root").unwrap().as_str().unwrap();
41            println!("Workspace root: {}", workspace_root);
42
43            let mut child = Command::new("cargo")
44                .arg("run")
45                .arg("--bin")
46                .arg("seismic-reth") // Specify the binary name
47                .arg("--")
48                .arg("node")
49                .arg("--datadir")
50                .arg(SeismicRethTestCommand::data_dir().to_str().unwrap())
51                .arg("--dev")
52                .arg("--dev.block-max-transactions")
53                .arg("1")
54                .arg("--enclave.mock-server")
55                .arg("-vvvv")
56                .current_dir(workspace_root)
57                .stdout(Stdio::piped())
58                .stderr(Stdio::piped())
59                .spawn()
60                .expect("Failed to start the binary");
61
62            tokio::spawn(async move {
63                let stdout = child.stdout.as_mut().expect("Failed to capture stdout");
64                let stderr = child.stderr.as_mut().expect("Failed to capture stderr");
65                let mut stdout_reader = BufReader::new(stdout);
66                let mut stderr_reader = BufReader::new(stderr);
67                let mut stdout_line = String::new();
68                let mut stderr_line = String::new();
69                let mut sent = false;
70                std::panic::set_hook(Box::new(|info| {
71                    eprintln!("❌ PANIC DETECTED: {:?}", info);
72                }));
73
74                loop {
75                    tokio::select! {
76                        result = stdout_reader.read_line(&mut stdout_line) => {
77                            if result.unwrap() == 0 {
78                                eprintln!("🛑 STDOUT reached EOF! Breaking loop.");
79                                break;
80                            }
81                            eprint!("{}", stdout_line);
82
83                            if stdout_line.contains("Starting consensus engine") && !sent {
84                                eprintln!("🚀 Reth server is ready!");
85                                let _ = tx.send(()).await;
86                                sent = true;
87                            }
88                            stdout_line.clear();
89                            tokio::io::stdout().flush().await.unwrap();
90                        }
91
92                        result = stderr_reader.read_line(&mut stderr_line) => {
93                            if result.unwrap() == 0 {
94                                eprintln!("🛑 STDERR reached EOF! Breaking loop.");
95                                break;
96                            }
97                            eprint!("{}", stderr_line);
98                            stderr_line.clear();
99                        }
100
101                        Some(_) = shutdown_rx.recv() => {
102                            eprintln!("🛑 Shutdown signal received! Breaking loop.");
103                            break;
104                        }
105                    }
106                }
107                println!("✅ Exiting loop.");
108
109                child.kill().await.unwrap();
110                println!("✅ Killed child process.");
111            });
112        }
113
114        /// Get the data directory for the seismic reth test command
115        pub fn data_dir() -> PathBuf {
116            static TEMP_DIR: once_cell::sync::Lazy<tempfile::TempDir> =
117                once_cell::sync::Lazy::new(|| tempfile::tempdir().unwrap());
118            TEMP_DIR.path().to_path_buf()
119        }
120
121        /// Get the chain id for the seismic reth test command
122        pub fn chain_id() -> u64 {
123            SEISMIC_DEV.chain().into()
124        }
125
126        /// Get the url for the seismic reth test command
127        pub fn url() -> String {
128            format!("http://127.0.0.1:8545")
129        }
130    }
131
132    /// Get the nonce from the client
133    pub async fn get_nonce(client: &HttpClient, address: Address) -> u64 {
134        let nonce =
135            EthApiClient::<Transaction, Block, TransactionReceipt, Header>::transaction_count(
136                client, address, None,
137            )
138            .await
139            .unwrap();
140        nonce.wrapping_to::<u64>()
141    }
142}