Skip to content
Closed
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
34 changes: 31 additions & 3 deletions pool-apps/pool/src/lib/channel_manager/mining_message_handler.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::str::FromStr;
use std::sync::atomic::Ordering;

use stratum_apps::stratum_core::{
binary_sv2::Str0255,
bitcoin::{consensus::Decodable, Amount, Target, TxOut},
bitcoin::{consensus::Decodable, Address, Amount, Target, TxOut},
channels_sv2::{
server::{
error::{ExtendedChannelError, StandardChannelError},
Expand Down Expand Up @@ -141,10 +142,23 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager {
return Err(PoolError::disconnect(PoolErrorKind::LastNewPrevhashNotFound, downstream_id));
};

// Determine the script pubkey for the coinbase output
// If SOLO mining is enabled, we try to use the address provided by the miner
let script_pubkey = if self.solo_mining {
match Address::from_str(&user_identity) {
Ok(addr) => addr.assume_checked().script_pubkey(),
Err(_) => {
error!("SOLO Mining Error: Invalid address '{}' provided by user. Fallback to pool reward address.", user_identity);
self.coinbase_reward_script.script_pubkey().clone()
Comment on lines +151 to +152
Copy link
Member

Choose a reason for hiding this comment

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

Here we should disconnect the the client, instead of doing fallback to pool's address.

}
}
} else {
self.coinbase_reward_script.script_pubkey().clone()
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't this just be self for Channel manager? I would think you want per Channel address and not for the broader Pool Channel Manager.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wouldn't this just be self for Channel manager? I would think you want per Channel address and not for the broader Pool Channel Manager.

You are correct that for Solo Mining we need the per-channel address. That logic is handled in the if block immediately above this.

This specific line is inside the else block, which handles Standard Mining. In Standard mode, the coinbase reward must go to the Pool's global wallet (self.coinbase_reward_script) so the pool can collect the funds and distribute shares later.

};

let pool_coinbase_output = TxOut {
value: Amount::from_sat(last_future_template.coinbase_tx_value_remaining),
script_pubkey: self.coinbase_reward_script.script_pubkey(),
script_pubkey,
};

downstream.downstream_data.super_safe_lock(|downstream_data| {
Expand Down Expand Up @@ -435,11 +449,25 @@ impl HandleMiningMessagesFromClientAsync for ChannelManager {
// future extended job
// and the SetNewPrevHash message
} else {
// Determine the script pubkey for the coinbase output
// If SOLO mining is enabled, we try to use the address provided by the miner
let script_pubkey = if self.solo_mining {
match Address::from_str(&user_identity) {
Ok(addr) => addr.assume_checked().script_pubkey(),
Err(_) => {
error!("SOLO Mining Error: Invalid address '{}' provided by user. Fallback to pool reward address.", user_identity);
self.coinbase_reward_script.script_pubkey().clone()
Comment on lines +458 to +459
Copy link
Member

Choose a reason for hiding this comment

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

Here we should disconnect the the client, instead of doing fallback to pool's address.

}
}
} else {
self.coinbase_reward_script.script_pubkey().clone()
};

let pool_coinbase_output = TxOut {
value: Amount::from_sat(
last_future_template.coinbase_tx_value_remaining,
),
script_pubkey: self.coinbase_reward_script.script_pubkey(),
script_pubkey,
};

extended_channel.on_new_template(
Expand Down
3 changes: 3 additions & 0 deletions pool-apps/pool/src/lib/channel_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ pub struct ChannelManager {
share_batch_size: usize,
shares_per_minute: SharesPerMinute,
coinbase_reward_script: CoinbaseRewardScript,
/// Indicates if SOLO mining mode is enabled.
solo_mining: bool,
/// Protocol extensions that the pool supports (will accept if requested by clients).
supported_extensions: Vec<u16>,
/// Protocol extensions that the pool requires (clients must support these).
Expand Down Expand Up @@ -163,6 +165,7 @@ impl ChannelManager {
shares_per_minute: config.shares_per_minute(),
pool_tag_string: config.pool_signature().to_string(),
coinbase_reward_script: config.coinbase_reward_script().clone(),
solo_mining: config.solo_mining(),
supported_extensions: config.supported_extensions().to_vec(),
required_extensions: config.required_extensions().to_vec(),
};
Expand Down
12 changes: 12 additions & 0 deletions pool-apps/pool/src/lib/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ pub struct PoolConfig {
required_extensions: Vec<u16>,
#[serde(default)]
monitoring_address: Option<SocketAddr>,

Copy link
Member

Choose a reason for hiding this comment

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

Remove this blank line.

/// Enable SOLO mining mode.
/// In this mode, the block reward is sent to the address provided by the miner
/// in the 'user_identity' field.
#[serde(default)]
solo_mining: bool,
}

impl PoolConfig {
Expand Down Expand Up @@ -75,6 +81,7 @@ impl PoolConfig {
supported_extensions,
required_extensions,
monitoring_address: None,
solo_mining: false,
Copy link
Member

Choose a reason for hiding this comment

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

Why did you set this to false here?

}
}

Expand Down Expand Up @@ -165,6 +172,11 @@ impl PoolConfig {
pub fn monitoring_address(&self) -> Option<SocketAddr> {
self.monitoring_address
}

/// Returns true if SOLO mining mode is enabled.
pub fn solo_mining(&self) -> bool {
self.solo_mining
}
}

/// Pool's authority public and secret keys.
Expand Down