Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore/split cli admin #31

Merged
merged 3 commits into from
Feb 1, 2024
Merged
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
10 changes: 5 additions & 5 deletions DEVELOPER.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ docker pull imikushin/zkbitcoin

```shell
docker create --restart=always -v keys:/keys --name zkbtc-node -p 8891:8891 imikushin/zkbitcoin \
zkbtc start-committee-node \
zkbtc-admin start-committee-node \
--key-path=/keys/key.json --publickey-package-path=/keys/publickey-package.json \
--address=0.0.0.0:8891
```
Expand Down Expand Up @@ -113,19 +113,19 @@ Now re-run steps 2 and 4 from above: create the container and then start it (the
### Generate committee with trusted dealer

```shell
cargo run -- generate-committee --num 3 --threshold 2 --output-dir tests/
cargo run --bin zktbct-admin -- generate-committee --num 3 --threshold 2 --output-dir tests/
```

### Start a committee node

```shell
RUST_LOG=debug cargo run -- start-committee-node --key-path examples/committee/key-0.json --publickey-package-path examples/committee/publickey-package.json --address "127.0.0.1:8891"
RUST_LOG=debug cargo run --bin zktbct-admin -- start-committee-node --key-path examples/committee/key-0.json --publickey-package-path examples/committee/publickey-package.json --address "127.0.0.1:8891"
```

### Start an orchestrator/coordinator

```shell
RUST_LOG=debug cargo run -- start-orchestrator --publickey-package-path examples/committee/publickey-package.json --committee-cfg-path examples/committee/committee-cfg.json --address "127.0.0.1:8891"
RUST_LOG=debug cargo run --bin zktbct-admin -- start-orchestrator --publickey-package-path examples/committee/publickey-package.json --committee-cfg-path examples/committee/committee-cfg.json --address "127.0.0.1:8891"
```

then you can query it like so:
Expand Down Expand Up @@ -170,4 +170,4 @@ or with the unlock funds CLI command.
* `sudo systemctl restart nginx`
* `git clone https://github.com/sigma0-xyz/zkbitcoin`
* `cd zkbitcoin`
* `RUST_LOG=debug cargo run -- start-committee-node --key-path examples/committee/key-0.json --publickey-package-path examples/committee/publickey-package.json --address "127.0.0.1:8891"`
* `RUST_LOG=debug cargo run --bin zktbct-admin -- start-committee-node --key-path examples/committee/key-0.json --publickey-package-path examples/committee/publickey-package.json --address "127.0.0.1:8891"`
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export RPC_AUTH="username:password"

### zkbtc: the zkBitcoin CLI

To install `zkbtc`, run the following command:
To install `zkbtc` and `zkbtc-admin`, run the following command:

```shell
cargo install --git https://github.com/sigma0-xyz/zkbitcoin.git
Expand Down
210 changes: 210 additions & 0 deletions src/bin/zkbtc-admin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
use anyhow::Result;
use clap::{Parser, Subcommand};
use log::info;
use std::path::PathBuf;
use zkbitcoin::{
committee::orchestrator::{CommitteeConfig, Member},
constants::{ZKBITCOIN_FEE_PUBKEY, ZKBITCOIN_PUBKEY},
frost, taproot_addr_from,
};

#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}

#[derive(Subcommand)]
enum Commands {
/// Generates an MPC committee via a trusted dealer.
/// Ideally this is just used for testing as it is more secure to do a DKG.
GenerateCommittee {
/// Number of nodes in the committee.
#[arg(short, long)]
num: u16,

/// Minimum number of committee member required for a signature.
#[arg(short, long)]
threshold: u16,

/// Output directory to write the committee configuration files to.
#[arg(short, long)]
output_dir: String,
},

/// Starts an MPC node given a configuration
StartCommitteeNode {
/// The address to run the node on.
#[arg(short, long)]
address: Option<String>,

/// The path to the node's key package.
#[arg(short, long)]
key_path: String,

/// The path to the MPC committee public key package.
#[arg(short, long)]
publickey_package_path: String,
},

/// Starts an orchestrator
StartOrchestrator {
/// The address to run the node on.
#[arg(short, long)]
address: Option<String>,

#[arg(short, long)]
publickey_package_path: String,

#[arg(short, long)]
committee_cfg_path: String,
},
}

#[tokio::main]
async fn main() -> Result<()> {
// init default log level to info (unless RUST_LOG is set)
env_logger::init_from_env(env_logger::Env::default().default_filter_or("info"));

// debug info
info!(
"- zkbitcoin_address: {}",
taproot_addr_from(ZKBITCOIN_PUBKEY).unwrap().to_string()
);
info!(
"- zkbitcoin_fund_address: {}",
taproot_addr_from(ZKBITCOIN_FEE_PUBKEY).unwrap().to_string()
);

// parse CLI
let cli = Cli::parse();
match &cli.command {
Commands::GenerateCommittee {
num,
threshold,
output_dir,
} => {
let output_dir = PathBuf::from(output_dir);

// deal until we get a public key starting with 0x02
let (mut key_packages, mut pubkey_package) =
frost::gen_frost_keys(*num, *threshold).unwrap();
let mut pubkey = pubkey_package.verifying_key().to_owned();
loop {
if pubkey.serialize()[0] == 2 {
break;
}
(key_packages, pubkey_package) = frost::gen_frost_keys(*num, *threshold).unwrap();
pubkey = pubkey_package.verifying_key().to_owned();
}

// all key packages
{
for (id, key_package) in key_packages.values().enumerate() {
let filename = format!("key-{id}.json");

let path = output_dir.join(filename);
std::fs::create_dir_all(path.clone().parent().unwrap())
.expect("Couldn't create directory");
let file = std::fs::File::create(&path)
.expect("couldn't create file given output dir");
serde_json::to_writer_pretty(file, key_package).unwrap();
}
}

// public key package
{
let path = output_dir.join("publickey-package.json");
let file =
std::fs::File::create(path).expect("couldn't create file given output dir");
serde_json::to_writer_pretty(file, &pubkey_package).unwrap();
}

// create the committee-cfg.json file
{
let ip = "http://127.0.0.1:889";
let committee_cfg = CommitteeConfig {
threshold: *threshold as usize,
members: key_packages
.iter()
.enumerate()
.map(|(id, (member_id, _))| {
(
*member_id,
Member {
address: format!("{}{}", ip, id),
},
)
})
.collect(),
};
let path = output_dir.join("committee-cfg.json");
let file =
std::fs::File::create(path).expect("couldn't create file given output dir");
serde_json::to_writer_pretty(file, &committee_cfg).unwrap();
}
}

Commands::StartCommitteeNode {
address,
key_path,
publickey_package_path,
} => {
let key_package = {
let full_path = PathBuf::from(key_path);
let file = std::fs::File::open(full_path).expect("file not found");
let key: frost::KeyPackage =
serde_json::from_reader(file).expect("error while reading file");
key
};

let pubkey_package = {
let full_path = PathBuf::from(publickey_package_path);
let file = std::fs::File::open(full_path).expect("file not found");
let publickey_package: frost::PublicKeyPackage =
serde_json::from_reader(file).expect("error while reading file");
publickey_package
};

zkbitcoin::committee::node::run_server(address.as_deref(), key_package, pubkey_package)
.await
.unwrap();
}

Commands::StartOrchestrator {
address,
publickey_package_path,
committee_cfg_path,
} => {
let pubkey_package = {
let full_path = PathBuf::from(publickey_package_path);
let file = std::fs::File::open(full_path).expect("file not found");
let publickey_package: frost::PublicKeyPackage =
serde_json::from_reader(file).expect("error while reading file");
publickey_package
};

let committee_cfg = {
let full_path = PathBuf::from(committee_cfg_path);
let file = std::fs::File::open(full_path).expect("file not found");
let publickey_package: CommitteeConfig =
serde_json::from_reader(file).expect("error while reading file");
publickey_package
};

// sanity check (unfortunately the publickey_package doesn't contain this info)
assert!(committee_cfg.threshold > 0);

zkbitcoin::committee::orchestrator::run_server(
address.as_deref(),
pubkey_package,
committee_cfg,
)
.await
.unwrap();
}
}

Ok(())
}
Loading
Loading