diff --git a/src/cli.rs b/src/cli.rs index 9aa92e4..3c1d4b1 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -44,6 +44,9 @@ pub struct Opt { #[clap(long, display_order = 10)] /// Output logs in alternative format (same as kaspad) pub altlogs: bool, + #[clap(long = "user-agent-suffix", display_order = 11)] + /// Custom user agent suffix (max 20 characters) + pub user_agent_suffix: Option, } fn parse_devfund_percent(s: &str) -> Result { @@ -82,6 +85,15 @@ impl Opt { } log::info!("Kaspad address: {}", self.kaspad_address); + if let Some(suffix) = &self.user_agent_suffix { + if suffix.contains('/') { + return Err("--user-agent-suffix cannot contain '/' characters".into()); + } + if suffix.chars().count() > 20 { + return Err("--user-agent-suffix must be at most 20 characters".into()); + } + } + Ok(()) } diff --git a/src/client.rs b/src/client.rs index f0ff633..695aec9 100644 --- a/src/client.rs +++ b/src/client.rs @@ -23,20 +23,39 @@ pub struct KaspadHandler { devfund_address: Option, devfund_percent: u16, block_template_ctr: u64, + extra_data: String, } impl KaspadHandler { - pub async fn connect(address: D, miner_address: String, mine_when_not_synced: bool) -> Result + pub async fn connect( + address: D, + miner_address: String, + mine_when_not_synced: bool, + user_agent_suffix: Option, + ) -> Result where D: TryInto, D::Error: Into, { let mut client = RpcClient::connect(address).await?; let (send_channel, recv) = mpsc::channel(3); + + let extra_data = match user_agent_suffix { + Some(suffix) => { + let extra_data = format!("{}/{}", EXTRA_DATA, suffix); + info!("Using user agent: {}", extra_data); + extra_data + } + None => { + info!("Using user agent: {}, specify --user-agent-suffix to customize", EXTRA_DATA); + EXTRA_DATA.to_string() + } + }; + send_channel.send(GetInfoRequestMessage {}.into()).await?; send_channel .send( - GetBlockTemplateRequestMessage { pay_address: miner_address.clone(), extra_data: EXTRA_DATA.into() } + GetBlockTemplateRequestMessage { pay_address: miner_address.clone(), extra_data: extra_data.clone() } .into(), ) .await?; @@ -50,6 +69,7 @@ impl KaspadHandler { devfund_address: None, devfund_percent: 0, block_template_ctr: 0, + extra_data, }) } @@ -70,7 +90,7 @@ impl KaspadHandler { _ => self.miner_address.clone(), }; self.block_template_ctr += 1; - self.client_send(GetBlockTemplateRequestMessage { pay_address, extra_data: EXTRA_DATA.into() }).await + self.client_send(GetBlockTemplateRequestMessage { pay_address, extra_data: self.extra_data.clone() }).await } pub async fn listen(&mut self, miner: &mut MinerManager, shutdown: ShutdownHandler) -> Result<(), Error> { diff --git a/src/main.rs b/src/main.rs index c99ec46..dca2a3c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -77,9 +77,13 @@ async fn main() -> Result<(), Error> { let _shutdown_when_dropped = shutdown.arm(); while !shutdown.is_shutdown() { - let mut client = - KaspadHandler::connect(opt.kaspad_address.clone(), opt.mining_address.clone(), opt.mine_when_not_synced) - .await?; + let mut client = KaspadHandler::connect( + opt.kaspad_address.clone(), + opt.mining_address.clone(), + opt.mine_when_not_synced, + opt.user_agent_suffix.clone(), + ) + .await?; if let Some(devfund_address) = &opt.devfund_address { client.add_devfund(devfund_address.clone(), opt.devfund_percent); info!(