Skip to content
This repository has been archived by the owner on May 7, 2024. It is now read-only.

Commit

Permalink
Part II
Browse files Browse the repository at this point in the history
  • Loading branch information
aurexav committed Jan 21, 2024
1 parent b4e2132 commit 2948e0b
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 64 deletions.
84 changes: 79 additions & 5 deletions src/electrumx.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// TODO: Make this a single library.
// TODO: Use thiserror.

#[cfg(test)] mod test;

pub mod r#type;
Expand Down Expand Up @@ -139,6 +142,8 @@ impl<T> Api for T where T: Config + Http {}
#[derive(Debug)]
pub struct ElectrumX {
pub client: ReqwestClient,
pub retry_period: Duration,
pub max_retries: MaxRetries,
pub network: Network,
pub base_uri: String,
}
Expand All @@ -158,25 +163,62 @@ impl Http for ElectrumX {
P: Serialize,
R: DeserializeOwned,
{
let resp = self.client.post(uri.as_ref()).json(&params).send().await?.text().await?;
let u = uri.as_ref();

for _ in self.max_retries.clone() {
match self.client.post(u).json(&params).send().await {
Ok(r) => match r.json().await {
Ok(r) => return Ok(r),
Err(e) => {
tracing::error!("failed to parse response into JSON due to {e}");
},
},
Err(e) => {
tracing::error!("the request to {u} failed due to {e}");
},
}

tracing::debug!("{resp}");
time::sleep(self.retry_period).await;
}

Ok(serde_json::from_str(&resp)?)
Err(anyhow::anyhow!("exceeded maximum retries"))
}
}

