Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
Cargo.lock
/target/

# Testing infrastructure (development only, not for upstream)
/test/
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,5 @@ rustix = { version = "0.38", features = ["fs", "termios"] }
slotmap = "1.0"
tokio-udev = "0.10"
udev = "0.9"
toml = "0.8"
rand = "0.8"
7 changes: 7 additions & 0 deletions mujina-miner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ regex = { workspace = true }
reqwest = { workspace = true }
rustix = { workspace = true }
slotmap = { workspace = true }
toml = { workspace = true }
rand = { workspace = true }

# Stratum V2 dependencies (aligned with sv2-apps v0.1.0)
stratum-core = "0.1.0"
stratum-apps = { git = "https://github.com/stratum-mining/sv2-apps", tag = "v0.1.0", features = ["network"] }
async-channel = "1.8.0"

[target.'cfg(target_os = "linux")'.dependencies]
tokio-udev = { workspace = true }
Expand Down
96 changes: 66 additions & 30 deletions mujina-miner/src/daemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
api::{self, ApiConfig},
backplane::Backplane,
hash_thread::HashThread,
job_source::{dummy::DummySource, stratum_v1::StratumV1Source, SourceEvent},
job_source::{dummy::DummySource, stratum_v1::StratumV1Source, stratum_v2::StratumV2Source, SourceEvent},
scheduler::{self, SourceRegistration},
stratum_v1::PoolConfig as StratumPoolConfig,
transport::{TransportEvent, UsbTransport},
Expand Down Expand Up @@ -73,39 +73,75 @@ impl Daemon {
let (source_cmd_tx, source_cmd_rx) = mpsc::channel(10);

if let Ok(pool_url) = std::env::var("MUJINA_POOL_URL") {
// Use Stratum v1 source
let pool_user =
std::env::var("MUJINA_POOL_USER").unwrap_or_else(|_| "mujina-testing".to_string());
let pool_pass = std::env::var("MUJINA_POOL_PASS").unwrap_or_else(|_| "x".to_string());

let stratum_config = StratumPoolConfig {
url: pool_url,
username: pool_user,
password: pool_pass,
user_agent: "mujina-miner/0.1.0-alpha".to_string(),
suggested_difficulty: 1024,
};

let stratum_source = StratumV1Source::new(
stratum_config,
source_cmd_rx,
source_event_tx,
self.shutdown.clone(),
);

source_reg_tx
.send(SourceRegistration {
name: "stratum-v1".into(),
event_rx: source_event_rx,
command_tx: source_cmd_tx,
})
.await?;

self.tracker.spawn(async move {
if let Err(e) = stratum_source.run().await {
error!("Stratum v1 source error: {}", e);
}
});
// Protocol detection based on URL scheme
if pool_url.starts_with("sv2+tcp://") {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIU this can be stratum2+tcp in some cases (see https://academy.braiins.com/en/braiins-pool/stratum-v2-manual/, URL is stratum2+tcp://stratum.braiins.com:3333/9awtMD5KQgvRUh2yFbjVeT7b6hjipWcAsQHd6wEhgtDT9soosna there).

Not sure if this is ALL cases, but certainly should be supported.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SRI spec implies the same, using scheme stratum2+tcp.

@plebhash, is there any more clear, official statement of this in the SRI spec?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll update shortly to fix the url and propose a more concrete PR.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this link is indeed the only reference on this on the spec

and yeah, this is the correct scheme

// Use Stratum V2 source
info!("Detected SV2 pool URL, using Stratum V2 protocol");

let sv2_config = crate::job_source::stratum_v2::StratumV2Config {
url: pool_url,
worker: pool_user,
password: Some(pool_pass),
user_agent: "mujina-miner/0.1.0-alpha".to_string(),
};

let sv2_source = StratumV2Source::new(
sv2_config,
source_cmd_rx,
source_event_tx,
self.shutdown.clone(),
);

source_reg_tx
.send(SourceRegistration {
name: "stratum-v2".into(),
event_rx: source_event_rx,
command_tx: source_cmd_tx,
})
.await?;

self.tracker.spawn(async move {
if let Err(e) = sv2_source.run().await {
error!("Stratum V2 source error: {}", e);
}
});
} else {
// Use Stratum V1 source (default)
info!("Using Stratum V1 protocol");

let stratum_config = StratumPoolConfig {
url: pool_url,
username: pool_user,
password: pool_pass,
user_agent: "mujina-miner/0.1.0-alpha".to_string(),
suggested_difficulty: 1024,
};

let stratum_source = StratumV1Source::new(
stratum_config,
source_cmd_rx,
source_event_tx,
self.shutdown.clone(),
);

source_reg_tx
.send(SourceRegistration {
name: "stratum-v1".into(),
event_rx: source_event_rx,
command_tx: source_cmd_tx,
})
.await?;

self.tracker.spawn(async move {
if let Err(e) = stratum_source.run().await {
error!("Stratum V1 source error: {}", e);
}
});
}
} else {
// Use DummySource
info!("Using dummy job source (set MUJINA_POOL_URL to use Stratum v1)");
Expand Down
11 changes: 9 additions & 2 deletions mujina-miner/src/hash_thread/bm13xx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -871,8 +871,15 @@ async fn bm13xx_thread_actor<R, W>(
// Reconstruct full version from rolling field
let full_version = version.apply_to_version(template.version.base());

// Compute merkle root for this task's EN2
match task.en2.as_ref().and_then(|en2| template.compute_merkle_root(en2).ok()) {
// Get merkle root: either compute from EN2 or use fixed value
use crate::job_source::MerkleRootKind;
let merkle_root_result = match &template.merkle_root {
MerkleRootKind::Computed(_) => {
task.en2.as_ref().and_then(|en2| template.compute_merkle_root(en2).ok())
}
MerkleRootKind::Fixed(merkle_root) => Some(*merkle_root),
};
match merkle_root_result {
Some(merkle_root) => {
// Build block header
let header = BlockHeader {
Expand Down
1 change: 1 addition & 0 deletions mujina-miner/src/job_source/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub(crate) mod job;
mod merkle;
mod messages;
pub mod stratum_v1;
pub mod stratum_v2;
pub mod test_blocks;
mod version;

Expand Down
Loading