diff --git a/src/electrumx.rs b/src/electrumx.rs index 8233432..509b29a 100644 --- a/src/electrumx.rs +++ b/src/electrumx.rs @@ -6,7 +6,7 @@ use r#type::*; // std use std::{str::FromStr, time::Duration}; // crates.io -use bitcoin::{Address, Network}; +use bitcoin::{Address, Amount, Network}; use reqwest::{Client as ReqwestClient, ClientBuilder as ReqwestClientBuilder}; use serde::{de::DeserializeOwned, Serialize}; use tokio::time; @@ -95,23 +95,27 @@ pub trait Api: Config + Http { where S: AsRef, { + let addr = address.as_ref(); + let sat = Amount::from_sat(satoshis); + loop { - for u in self.get_unspent_address(address.as_ref()).await? { - if u.atomicals.is_empty() && u.value >= satoshis { - tracing::info!( - "Detected Funding UTXO {txid}:{vout}) with value {value} for funding...", - txid = u.txid, - vout = u.vout, - value = u.value - ); - return Ok(u); - } + if let Some(u) = self + .get_unspent_address(addr) + .await? + .into_iter() + .find(|u| u.atomicals.is_empty() && u.value >= satoshis) + { + tracing::info!( + "funding UTXO detected {}:{} with a value of {} for funding purposes", + u.txid, + u.vout, + u.value + ); + return Ok(u); } tracing::info!( - "WAITING for UTXO... UNTIL {btc} BTC RECEIVED AT {addr}", - btc = satoshis as f64 / 100000000., - addr = address.as_ref() + "awaiting UTXO confirmation until {sat} BTC is received at address {addr}" ); time::sleep(Duration::from_secs(5)).await; diff --git a/src/electrumx/type.rs b/src/electrumx/type.rs index 584ad16..77e53ca 100644 --- a/src/electrumx/type.rs +++ b/src/electrumx/type.rs @@ -3,6 +3,8 @@ use std::collections::HashMap; // crates.io use serde::{Deserialize, Serialize}; +// TODO: We can remove the unused parts as much as possible. + #[derive(Debug, Serialize)] pub struct Params

where diff --git a/src/engine/js.rs b/src/engine/js.rs index 113f38f..2ad0af4 100644 --- a/src/engine/js.rs +++ b/src/engine/js.rs @@ -1,6 +1,7 @@ // std use std::{ fs::OpenOptions, + future::Future, io::{BufRead, BufReader, Write}, path::Path, process::{Command, Stdio}, @@ -9,7 +10,10 @@ use std::{ Arc, }, thread, + time::Duration, }; +// crates.io +use tokio::time; // atomicalsir use crate::{prelude::*, util, wallet::Wallet}; @@ -38,7 +42,7 @@ impl Wallet { tracing::info!("funding: {}", self.funding.address); let fee = if network == "livenet" { - let f = util::loop_fut(util::query_fee, "fee").await; + let f = loop_fut(util::query_fee, "fee").await; tracing::info!("current priority fee: {f} sat/vB"); @@ -110,7 +114,7 @@ fn execute(mut command: Command) -> Result<()> { _ => (), } - util::kill_process(pid)?; + kill_process(pid)?; break; } @@ -135,7 +139,7 @@ fn execute(mut command: Command) -> Result<()> { if l.contains("worker stopped with exit code 1") { tracing::error!("worker stopped with exit code 1; killing process"); - util::kill_process(pid)?; + kill_process(pid)?; break; } @@ -154,3 +158,28 @@ fn execute(mut command: Command) -> Result<()> { Ok(()) } + +async fn loop_fut(function: F, target: &str) -> T +where + F: Fn() -> Fut, + Fut: Future>, +{ + loop { + if let Ok(f) = function().await { + return f; + } + + tracing::error!("failed to query {target}; retrying in 1 minute"); + + time::sleep(Duration::from_secs(60)).await; + } +} + +fn kill_process(pid: u32) -> Result<()> { + #[cfg(any(target_os = "linux", target_os = "macos"))] + std::process::Command::new("kill").args(["-9", &pid.to_string()]).output()?; + #[cfg(target_os = "windows")] + std::process::Command::new("taskkill").args(["/F", "/PID", &pid.to_string()]).output()?; + + Ok(()) +} diff --git a/src/engine/rust.rs b/src/engine/rust.rs index cccf4a5..8468ce9 100644 --- a/src/engine/rust.rs +++ b/src/engine/rust.rs @@ -346,7 +346,7 @@ impl Miner { psbt.unsigned_tx.output.push(TxOut { value: Amount::ZERO, - script_pubkey: util::solution_tm_nonce_script(unixtime, seq), + script_pubkey: util::time_nonce_script(unixtime, seq), }); psbt.outputs.push(Default::default()); @@ -720,6 +720,8 @@ pub struct PayloadWrapper { #[derive(Debug, Serialize)] pub struct Payload { pub bitworkc: String, + // TODO: This field is unnecessary in the current version. + // pub bitworkr: Option, pub mint_ticker: String, pub nonce: u64, pub time: u64, diff --git a/src/util.rs b/src/util.rs index cd6381c..a9e8c68 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,8 +1,5 @@ // std -use std::{ - future::Future, - time::{Duration, SystemTime, UNIX_EPOCH}, -}; +use std::time::{SystemTime, UNIX_EPOCH}; // crates.io use bitcoin::{ opcodes::{ @@ -16,26 +13,9 @@ use bitcoin::{ use rand::Rng; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; -use tokio::time; // atomicalsir use crate::prelude::*; -pub async fn loop_fut(function: F, target: &str) -> T -where - F: Fn() -> Fut, - Fut: Future>, -{ - loop { - if let Ok(f) = function().await { - return f; - } - - tracing::error!("failed to query {target}; retrying in 1 minute"); - - time::sleep(Duration::from_secs(60)).await; - } -} - pub async fn query_fee() -> Result { #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase")] @@ -50,21 +30,18 @@ pub async fn query_fee() -> Result { .fastest_fee) } -pub fn kill_process(pid: u32) -> Result<()> { - #[cfg(any(target_os = "linux", target_os = "macos"))] - std::process::Command::new("kill").args(["-9", &pid.to_string()]).output()?; - #[cfg(target_os = "windows")] - std::process::Command::new("taskkill").args(["/F", "/PID", &pid.to_string()]).output()?; - - Ok(()) -} - pub fn time_nonce() -> (u64, u64) { ( SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(), rand::thread_rng().gen_range(1..10_000_000), ) } +pub fn time_nonce_script(time: u64, nonce: u32) -> ScriptBuf { + Script::builder() + .push_opcode(OP_RETURN) + .push_slice(<&PushBytes>::try_from(format!("{time}:{nonce}").as_bytes()).unwrap()) + .into_script() +} pub fn cbor(v: &T) -> Result> where @@ -168,13 +145,6 @@ fn build_reval_script_should_work() { ); } -pub fn solution_tm_nonce_script(time: u64, nonce: u32) -> ScriptBuf { - Script::builder() - .push_opcode(OP_RETURN) - .push_slice(<&PushBytes>::try_from(format!("{time}:{nonce}").as_bytes()).unwrap()) - .into_script() -} - pub fn address2scripthash(address: &Address) -> Result { let mut hasher = Sha256::new();