#[derive(Debug)]
pub struct ElectrumXBuilder {
pub timeout: Duration,
pub retry_period: Duration,
pub max_retries: MaxRetries,
pub network: Network,
pub base_uri: String,
}
// TODO: Remove this cfg.
#[allow(unused)]
impl ElectrumXBuilder {
#[cfg(test)]
pub fn testnet() -> Self {
Self { network: Network::Testnet, base_uri: "https://eptestnet.atomicals.xyz/proxy".into() }

Check failure on line 201 in src/electrumx.rs

View workflow job for this annotation

GitHub Actions / clippy

missing fields `max_retries`, `retry_period` and `timeout` in initializer of `electrumx::ElectrumXBuilder`

error[E0063]: missing fields `max_retries`, `retry_period` and `timeout` in initializer of `electrumx::ElectrumXBuilder` --> src/electrumx.rs:201:3 | 201 | Self { network: Network::Testnet, base_uri: "https://eptestnet.atomicals.xyz/proxy".into() } | ^^^^ missing `max_retries`, `retry_period` and `timeout`
}

pub fn timeout(mut self, timeout: Duration) -> Self {
self.timeout = timeout;

self
}

pub fn retry_period(mut self, retry_period: Duration) -> Self {
self.retry_period = retry_period;

self
}

pub fn max_retries(mut self, max_retries: MaxRetries) -> Self {
self.max_retries = max_retries;

self
}

pub fn network(mut self, network: Network) -> Self {
self.network = network;

Expand All @@ -194,14 +236,46 @@ impl ElectrumXBuilder {

pub fn build(self) -> Result<ElectrumX> {
Ok(ElectrumX {
client: ReqwestClientBuilder::new().timeout(Duration::from_secs(30)).build()?,
client: ReqwestClientBuilder::new().timeout(self.timeout).build()?,
retry_period: self.retry_period,
max_retries: self.max_retries,
network: self.network,
base_uri: self.base_uri,
})
}
}
impl Default for ElectrumXBuilder {
fn default() -> Self {
Self { network: Network::Bitcoin, base_uri: "https://ep.atomicals.xyz/proxy".into() }
Self {
timeout: Duration::from_secs(30),
retry_period: Duration::from_secs(5),
max_retries: MaxRetries::Finite(5),
network: Network::Bitcoin,
base_uri: "https://ep.atomicals.xyz/proxy".into(),
}
}
}
// TODO: Remove this cfg.
#[allow(unused)]
#[derive(Debug, Clone)]
pub enum MaxRetries {
Infinite,
Finite(u8),
}
impl Iterator for MaxRetries {
type Item = ();

fn next(&mut self) -> Option<Self::Item> {
match self {
Self::Infinite => Some(()),
Self::Finite(n) =>
if *n > 0 {
*n -= 1;

Some(())
} else {
None
},
}
}
}
75 changes: 16 additions & 59 deletions src/engine/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use std::{
atomic::{AtomicBool, Ordering},
Arc, Mutex,
},
thread::{self, sleep, JoinHandle},
time::{Duration, SystemTime, UNIX_EPOCH},
thread::{self, JoinHandle},
time::{SystemTime, UNIX_EPOCH},
};
// crates.io
use bitcoin::{
Expand Down Expand Up @@ -63,9 +63,7 @@ struct Miner {
}
impl Miner {
const BASE_BYTES: f64 = 10.5;
const BROADCAST_SLEEP_SECONDS: u32 = 15;
const INPUT_BYTES_BASE: f64 = 57.5;
const MAX_BROADCAST_NUM: u32 = 20;
const MAX_SEQUENCE: u32 = u32::MAX;
// OP_RETURN size
// 8-bytes value(roughly estimate), a one-byte script’s size
Expand Down Expand Up @@ -224,37 +222,16 @@ impl Miner {

// TODO: If no solution found.
let commit_tx = maybe_commit_tx.lock().unwrap().take().unwrap();

let commit_txid = commit_tx.txid();
// tracing::info!("commit txid {}", commit_txid);
tracing::info!("Broadcasting commit tx...");
let raw_tx = encode::serialize_hex(&commit_tx);
tracing::info!("raw tx: {}", &raw_tx);

let mut attempts = 0;
while attempts < Self::MAX_BROADCAST_NUM {
if let Err(_) = self.api.broadcast(raw_tx.clone()).await {
tracing::info!(
"Network error, will retry to broadcast commit transaction in {} seconds...",
Self::BROADCAST_SLEEP_SECONDS
);
sleep(Duration::from_secs(15));
attempts += 1;
continue;
}
break;
}
let commit_tx_hex = encode::serialize_hex(&commit_tx);

if attempts < Self::MAX_BROADCAST_NUM {
tracing::info!("Successfully sent commit tx {commit_txid}");
} else {
tracing::info!("❌ Failed to send commit tx {commit_txid}");
return Ok(());
}
tracing::info!("broadcasting commit transaction {commit_txid}");
tracing::debug!("{commit_tx:#?}");
tracing::info!("{commit_tx_hex}");

tracing::info!("\nCommit workers have completed their tasks for the commit transaction.\n");
// TODO?: Handle result.
self.api.broadcast(commit_tx_hex).await?;

let commit_txid = commit_tx.txid();
let commit_txid_ = self
.api
.wait_until_utxo(
Expand Down Expand Up @@ -291,6 +268,7 @@ impl Miner {

for i in 0..concurrency {
tracing::info!("spawning reveal worker thread {i} for bitworkr");

let secp = secp.clone();
let bitworkr = bitworkr.clone();
let funding_kp = wallet.funding.pair;
Expand Down Expand Up @@ -332,11 +310,9 @@ impl Miner {
(seq + 10000).min(seq_end)
);
}

if solution_found.load(Ordering::Relaxed) {
return Ok(());
}

if nonces_generated % 10000 == 0 {
unixtime =
SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs();
Expand Down Expand Up @@ -472,34 +448,15 @@ impl Miner {

psbt.extract_tx_unchecked_fee_rate()
};

let reveal_txid = reveal_tx.txid();
tracing::info!("reveal txid {}", reveal_txid);
tracing::info!("reveal tx {reveal_tx:#?}");

tracing::info!("Broadcasting reveal tx...");
let raw_tx = encode::serialize_hex(&reveal_tx);
tracing::info!("raw tx: {}", &raw_tx);
let mut attempts = 0;
while attempts < Self::MAX_BROADCAST_NUM {
if let Err(_) = self.api.broadcast(raw_tx.clone()).await {
tracing::info!(
"Network error, will retry to broadcast reveal transaction in {} seconds...",
Self::BROADCAST_SLEEP_SECONDS
);
sleep(Duration::from_secs(15));
attempts += 1;
continue;
}
break;
}
let reveal_tx_hex = encode::serialize_hex(&reveal_tx);

if attempts < Self::MAX_BROADCAST_NUM {
tracing::info!("✅ Successfully sent reveal tx {reveal_txid}");
tracing::info!("✨Congratulations! Mission completed.✨");
} else {
tracing::info!("❌ Failed to send reveal tx {reveal_txid}");
}
tracing::info!("broadcasting reveal transaction {reveal_txid}");
tracing::debug!("{reveal_tx:#?}");
tracing::info!("{reveal_tx_hex}");

// TODO?: Handle result.
self.api.broadcast(reveal_tx_hex).await?;

Ok(())
}
Expand Down

0 comments on commit 2948e0b

Please sign in to comment.