diff --git a/libsigner/src/runloop.rs b/libsigner/src/runloop.rs index 7f0a2a73d7..2f4bbcf46b 100644 --- a/libsigner/src/runloop.rs +++ b/libsigner/src/runloop.rs @@ -133,6 +133,12 @@ impl RunningSigner { // kill event receiver self.stop_signal.send(); + self.join() + } + + /// Wait for the signer to terminate, and get the final state. + /// WARNING: This will hang forever if the event receiver stop signal was never sent/no error occurs. + pub fn join(self) -> Option { debug!("Try join event loop..."); // wait for event receiver join let _ = self.event_join.join().map_err(|thread_panic| { diff --git a/stacks-signer/src/cli.rs b/stacks-signer/src/cli.rs index 732913384d..c21c3d78cc 100644 --- a/stacks-signer/src/cli.rs +++ b/stacks-signer/src/cli.rs @@ -2,11 +2,12 @@ use std::io::{self, Read}; use std::net::SocketAddr; use std::path::PathBuf; +use crate::config::Network; use clap::Parser; use clarity::vm::types::QualifiedContractIdentifier; -use stacks_common::types::chainstate::StacksPrivateKey; +use stacks_common::{address::b58, types::chainstate::StacksPrivateKey}; -use crate::config::Network; +extern crate alloc; #[derive(Parser, Debug)] #[command(author, version, about)] @@ -93,7 +94,9 @@ pub struct PutChunkArgs { pub slot_version: u32, /// The data to upload #[arg(required = false, value_parser = parse_data)] - pub data: Vec, + // Note this weirdness is due to https://github.com/clap-rs/clap/discussions/4695 + // Need to specify the long name here due to invalid parsing in Clap which looks at the NAME rather than the TYPE which causes issues in how it handles Vec's. + pub data: alloc::vec::Vec, } #[derive(Parser, Debug, Clone)] @@ -104,7 +107,9 @@ pub struct SignArgs { pub config: PathBuf, /// The data to sign #[arg(required = false, value_parser = parse_data)] - pub data: Vec, + // Note this weirdness is due to https://github.com/clap-rs/clap/discussions/4695 + // Need to specify the long name here due to invalid parsing in Clap which looks at the NAME rather than the TYPE which causes issues in how it handles Vec's. + pub data: alloc::vec::Vec, } #[derive(Parser, Debug, Clone)] @@ -135,7 +140,7 @@ pub struct GenerateFilesArgs { /// The total number of key ids to distribute among the signers pub num_keys: u32, #[arg(long, value_parser = parse_network)] - /// The network to use. One of "mainnet" or "testnet". + /// The network to use. One of "mainnet", "testnet", or "mocknet". pub network: Network, /// The directory to write the test data files to #[arg(long, default_value = ".")] @@ -157,25 +162,28 @@ fn parse_private_key(private_key: &str) -> Result { /// Parse the input data fn parse_data(data: &str) -> Result, String> { - let data = if data == "-" { + let encoded_data = if data == "-" { // Parse the data from stdin - let mut buf = vec![]; - io::stdin().read_to_end(&mut buf).unwrap(); - buf + let mut data = String::new(); + io::stdin().read_to_string(&mut data).unwrap(); + data } else { - data.as_bytes().to_vec() + data.to_string() }; + let data = + b58::from(&encoded_data).map_err(|e| format!("Failed to decode provided data: {}", e))?; Ok(data) } -/// Parse the network. Must be one of "mainnet" or "testnet". +/// Parse the network. Must be one of "mainnet", "testnet", or "mocknet". fn parse_network(network: &str) -> Result { Ok(match network.to_lowercase().as_str() { "mainnet" => Network::Mainnet, "testnet" => Network::Testnet, + "mocknet" => Network::Mocknet, _ => { return Err(format!( - "Invalid network: {}. Must be one of \"mainnet\" or \"testnet\".", + "Invalid network: {}. Must be one of \"mainnet\", \"testnet\", or \"mocknet\".", network )) } diff --git a/stacks-signer/src/config.rs b/stacks-signer/src/config.rs index 682e8d2117..db9b11f38d 100644 --- a/stacks-signer/src/config.rs +++ b/stacks-signer/src/config.rs @@ -67,6 +67,8 @@ pub enum Network { Mainnet, /// The testnet network Testnet, + /// The mocknet network + Mocknet, } impl Network { @@ -74,7 +76,7 @@ impl Network { pub fn to_chain_id(&self) -> u32 { match self { Self::Mainnet => CHAIN_ID_MAINNET, - Self::Testnet => CHAIN_ID_TESTNET, + Self::Testnet | Self::Mocknet => CHAIN_ID_TESTNET, } } @@ -82,7 +84,7 @@ impl Network { pub fn to_address_version(&self) -> u8 { match self { Self::Mainnet => C32_ADDRESS_VERSION_MAINNET_SINGLESIG, - Self::Testnet => C32_ADDRESS_VERSION_TESTNET_SINGLESIG, + Self::Testnet | Self::Mocknet => C32_ADDRESS_VERSION_TESTNET_SINGLESIG, } } @@ -90,7 +92,7 @@ impl Network { pub fn to_transaction_version(&self) -> TransactionVersion { match self { Self::Mainnet => TransactionVersion::Mainnet, - Self::Testnet => TransactionVersion::Testnet, + Self::Testnet | Self::Mocknet => TransactionVersion::Testnet, } } } diff --git a/stacks-signer/src/main.rs b/stacks-signer/src/main.rs index 2e1db38a2c..cf8b4bd72b 100644 --- a/stacks-signer/src/main.rs +++ b/stacks-signer/src/main.rs @@ -95,7 +95,7 @@ fn spawn_running_signer(path: &PathBuf) -> SpawnedSigner { RunLoop>, StackerDBEventReceiver, > = Signer::new(runloop, ev, cmd_recv, res_send); - let endpoint = config.node_host; + let endpoint = config.endpoint; let running_signer = signer.spawn(endpoint).unwrap(); SpawnedSigner { running_signer, @@ -174,7 +174,7 @@ fn handle_list_chunks(args: StackerDBArgs) { fn handle_put_chunk(args: PutChunkArgs) { debug!("Putting chunk..."); let mut session = stackerdb_session(args.db_args.host, args.db_args.contract); - let mut chunk = StackerDBChunkData::new(args.slot_id, args.slot_version, args.data.clone()); + let mut chunk = StackerDBChunkData::new(args.slot_id, args.slot_version, args.data); chunk.sign(&args.private_key).unwrap(); let chunk_ack = session.put_chunk(chunk).unwrap(); println!("{}", serde_json::to_string(&chunk_ack).unwrap()); @@ -186,7 +186,7 @@ fn handle_dkg(args: RunDkgArgs) { spawned_signer.cmd_send.send(RunLoopCommand::Dkg).unwrap(); let dkg_res = spawned_signer.res_recv.recv().unwrap(); process_dkg_result(&dkg_res); - spawned_signer.running_signer.stop().unwrap(); + spawned_signer.running_signer.stop(); } fn handle_sign(args: SignArgs) { @@ -202,7 +202,7 @@ fn handle_sign(args: SignArgs) { .unwrap(); let sign_res = spawned_signer.res_recv.recv().unwrap(); process_sign_result(&sign_res); - spawned_signer.running_signer.stop().unwrap(); + spawned_signer.running_signer.stop(); } fn handle_dkg_sign(args: SignArgs) { @@ -222,13 +222,15 @@ fn handle_dkg_sign(args: SignArgs) { process_dkg_result(&dkg_res); let sign_res = spawned_signer.res_recv.recv().unwrap(); process_sign_result(&sign_res); - spawned_signer.running_signer.stop().unwrap(); + spawned_signer.running_signer.stop(); } fn handle_run(args: RunDkgArgs) { debug!("Running signer..."); - let _spawned_signer = spawn_running_signer(&args.config); - println!("Signer spawned successfully. Waiting for messages to process."); + let spawned_signer = spawn_running_signer(&args.config); + println!("Signer spawned successfully. Waiting for messages to process..."); + // Wait for the spawned signer to stop (will only occur if an error occurs) + let _ = spawned_signer.running_signer.join(); } fn handle_generate_files(args: GenerateFilesArgs) { @@ -333,7 +335,7 @@ fn main() { fn to_addr(stacks_private_key: &StacksPrivateKey, network: &Network) -> StacksAddress { let version = match network { Network::Mainnet => C32_ADDRESS_VERSION_MAINNET_SINGLESIG, - Network::Testnet => C32_ADDRESS_VERSION_TESTNET_SINGLESIG, + Network::Testnet | Network::Mocknet => C32_ADDRESS_VERSION_TESTNET_SINGLESIG, }; StacksAddress::from_public_keys( version,