Skip to content

Commit

Permalink
Merge pull request #833 from near/print-cmd
Browse files Browse the repository at this point in the history
print command for spin up a local mpc cluster
  • Loading branch information
ailisp authored Oct 11, 2024
2 parents 4850993 + e2cb49f commit 3715df1
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 4 deletions.
1 change: 1 addition & 0 deletions integration-tests/chain-signatures/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions integration-tests/chain-signatures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ rand = "0.7"
reqwest = "0.11.16"
serde = "1"
serde_json = "1"
shell-escape = "0.1.5"
testcontainers = { version = "0.15", features = ["experimental"] }
tokio = { version = "1.28", features = ["full"] }
tracing = "0.1"
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/chain-signatures/src/execute.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use anyhow::Context;
use async_process::Child;

const PACKAGE_MULTICHAIN: &str = "mpc-node";
pub(crate) const PACKAGE_MULTICHAIN: &str = "mpc-node";

pub fn target_dir() -> Option<std::path::PathBuf> {
let mut out_dir = std::path::Path::new(std::env!("OUT_DIR"));
Expand Down
68 changes: 68 additions & 0 deletions integration-tests/chain-signatures/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use mpc_node::storage;
use mpc_node::storage::triple_storage::TripleNodeStorageBox;
use near_crypto::KeyFile;
use near_workspaces::network::{Sandbox, ValidatorKey};
use near_workspaces::types::{KeyType, SecretKey};
use near_workspaces::{Account, AccountId, Contract, Worker};
use serde_json::json;
use testcontainers::{Container, GenericImage};
Expand Down Expand Up @@ -298,6 +299,62 @@ pub async fn docker(cfg: MultichainConfig, docker_client: &DockerClient) -> anyh
Ok(Nodes::Docker { ctx, nodes })
}

pub async fn dry_host(
cfg: MultichainConfig,
docker_client: &DockerClient,
) -> anyhow::Result<Context> {
let ctx = setup(docker_client).await?;

let accounts =
futures::future::join_all((0..cfg.nodes).map(|_| ctx.worker.dev_create_account()))
.await
.into_iter()
.collect::<Result<Vec<_>, _>>()?;
let mut node_cfgs = Vec::new();
for account in accounts.iter().take(cfg.nodes) {
node_cfgs.push(local::Node::dry_run(&ctx, account, &cfg).await?);
}

let candidates: HashMap<AccountId, CandidateInfo> = accounts
.iter()
.cloned()
.zip(&node_cfgs)
.map(|(account, node_cfg)| {
(
account.id().clone(),
CandidateInfo {
account_id: account.id().as_str().parse().unwrap(),
url: format!("http://127.0.0.1:{0}", node_cfg.web_port),
cipher_pk: node_cfg.cipher_pk.to_bytes(),
sign_pk: node_cfg.sign_sk.public_key().to_string().parse().unwrap(),
},
)
})
.collect();

println!("\nPlease call below to update localnet:\n");
let near_rpc = ctx.lake_indexer.rpc_host_address.clone();
println!("near config add-connection --network-name local --connection-name local --rpc-url {} --wallet-url http://127.0.0.1/ --explorer-transaction-url http://127.0.0.1:6666/", near_rpc);
println!("\nAfter run the nodes, please call the following command to init contract: ");
let args = json!({
"threshold": cfg.threshold,
"candidates": candidates
})
.to_string();
let sk = SecretKey::from_seed(KeyType::ED25519, "testificate");

println!("near contract call-function as-transaction {} init json-args '{}' prepaid-gas '100.0 Tgas' attached-deposit '0 NEAR' sign-as {} network-config local sign-with-plaintext-private-key --signer-public-key {} --signer-private-key {} send",
ctx.mpc_contract.id(),
args,
ctx.mpc_contract.id(),
sk.public_key(),
sk
);
println!();

Ok(ctx)
}

pub async fn host(cfg: MultichainConfig, docker_client: &DockerClient) -> anyhow::Result<Nodes> {
let ctx = setup(docker_client).await?;

Expand Down Expand Up @@ -351,6 +408,17 @@ pub async fn run(cfg: MultichainConfig, docker_client: &DockerClient) -> anyhow:
return host(cfg, docker_client).await;
}

