Skip to content

Commit

Permalink
Merge pull request #18 from Duddino/wait_pivxd
Browse files Browse the repository at this point in the history
Wait for pivxd to finish loading before creating explorer
  • Loading branch information
Duddino authored Oct 7, 2024
2 parents 37cc6a8 + 42de4cc commit de1f2ae
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 15 deletions.
10 changes: 10 additions & 0 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ sha256 = "1.5.0"
futures = "0.3.30"
rusqlite = "0.32.1"
jsonrpsee = { version = "0.24.4", features = ["client-core"] }
tokio = "1.40.0"
tokio = { version = "1.40.0", features = ["process"] }
base64 = "0.22.1"
hex = "0.4.3"
bs58 = "0.5.1"
Expand Down
5 changes: 4 additions & 1 deletion src-tauri/src/address_index/pivx_rpc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod json_rpc;
mod test;

use crate::binary::Binary;
use crate::error::PIVXErrors;

use super::block_source::{BlockSource, BlockSourceType, IndexedBlockSource, PinnedStream};
Expand All @@ -21,6 +22,7 @@ use std::task::{Context, Poll};
#[derive(Clone)]
pub struct PIVXRpc {
client: HttpClient,
_pivx: Arc<Binary>,
}

type BlockStreamFuture = Pin<Box<dyn Future<Output = Option<(Block, u64)>> + Send>>;
Expand Down Expand Up @@ -90,7 +92,7 @@ impl Stream for BlockStream {
}

impl PIVXRpc {
pub async fn new(url: &str) -> crate::error::Result<Self> {
pub async fn new(url: &str, pivx: Binary) -> crate::error::Result<Self> {
let mut headers = HeaderMap::new();
let credentials = format!("{}:{}", crate::RPC_USERNAME, crate::RPC_PASSWORD);
headers.insert(
Expand All @@ -101,6 +103,7 @@ impl PIVXRpc {
);
Ok(PIVXRpc {
client: HttpClient::builder().set_headers(headers).build(url)?,
_pivx: Arc::new(pivx),
})
}

Expand Down
21 changes: 17 additions & 4 deletions src-tauri/src/binary/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use crate::error::PIVXErrors;
use std::fs::File;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process::{Child, Command, Stdio};
use std::process::Stdio;
use tokio::process::{Child, Command};

pub trait BinaryDefinition {
fn get_url(&self) -> &str;
Expand All @@ -14,6 +15,7 @@ pub trait BinaryDefinition {
fn decompress_archive(&self, dir: &Path) -> Result<(), PIVXErrors>;
fn get_binary_path(&self, base_dir: &Path) -> PathBuf;
fn get_binary_args(&self, base_dir: &Path) -> Result<Vec<String>, PIVXErrors>;
async fn wait_for_load(&self, handle: &mut Child) -> crate::error::Result<()>;
}

pub struct Binary {
Expand All @@ -23,8 +25,8 @@ pub struct Binary {
impl Drop for Binary {
fn drop(&mut self) {
// This sends SIGKILL so this should be refactored to send SIGTERM
self.handle.kill().expect("Failed to kill pivxd");
self.handle.wait().expect("Failed to wait");
// self.handle.kill().expect("Failed to kill pivxd");
// self.handle.wait().expect("Failed to wait");
}
}

Expand Down Expand Up @@ -79,7 +81,8 @@ impl Binary {
}
let handle = Command::new(path)
.args(binary_definition.get_binary_args(&data_dir)?)
.stdout(Stdio::null())
.stdout(Stdio::piped())
.kill_on_drop(true)
.spawn()
.map_err(|_| PIVXErrors::PivxdNotFound)?;
Ok(Binary { handle })
Expand All @@ -96,4 +99,14 @@ impl Binary {
}
Self::new_by_path(&binary_path.to_string_lossy(), binary_definition)
}

/**
* Resolves when binary finishes to load
*/
pub async fn wait_for_load<T: BinaryDefinition + Send>(
&mut self,
binary_definition: &T,
) -> crate::error::Result<()> {
binary_definition.wait_for_load(&mut self.handle).await
}
}
3 changes: 3 additions & 0 deletions src-tauri/src/binary/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ impl BinaryDefinition for TestBinary {
fn get_binary_args(&self, _: &Path) -> Result<Vec<String>, PIVXErrors> {
unimplemented!()
}
async fn wait_for_load(&self, _handle: &mut Child) -> crate::error::Result<()> {
Ok(())
}
}
mod pivx_fetch {
use super::*;
Expand Down
3 changes: 3 additions & 0 deletions src-tauri/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pub enum PIVXErrors {

#[error("Failed to fetch sapling params")]
FetchParamsFailed,

#[error("PIVXD was stopped before loading was finished")]
PivxdStopped,
}

pub type Result<T> = std::result::Result<T, PIVXErrors>;
12 changes: 3 additions & 9 deletions src-tauri/src/explorer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,7 @@ use crate::binary::Binary;
use crate::{PIVXDefinition, RPC_PORT};
use global_function_macro::generate_global_functions;

//#[derive(Deserialize, Serialize)]
type TxHexWithBlockCount = (String, u64, u64);
/*struct TxHexWithBlockCount {
hex: String,
time: u64,
height: u64,
}*/

#[derive(Clone)]
pub struct Explorer<D>
Expand Down Expand Up @@ -48,10 +42,11 @@ async fn get_explorer() -> &'static DefaultExplorer {
EXPLORER
.get_or_init(|| async {
let pivx_definition = PIVXDefinition;
let pivx = Binary::new_by_fetching(&pivx_definition)
let mut pivx = Binary::new_by_fetching(&pivx_definition)
.await
.expect("Failed to run PIVX");
let pivx_rpc = PIVXRpc::new(&format!("http://127.0.0.1:{}", RPC_PORT))
pivx.wait_for_load(&pivx_definition).await.unwrap();
let pivx_rpc = PIVXRpc::new(&format!("http://127.0.0.1:{}", RPC_PORT), pivx)
.await
.unwrap();
// FIXME: refactor this to accept HOME
Expand All @@ -61,7 +56,6 @@ async fn get_explorer() -> &'static DefaultExplorer {
.unwrap(),
pivx_rpc.clone(),
);
std::mem::forget(pivx);

let explorer = Explorer::new(address_index, pivx_rpc);
// Cloning is very cheap, it's just a Pathbuf and some Arcs
Expand Down
24 changes: 24 additions & 0 deletions src-tauri/src/pivx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::fs::File;
use std::path::{Path, PathBuf};
use std::process::Command;
use tar::Archive;
use tokio::io::{AsyncBufReadExt, BufReader};

use crate::binary::BinaryDefinition;

Expand Down Expand Up @@ -83,4 +84,27 @@ impl BinaryDefinition for PIVXDefinition {
);
Ok(args.split(" ").map(|s| s.to_string()).collect::<Vec<_>>())
}

async fn wait_for_load(&self, handle: &mut tokio::process::Child) -> crate::error::Result<()> {
let stdout = handle.stdout.take();
match stdout {
Some(stdout) => {
let mut reader = BufReader::new(stdout);
let mut line = String::new();
loop {
let read_bytes = reader.read_line(&mut line).await?;
if read_bytes == 0 {
return Err(PIVXErrors::PivxdStopped);
}
if line.contains("asking peer for sporks") {
break;
}
}
}
None => eprintln!(
"Warning: couldn't wait for load because no stdout is attached to the handle."
),
}
Ok(())
}
}

0 comments on commit de1f2ae

Please sign in to comment.