mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-01-13 08:40:45 +08:00
Remove dead CLI commands including Sign, DKG, and generate Files commands
Signed-off-by: Jacinta Ferrant <jacinta@trustmachines.co>
This commit is contained in:
@@ -14,7 +14,6 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
use std::io::{self, Read};
|
||||
use std::net::SocketAddr;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use blockstack_lib::chainstate::stacks::address::PoxAddress;
|
||||
@@ -28,8 +27,6 @@ use stacks_common::address::{
|
||||
};
|
||||
use stacks_common::types::chainstate::StacksPrivateKey;
|
||||
|
||||
use crate::config::Network;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
@@ -52,16 +49,8 @@ pub enum Command {
|
||||
ListChunks(StackerDBArgs),
|
||||
/// Upload a chunk to the stacker-db instance
|
||||
PutChunk(PutChunkArgs),
|
||||
/// Run DKG and sign the message through the stacker-db instance
|
||||
DkgSign(SignArgs),
|
||||
/// Sign the message through the stacker-db instance
|
||||
Sign(SignArgs),
|
||||
/// Run a DKG round through the stacker-db instance
|
||||
Dkg(RunDkgArgs),
|
||||
/// Run the signer, waiting for events from the stacker-db instance
|
||||
Run(RunSignerArgs),
|
||||
/// Generate necessary files for running a collection of signers
|
||||
GenerateFiles(GenerateFilesArgs),
|
||||
/// Generate a signature for Stacking transactions
|
||||
GenerateStackingSignature(GenerateStackingSignatureArgs),
|
||||
/// Check a configuration file and output config information
|
||||
@@ -126,34 +115,6 @@ pub struct PutChunkArgs {
|
||||
pub data: alloc::vec::Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
/// Arguments for the dkg-sign and sign command
|
||||
pub struct SignArgs {
|
||||
/// Path to config file
|
||||
#[arg(long, short, value_name = "FILE")]
|
||||
pub config: PathBuf,
|
||||
/// The reward cycle the signer is registered for and wants to sign for
|
||||
/// Note: this must be the current reward cycle of the node
|
||||
#[arg(long, short)]
|
||||
pub reward_cycle: u64,
|
||||
/// The data to sign
|
||||
#[arg(required = false, value_parser = parse_data)]
|
||||
// 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<u8>,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
/// Arguments for the Dkg command
|
||||
pub struct RunDkgArgs {
|
||||
/// Path to config file
|
||||
#[arg(long, short, value_name = "FILE")]
|
||||
pub config: PathBuf,
|
||||
/// The reward cycle the signer is registered for and wants to peform DKG for
|
||||
#[arg(long, short)]
|
||||
pub reward_cycle: u64,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
/// Arguments for the Run command
|
||||
pub struct RunSignerArgs {
|
||||
@@ -162,36 +123,6 @@ pub struct RunSignerArgs {
|
||||
pub config: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
/// Arguments for the generate-files command
|
||||
pub struct GenerateFilesArgs {
|
||||
/// The Stacks node to connect to
|
||||
#[arg(long)]
|
||||
pub host: SocketAddr,
|
||||
#[arg(
|
||||
long,
|
||||
required_unless_present = "private_keys",
|
||||
conflicts_with = "private_keys"
|
||||
)]
|
||||
/// The number of signers to generate
|
||||
pub num_signers: Option<u32>,
|
||||
#[clap(long, value_name = "FILE")]
|
||||
/// A path to a file containing a list of hexadecimal Stacks private keys of the signers
|
||||
pub private_keys: Option<PathBuf>,
|
||||
#[arg(long, value_parser = parse_network)]
|
||||
/// 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 = ".")]
|
||||
pub dir: PathBuf,
|
||||
/// The number of milliseconds to wait when polling for events from the stacker-db instance.
|
||||
#[arg(long)]
|
||||
pub timeout: Option<u64>,
|
||||
#[arg(long)]
|
||||
/// The authorization password to use to connect to the validate block proposal node endpoint
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Wrapper around `Pox4SignatureTopic` to implement `ValueEnum`
|
||||
pub struct StackingSignatureMethod(Pox4SignatureTopic);
|
||||
@@ -312,21 +243,6 @@ fn parse_data(data: &str) -> Result<Vec<u8>, String> {
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
/// Parse the network. Must be one of "mainnet", "testnet", or "mocknet".
|
||||
fn parse_network(network: &str) -> Result<Network, String> {
|
||||
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\", \"testnet\", or \"mocknet\".",
|
||||
network
|
||||
))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use blockstack_lib::chainstate::stacks::address::{PoxAddressType20, PoxAddressType32};
|
||||
|
||||
@@ -26,41 +26,33 @@ extern crate serde;
|
||||
extern crate serde_json;
|
||||
extern crate toml;
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::{self, BufRead, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::io::{self, Write};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
use std::time::Duration;
|
||||
|
||||
use blockstack_lib::util_lib::signed_structured_data::pox4::make_pox_4_signer_key_signature;
|
||||
use clap::Parser;
|
||||
use clarity::vm::types::QualifiedContractIdentifier;
|
||||
use libsigner::{
|
||||
BlockProposalSigners, RunningSigner, Signer, SignerEventReceiver, SignerSession,
|
||||
StackerDBSession,
|
||||
};
|
||||
use libsigner::{RunningSigner, Signer, SignerEventReceiver, SignerSession, StackerDBSession};
|
||||
use libstackerdb::StackerDBChunkData;
|
||||
use slog::{slog_debug, slog_error, slog_info};
|
||||
use stacks_common::codec::read_next;
|
||||
use stacks_common::types::chainstate::StacksPrivateKey;
|
||||
use slog::{slog_debug, slog_info};
|
||||
use stacks_common::util::hash::to_hex;
|
||||
use stacks_common::util::secp256k1::{MessageSignature, Secp256k1PublicKey};
|
||||
use stacks_common::{debug, error, info};
|
||||
use stacks_common::{debug, info};
|
||||
use stacks_signer::cli::{
|
||||
Cli, Command, GenerateFilesArgs, GenerateStackingSignatureArgs, GetChunkArgs,
|
||||
GetLatestChunkArgs, PutChunkArgs, RunDkgArgs, RunSignerArgs, SignArgs, StackerDBArgs,
|
||||
Cli, Command, GenerateStackingSignatureArgs, GetChunkArgs, GetLatestChunkArgs, PutChunkArgs,
|
||||
RunSignerArgs, StackerDBArgs,
|
||||
};
|
||||
use stacks_signer::config::{build_signer_config_tomls, GlobalConfig};
|
||||
use stacks_signer::config::GlobalConfig;
|
||||
use stacks_signer::runloop::{RunLoop, RunLoopCommand};
|
||||
use stacks_signer::signer::Command as SignerCommand;
|
||||
use tracing_subscriber::prelude::*;
|
||||
use tracing_subscriber::{fmt, EnvFilter};
|
||||
use wsts::state_machine::OperationResult;
|
||||
|
||||
struct SpawnedSigner {
|
||||
running_signer: RunningSigner<SignerEventReceiver, Vec<OperationResult>>,
|
||||
cmd_send: Sender<RunLoopCommand>,
|
||||
res_recv: Receiver<Vec<OperationResult>>,
|
||||
_cmd_send: Sender<RunLoopCommand>,
|
||||
_res_recv: Receiver<Vec<OperationResult>>,
|
||||
}
|
||||
|
||||
/// Create a new stacker db session
|
||||
@@ -90,8 +82,8 @@ fn spawn_running_signer(path: &PathBuf) -> SpawnedSigner {
|
||||
let config = GlobalConfig::try_from(path).unwrap();
|
||||
let endpoint = config.endpoint;
|
||||
info!("Starting signer with config: {}", config);
|
||||
let (cmd_send, cmd_recv) = channel();
|
||||
let (res_send, res_recv) = channel();
|
||||
let (_cmd_send, cmd_recv) = channel();
|
||||
let (res_send, _res_recv) = channel();
|
||||
let ev = SignerEventReceiver::new(config.network.is_mainnet());
|
||||
#[cfg(feature = "monitoring_prom")]
|
||||
{
|
||||
@@ -103,66 +95,8 @@ fn spawn_running_signer(path: &PathBuf) -> SpawnedSigner {
|
||||
let running_signer = signer.spawn(endpoint).unwrap();
|
||||
SpawnedSigner {
|
||||
running_signer,
|
||||
cmd_send,
|
||||
res_recv,
|
||||
}
|
||||
}
|
||||
|
||||
// Process a DKG result
|
||||
fn process_dkg_result(dkg_res: &[OperationResult]) {
|
||||
assert!(dkg_res.len() == 1, "Received unexpected number of results");
|
||||
let dkg = dkg_res.first().unwrap();
|
||||
match dkg {
|
||||
OperationResult::Dkg(aggregate_key) => {
|
||||
println!("Received aggregate group key: {aggregate_key}");
|
||||
}
|
||||
OperationResult::Sign(signature) => {
|
||||
panic!(
|
||||
"Received unexpected signature ({},{})",
|
||||
&signature.R, &signature.z,
|
||||
);
|
||||
}
|
||||
OperationResult::SignTaproot(schnorr_proof) => {
|
||||
panic!(
|
||||
"Received unexpected schnorr proof ({},{})",
|
||||
&schnorr_proof.r, &schnorr_proof.s,
|
||||
);
|
||||
}
|
||||
OperationResult::DkgError(dkg_error) => {
|
||||
panic!("Received DkgError {}", dkg_error);
|
||||
}
|
||||
OperationResult::SignError(sign_error) => {
|
||||
panic!("Received SignError {}", sign_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process a Sign result
|
||||
fn process_sign_result(sign_res: &[OperationResult]) {
|
||||
assert!(sign_res.len() == 1, "Received unexpected number of results");
|
||||
let sign = sign_res.first().unwrap();
|
||||
match sign {
|
||||
OperationResult::Dkg(aggregate_key) => {
|
||||
panic!("Received unexpected aggregate group key: {aggregate_key}");
|
||||
}
|
||||
OperationResult::Sign(signature) => {
|
||||
panic!(
|
||||
"Received bood signature ({},{})",
|
||||
&signature.R, &signature.z,
|
||||
);
|
||||
}
|
||||
OperationResult::SignTaproot(schnorr_proof) => {
|
||||
panic!(
|
||||
"Received unexpected schnorr proof ({},{})",
|
||||
&schnorr_proof.r, &schnorr_proof.s,
|
||||
);
|
||||
}
|
||||
OperationResult::DkgError(dkg_error) => {
|
||||
panic!("Received DkgError {}", dkg_error);
|
||||
}
|
||||
OperationResult::SignError(sign_error) => {
|
||||
panic!("Received SignError {}", sign_error);
|
||||
}
|
||||
_cmd_send,
|
||||
_res_recv,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,73 +132,6 @@ fn handle_put_chunk(args: PutChunkArgs) {
|
||||
println!("{}", serde_json::to_string(&chunk_ack).unwrap());
|
||||
}
|
||||
|
||||
fn handle_dkg(args: RunDkgArgs) {
|
||||
debug!("Running DKG...");
|
||||
let spawned_signer = spawn_running_signer(&args.config);
|
||||
let dkg_command = RunLoopCommand {
|
||||
reward_cycle: args.reward_cycle,
|
||||
command: SignerCommand::Dkg,
|
||||
};
|
||||
spawned_signer.cmd_send.send(dkg_command).unwrap();
|
||||
let dkg_res = spawned_signer.res_recv.recv().unwrap();
|
||||
process_dkg_result(&dkg_res);
|
||||
spawned_signer.running_signer.stop();
|
||||
}
|
||||
|
||||
fn handle_sign(args: SignArgs) {
|
||||
debug!("Signing message...");
|
||||
let spawned_signer = spawn_running_signer(&args.config);
|
||||
let Some(block_proposal) = read_next::<BlockProposalSigners, _>(&mut &args.data[..]).ok()
|
||||
else {
|
||||
error!("Unable to parse provided message as a BlockProposalSigners.");
|
||||
spawned_signer.running_signer.stop();
|
||||
return;
|
||||
};
|
||||
let sign_command = RunLoopCommand {
|
||||
reward_cycle: args.reward_cycle,
|
||||
command: SignerCommand::Sign {
|
||||
block_proposal,
|
||||
is_taproot: false,
|
||||
merkle_root: None,
|
||||
},
|
||||
};
|
||||
spawned_signer.cmd_send.send(sign_command).unwrap();
|
||||
let sign_res = spawned_signer.res_recv.recv().unwrap();
|
||||
process_sign_result(&sign_res);
|
||||
spawned_signer.running_signer.stop();
|
||||
}
|
||||
|
||||
fn handle_dkg_sign(args: SignArgs) {
|
||||
debug!("Running DKG and signing message...");
|
||||
let spawned_signer = spawn_running_signer(&args.config);
|
||||
let Some(block_proposal) = read_next::<BlockProposalSigners, _>(&mut &args.data[..]).ok()
|
||||
else {
|
||||
error!("Unable to parse provided message as a BlockProposalSigners.");
|
||||
spawned_signer.running_signer.stop();
|
||||
return;
|
||||
};
|
||||
let dkg_command = RunLoopCommand {
|
||||
reward_cycle: args.reward_cycle,
|
||||
command: SignerCommand::Dkg,
|
||||
};
|
||||
let sign_command = RunLoopCommand {
|
||||
reward_cycle: args.reward_cycle,
|
||||
command: SignerCommand::Sign {
|
||||
block_proposal,
|
||||
is_taproot: false,
|
||||
merkle_root: None,
|
||||
},
|
||||
};
|
||||
// First execute DKG, then sign
|
||||
spawned_signer.cmd_send.send(dkg_command).unwrap();
|
||||
spawned_signer.cmd_send.send(sign_command).unwrap();
|
||||
let dkg_res = spawned_signer.res_recv.recv().unwrap();
|
||||
process_dkg_result(&dkg_res);
|
||||
let sign_res = spawned_signer.res_recv.recv().unwrap();
|
||||
process_sign_result(&sign_res);
|
||||
spawned_signer.running_signer.stop();
|
||||
}
|
||||
|
||||
fn handle_run(args: RunSignerArgs) {
|
||||
debug!("Running signer...");
|
||||
let spawned_signer = spawn_running_signer(&args.config);
|
||||
@@ -273,50 +140,6 @@ fn handle_run(args: RunSignerArgs) {
|
||||
let _ = spawned_signer.running_signer.join();
|
||||
}
|
||||
|
||||
fn handle_generate_files(args: GenerateFilesArgs) {
|
||||
debug!("Generating files...");
|
||||
let signer_stacks_private_keys = if let Some(path) = args.private_keys {
|
||||
let file = File::open(path).unwrap();
|
||||
let reader = io::BufReader::new(file);
|
||||
|
||||
let private_keys: Vec<String> = reader.lines().collect::<Result<_, _>>().unwrap();
|
||||
println!("{}", StacksPrivateKey::new().to_hex());
|
||||
let private_keys = private_keys
|
||||
.iter()
|
||||
.map(|key| StacksPrivateKey::from_hex(key).expect("Failed to parse private key."))
|
||||
.collect::<Vec<StacksPrivateKey>>();
|
||||
if private_keys.is_empty() {
|
||||
panic!("Private keys file is empty.");
|
||||
}
|
||||
private_keys
|
||||
} else {
|
||||
let num_signers = args.num_signers.unwrap();
|
||||
if num_signers == 0 {
|
||||
panic!("--num-signers must be non-zero.");
|
||||
}
|
||||
(0..num_signers)
|
||||
.map(|_| StacksPrivateKey::new())
|
||||
.collect::<Vec<StacksPrivateKey>>()
|
||||
};
|
||||
|
||||
let signer_config_tomls = build_signer_config_tomls(
|
||||
&signer_stacks_private_keys,
|
||||
&args.host.to_string(),
|
||||
args.timeout.map(Duration::from_millis),
|
||||
&args.network,
|
||||
&args.password,
|
||||
rand::random(),
|
||||
3000,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
);
|
||||
debug!("Built {:?} signer config tomls.", signer_config_tomls.len());
|
||||
for (i, file_contents) in signer_config_tomls.iter().enumerate() {
|
||||
write_file(&args.dir, &format!("signer-{}.toml", i), file_contents);
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_generate_stacking_signature(
|
||||
args: GenerateStackingSignatureArgs,
|
||||
do_print: bool,
|
||||
@@ -370,15 +193,6 @@ fn handle_check_config(args: RunSignerArgs) {
|
||||
println!("Config: {}", config);
|
||||
}
|
||||
|
||||
/// Helper function for writing the given contents to filename in the given directory
|
||||
fn write_file(dir: &Path, filename: &str, contents: &str) {
|
||||
let file_path = dir.join(filename);
|
||||
let filename = file_path.to_str().unwrap();
|
||||
let mut file = File::create(filename).unwrap();
|
||||
file.write_all(contents.as_bytes()).unwrap();
|
||||
println!("Created file: {}", filename);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let cli = Cli::parse();
|
||||
|
||||
@@ -400,21 +214,9 @@ fn main() {
|
||||
Command::PutChunk(args) => {
|
||||
handle_put_chunk(args);
|
||||
}
|
||||
Command::Dkg(args) => {
|
||||
handle_dkg(args);
|
||||
}
|
||||
Command::DkgSign(args) => {
|
||||
handle_dkg_sign(args);
|
||||
}
|
||||
Command::Sign(args) => {
|
||||
handle_sign(args);
|
||||
}
|
||||
Command::Run(args) => {
|
||||
handle_run(args);
|
||||
}
|
||||
Command::GenerateFiles(args) => {
|
||||
handle_generate_files(args);
|
||||
}
|
||||
Command::GenerateStackingSignature(args) => {
|
||||
handle_generate_stacking_signature(args, true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user