pub async fn dry_run(
cfg: MultichainConfig,
docker_client: &DockerClient,
) -> anyhow::Result<Context> {
#[cfg(feature = "docker-test")]
unimplemented!("dry_run only works with native node");

#[cfg(not(feature = "docker-test"))]
return dry_host(cfg, docker_client).await;
}

async fn fetch_from_validator(
docker_client: &containers::DockerClient,
container: &Container<'_, GenericImage>,
Expand Down
68 changes: 68 additions & 0 deletions integration-tests/chain-signatures/src/local.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use crate::{execute, utils, MultichainConfig};

use crate::containers::LakeIndexer;
use crate::execute::executable;
use anyhow::Context;
use async_process::Child;
use mpc_keys::hpke;
use mpc_node::config::OverrideConfig;
use near_workspaces::Account;
use shell_escape::escape;

pub struct Node {
pub address: String,
Expand Down Expand Up @@ -33,6 +36,71 @@ pub struct NodeConfig {
}

impl Node {
pub async fn dry_run(
ctx: &super::Context<'_>,
account: &Account,
cfg: &MultichainConfig,
) -> anyhow::Result<NodeConfig> {
let account_id = account.id();
let account_sk = account.secret_key();
let web_port = utils::pick_unused_port().await?;
let (cipher_sk, cipher_pk) = hpke::generate();
let sign_sk =
near_crypto::SecretKey::from_seed(near_crypto::KeyType::ED25519, "integration-test");

let indexer_options = mpc_node::indexer::Options {
s3_bucket: ctx.localstack.s3_bucket.clone(),
s3_region: ctx.localstack.s3_region.clone(),
s3_url: Some(ctx.localstack.s3_host_address.clone()),
start_block_height: 0,
running_threshold: 120,
behind_threshold: 120,
};
let near_rpc = ctx.lake_indexer.rpc_host_address.clone();
let mpc_contract_id = ctx.mpc_contract.id().clone();
let cli = mpc_node::cli::Cli::Start {
near_rpc: near_rpc.clone(),
mpc_contract_id: mpc_contract_id.clone(),
account_id: account_id.clone(),
account_sk: account_sk.to_string().parse()?,
web_port,
cipher_pk: hex::encode(cipher_pk.to_bytes()),
cipher_sk: hex::encode(cipher_sk.to_bytes()),
sign_sk: Some(sign_sk.clone()),
indexer_options,
my_address: None,
storage_options: ctx.storage_options.clone(),
override_config: Some(OverrideConfig::new(serde_json::to_value(
cfg.protocol.clone(),
)?)),
client_header_referer: None,
};

let cmd = executable(ctx.release, crate::execute::PACKAGE_MULTICHAIN)
.with_context(|| "could not find target dir for mpc-node")?;
let args = cli.into_str_args();
let escaped_args: Vec<_> = args
.iter()
.map(|arg| escape(arg.clone().into()).to_string())
.collect();
println!(
"\nCommand to run node {}:\n {} {}",
account_id,
cmd.to_str().unwrap(),
escaped_args.join(" ")
);
let node_config = NodeConfig {
web_port,
account: account.clone(),
cipher_pk,
cipher_sk,
sign_sk,
cfg: cfg.clone(),
near_rpc,
};
Ok(node_config)
}

pub async fn run(
ctx: &super::Context<'_>,
cfg: &MultichainConfig,
Expand Down
12 changes: 9 additions & 3 deletions integration-tests/chain-signatures/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clap::Parser;
use integration_tests_chain_signatures::containers::DockerClient;
use integration_tests_chain_signatures::{run, setup, utils, MultichainConfig};
use integration_tests_chain_signatures::{dry_run, run, utils, MultichainConfig};
use tokio::signal;
use tracing_subscriber::EnvFilter;

Expand Down Expand Up @@ -69,8 +69,14 @@ async fn main() -> anyhow::Result<()> {
println!("Clean up finished");
}
Cli::DepServices => {
println!("Settting up dependency services");
let _ctx = setup(&docker_client).await?;
println!("Setting up dependency services");
let config = MultichainConfig::default();
let _ctx = dry_run(config.clone(), &docker_client).await?;

println!("Press Ctrl-C to stop dependency services");
signal::ctrl_c().await.expect("Failed to listen for event");
println!("Received Ctrl-C");
println!("Stopped dependency services");
}
}

Expand Down

0 comments on commit 3715df1

Please sign in to comment.