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

feat(cli): dirk delegations integration test #358

Merged
merged 1 commit into from
Nov 5, 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
41 changes: 38 additions & 3 deletions bolt-cli/src/commands/delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,18 +363,18 @@ pub fn verify_message_signature(message: &SignedMessage, chain: Chain) -> Result
mod tests {
use crate::{
cli::{Action, Chain},
common::{keystore::KeystoreSecret, parse_bls_public_key},
common::{dirk, keystore, parse_bls_public_key},
};

use super::{generate_from_keystore, verify_message_signature};
use super::{generate_from_dirk, generate_from_keystore, verify_message_signature};

#[test]
fn test_delegation_keystore_signer_lighthouse() -> eyre::Result<()> {
// Read the keystore from test_data
let keys_path = env!("CARGO_MANIFEST_DIR").to_string() + "/test_data/lighthouse/validators";
let secrets_path = env!("CARGO_MANIFEST_DIR").to_string() + "/test_data/lighthouse/secrets";

let keystore_secret = KeystoreSecret::from_directory(&secrets_path)?;
let keystore_secret = keystore::KeystoreSecret::from_directory(&secrets_path)?;

let delegatee_pubkey = "0x83eeddfac5e60f8fe607ee8713efb8877c295ad9f8ca075f4d8f6f2ae241a30dd57f78f6f3863a9fe0d5b5db9d550b93";
let delegatee_pubkey = parse_bls_public_key(delegatee_pubkey)?;
Expand All @@ -394,4 +394,39 @@ mod tests {

Ok(())
}

/// Test generating signed delegations using a remote Dirk signer.
///
/// ```shell
/// cargo test --package bolt --bin bolt -- commands::delegate::tests::test_delegation_dirk
/// --exact --show-output --ignored --nocapture
/// ```
#[tokio::test]
#[ignore]
async fn test_delegation_dirk() -> eyre::Result<()> {
let _ = tracing_subscriber::fmt::try_init();
let (mut dirk, mut dirk_proc) = dirk::test_util::start_dirk_test_server().await?;

let delegatee_pubkey = "0x83eeddfac5e60f8fe607ee8713efb8877c295ad9f8ca075f4d8f6f2ae241a30dd57f78f6f3863a9fe0d5b5db9d550b93";
let delegatee_pubkey = parse_bls_public_key(delegatee_pubkey)?;
let chain = Chain::Mainnet;

let signed_delegations = generate_from_dirk(
&mut dirk,
delegatee_pubkey.clone(),
"wallet1".to_string(),
Some(vec!["secret".to_string()]),
chain,
Action::Delegate,
)
.await?;

let signed_message = signed_delegations.first().expect("to get signed delegation");

verify_message_signature(signed_message, chain)?;

dirk_proc.kill()?;

Ok(())
}
}
12 changes: 6 additions & 6 deletions bolt-cli/src/commands/send.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ impl SendCommand {
let wallet: PrivateKeySigner = self.private_key.parse().wrap_err("invalid private key")?;

if self.devnet {
self.send_devnet_transaction(&wallet).await
self.send_devnet_transaction(wallet).await
} else {
self.send_transaction(&wallet).await
self.send_transaction(wallet).await
}
}

/// Send a transaction.
async fn send_transaction(self, wallet: &PrivateKeySigner) -> Result<()> {
async fn send_transaction(self, wallet: PrivateKeySigner) -> Result<()> {
let transaction_signer = EthereumWallet::from(wallet.clone());
let provider = ProviderBuilder::new()
.with_recommended_fillers()
Expand Down Expand Up @@ -90,7 +90,7 @@ impl SendCommand {
vec![tx_hash],
target_slot,
target_url.clone(),
wallet,
&wallet,
)
.await?;

Expand All @@ -102,7 +102,7 @@ impl SendCommand {
}

/// Send a transaction on the Kurtosis devnet.
async fn send_devnet_transaction(self, wallet: &PrivateKeySigner) -> Result<()> {
async fn send_devnet_transaction(self, wallet: PrivateKeySigner) -> Result<()> {
let transaction_signer = EthereumWallet::from(wallet.clone());
let el_url = self.devnet_execution_url.clone().wrap_err("missing devnet execution URL")?;
let cl_url = self.devnet_beacon_url.clone().wrap_err("missing devnet beacon URL")?;
Expand Down Expand Up @@ -137,7 +137,7 @@ impl SendCommand {
vec![tx_hash],
slot + 2,
sidecar_url.clone(),
wallet,
&wallet,
)
.await?;

Expand Down
86 changes: 53 additions & 33 deletions bolt-cli/src/common/dirk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,27 +152,42 @@ fn compose_credentials(creds: TlsCredentials) -> Result<ClientTlsConfig> {
}

#[cfg(test)]
mod tests {
use std::{process::Command, time::Duration};

use super::*;
pub mod test_util {
use eyre::{bail, Context};
use rustls::crypto::CryptoProvider;
use std::{
fs,
process::{Child, Command},
time::Duration,
};

use super::Dirk;
use crate::cli::TlsCredentials;

/// Initialize the default TLS provider for the tests if not already set.
pub fn try_init_tls_provider() {
// Init the default rustls provider
if CryptoProvider::get_default().is_none() {
let _ = rustls::crypto::ring::default_provider().install_default();
}
}

/// Test connecting to a DIRK server and listing available accounts.
/// Start a DIRK test server for testing (run on localhost:9091).
///
/// ```shell
/// cargo test --package bolt -- utils::dirk::tests::test_dirk_connection_e2e
/// --exact --show-output --ignored
/// ```
#[tokio::test]
#[ignore]
async fn test_dirk_connection_e2e() -> eyre::Result<()> {
// Init the default rustls provider
let _ = rustls::crypto::ring::default_provider().install_default();
/// Returns the DIRK client and the corresponding server process handle.
pub async fn start_dirk_test_server() -> eyre::Result<(Dirk, Child)> {
try_init_tls_provider();

let test_data_dir = env!("CARGO_MANIFEST_DIR").to_string() + "/test_data/dirk";

// Init the DIRK config file
init_dirk_config(test_data_dir.clone())?;
// read the template json file from test_data
let template_path = test_data_dir.clone() + "/dirk.template.json";
let template = fs::read_to_string(template_path).wrap_err("Failed to read template")?;

// change the occurrence of $PWD to the current working directory in the template
let new_file = test_data_dir.clone() + "/dirk.json";
let new_content = template.replace("$PWD", &test_data_dir);
fs::write(new_file, new_content).wrap_err("Failed to write dirk config file")?;

// Check if dirk is installed (in $PATH)
if Command::new("dirk")
Expand All @@ -182,12 +197,11 @@ mod tests {
.status()
.is_err()
{
eprintln!("DIRK is not installed in $PATH");
return Ok(());
bail!("DIRK is not installed in $PATH");
}

// Start the DIRK server in the background
let mut dirk_proc = Command::new("dirk").arg("--base-dir").arg(&test_data_dir).spawn()?;
let dirk_proc = Command::new("dirk").arg("--base-dir").arg(&test_data_dir).spawn()?;

// Wait for some time for the server to start up
tokio::time::sleep(Duration::from_secs(3)).await;
Expand All @@ -200,7 +214,26 @@ mod tests {
ca_cert_path: Some(test_data_dir.clone() + "/security/ca.crt"),
};

let mut dirk = Dirk::connect(url, cred).await?;
let dirk = Dirk::connect(url, cred).await?;

Ok((dirk, dirk_proc))
}
}

#[cfg(test)]
mod tests {
use super::*;

/// Test connecting to a DIRK server and listing available accounts.
///
/// ```shell
/// cargo test --package bolt --bin bolt -- common::dirk::tests::test_dirk_connection_e2e
/// --exact --show-output --ignored
/// ```
#[tokio::test]
#[ignore]
async fn test_dirk_connection_e2e() -> eyre::Result<()> {
let (mut dirk, mut dirk_proc) = test_util::start_dirk_test_server().await?;

let accounts = dirk.list_accounts("wallet1".to_string()).await?;
println!("Dirk Accounts: {:?}", accounts);
Expand All @@ -210,17 +243,4 @@ mod tests {

Ok(())
}

fn init_dirk_config(test_data_dir: String) -> eyre::Result<()> {
// read the template json file from test_data
let template_path = test_data_dir.clone() + "/dirk.template.json";
let template = fs::read_to_string(template_path).wrap_err("Failed to read template")?;

// change the occurrence of $PWD to the current working directory in the template
let new_file = test_data_dir.clone() + "/dirk.json";
let new_content = template.replace("$PWD", &test_data_dir);
fs::write(new_file, new_content).wrap_err("Failed to write dirk config file")?;

Ok(())
}
}
3 changes: 2 additions & 1 deletion bolt-cli/test_data/dirk/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
dirk.json
dirk.json
storage/
Binary file removed bolt-cli/test_data/dirk/storage/000000.vlog
Binary file not shown.
1 change: 0 additions & 1 deletion bolt-cli/test_data/dirk/storage/KEYREGISTRY

This file was deleted.

1 change: 0 additions & 1 deletion bolt-cli/test_data/dirk/storage/LOCK

This file was deleted.

Binary file removed bolt-cli/test_data/dirk/storage/MANIFEST
Binary file not shown.
Loading