ephemeral_validator.rs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. use anyhow::Result;
  2. use std::process::Stdio;
  3. pub struct EphemeralValidator;
  4. impl EphemeralValidator {
  5. pub fn is_available() -> bool {
  6. which::which("ephemeral-validator").is_ok()
  7. }
  8. async fn wait_for_basenet() -> Result<()> {
  9. let balance = tokio::spawn(async move {
  10. loop {
  11. let status = std::process::Command::new("solana")
  12. .arg("balance")
  13. .stdout(Stdio::null())
  14. .stderr(Stdio::null())
  15. .status()
  16. .expect("Failed to check solana balance");
  17. if status.success() {
  18. break;
  19. }
  20. std::thread::sleep(std::time::Duration::from_secs(1));
  21. }
  22. });
  23. balance.await.expect("Failed to check solana balance");
  24. Ok(())
  25. }
  26. pub async fn start() -> Result<Self> {
  27. if !Self::is_available() {
  28. return Err(anyhow::anyhow!("ephemeral-validator not available"));
  29. }
  30. Self::wait_for_basenet().await?;
  31. Self::cleanup()?;
  32. let temp_file = std::env::temp_dir().join("ephemeral-validator.toml");
  33. std::fs::write(
  34. &temp_file,
  35. include_str!("templates/ephemeral-validator.toml"),
  36. )
  37. .expect("Failed to write ephemeral validator config");
  38. tokio::process::Command::new("ephemeral-validator")
  39. .arg(temp_file)
  40. .spawn()
  41. .expect("Failed to start ephemeral validator");
  42. println!("Ephemeral validator started");
  43. Ok(Self)
  44. }
  45. pub fn cleanup() -> Result<()> {
  46. let mut system = sysinfo::System::new_all();
  47. system.refresh_processes(sysinfo::ProcessesToUpdate::All, true);
  48. let processes = system.processes();
  49. for process in processes.values() {
  50. if let Some(name) = process
  51. .exe()
  52. .and_then(|path| path.file_name())
  53. .and_then(|name| name.to_str())
  54. {
  55. if name == "ephemeral-validator" {
  56. process
  57. .kill_with(sysinfo::Signal::Term)
  58. .expect("Failed to kill ephemeral validator");
  59. }
  60. }
  61. }
  62. Ok(())
  63. }
  64. }
  65. impl Drop for EphemeralValidator {
  66. fn drop(&mut self) {
  67. if EphemeralValidator::is_available() {
  68. EphemeralValidator::cleanup().expect("Failed to cleanup ephemeral validator");
  69. }
  70. }
  71. }