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

test(wallet-integration): unit tests for pop up contract #374

Merged
merged 27 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9f7f430
chore: get_payload_works
al3mart Dec 11, 2024
1485dfa
test(wallet-integration): up contract get payload works
al3mart Dec 12, 2024
55addf5
get paylaod from server works
al3mart Dec 12, 2024
e6a5d6a
test(wallet-integration): retrieve upload call data works
al3mart Dec 12, 2024
3bd4c7b
test(wallet-integration): retrieve instantiate call data works
al3mart Dec 12, 2024
c03f658
style: better comments
al3mart Dec 12, 2024
3e8266d
test: try higher wait times in CI
al3mart Dec 12, 2024
a391771
test(wallet-integration): bump sleep time
al3mart Dec 12, 2024
193582a
test(wallet-integration): even more sleep time
al3mart Dec 12, 2024
0075e94
test(wallet-integration): maybe a port problem ?
al3mart Dec 12, 2024
50bd1c8
revert 0075e94
al3mart Dec 12, 2024
b3d6aa3
test(wallet-integration): better unit tests
al3mart Dec 13, 2024
ebaf925
test(wallet-integration): wait for wallet signature
al3mart Dec 13, 2024
4f7798e
test(wallet-integration): assert on received payload
al3mart Dec 13, 2024
3460818
test(wallet-integration): use tokio spawn
al3mart Dec 13, 2024
6f2dd8c
test(wallet-integration): add some waiting time
al3mart Dec 13, 2024
0784af7
test(wallet-integration): use cargo run
al3mart Dec 13, 2024
9cb21a0
style: nightly fmt
al3mart Dec 13, 2024
4c4d3b2
test(wallet-integration): 500s sleep time
al3mart Dec 13, 2024
13cc493
test(wallet-integration): ignore some tests
al3mart Dec 13, 2024
1edf8dc
test(wallet-integration): get instantiate call data
al3mart Dec 13, 2024
76b8aec
test(wallet-integration): integration tests improvements
al3mart Dec 13, 2024
50818a4
test(wallet-integration): bump sleep time
al3mart Dec 13, 2024
59509cb
test(wallet-integration): merge integration tests
al3mart Dec 13, 2024
f9851d1
test(wallet-integration): remove sign_call_data test
al3mart Dec 15, 2024
80f4f7b
test(wallet-integration): use random free port
al3mart Dec 15, 2024
86ab4b8
test(wallet-integration): define gas_limit & proof_size
al3mart Dec 15, 2024
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
9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,13 @@ walkdir = "2.5"
indexmap = "2.2"
toml_edit = { version = "0.22", features = ["serde"] }
symlink = "0.1"
scale-info = { version = "2.11.3", default-features = false, features = ["derive"] }
scale-value = { version = "0.16.2", default-features = false, features = ["from-string", "parser-ss58"] }
scale-info = { version = "2.11.3", default-features = false, features = [
"derive",
] }
scale-value = { version = "0.16.2", default-features = false, features = [
"from-string",
"parser-ss58",
] }
serde_json = { version = "1.0", features = ["preserve_order"] }
serde = { version = "1.0", features = ["derive"] }
zombienet-sdk = "0.2.14"
Expand Down
2 changes: 2 additions & 0 deletions crates/pop-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ tower-http = { workspace = true, features = ["fs"] }

[dev-dependencies]
assert_cmd.workspace = true
contract-extrinsics.workspace = true
predicates.workspace = true
subxt.workspace = true
subxt-signer.workspace = true
sp-weights.workspace = true

[features]
default = ["contract", "parachain", "telemetry"]
Expand Down
136 changes: 131 additions & 5 deletions crates/pop-cli/src/commands/up/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,16 @@ fn display_contract_info(spinner: &ProgressBar, address: String, code_hash: Opti
#[cfg(test)]
mod tests {
use super::*;
use pop_common::{find_free_port, set_executable_permission};
use pop_contracts::{contracts_node_generator, mock_build_process, new_environment};
use std::{
env,
process::{Child, Command},
time::Duration,
};
use subxt::{tx::Payload, SubstrateConfig};
use tempfile::TempDir;
use tokio::time::sleep;
use url::Url;

fn default_up_contract_command() -> UpContractCommand {
Expand All @@ -417,6 +427,28 @@ mod tests {
}
}

async fn start_test_environment() -> anyhow::Result<(Child, u16, TempDir)> {
let random_port = find_free_port();
let temp_dir = new_environment("testing")?;
let current_dir = env::current_dir().expect("Failed to get current directory");
mock_build_process(
temp_dir.path().join("testing"),
current_dir.join("../pop-contracts/tests/files/testing.contract"),
current_dir.join("../pop-contracts/tests/files/testing.json"),
)?;
let cache = temp_dir.path().join("");
let binary = contracts_node_generator(cache.clone(), None).await?;
binary.source(false, &(), true).await?;
set_executable_permission(binary.path())?;
let process = run_contracts_node(binary.path(), None, random_port).await?;
Ok((process, random_port, temp_dir))
}

fn stop_test_environment(id: &str) -> anyhow::Result<()> {
Command::new("kill").args(["-s", "TERM", id]).spawn()?.wait()?;
Ok(())
}

#[test]
fn conversion_up_contract_command_to_up_opts_works() -> anyhow::Result<()> {
let command = default_up_contract_command();
Expand All @@ -438,15 +470,109 @@ mod tests {
Ok(())
}

#[tokio::test]
async fn get_upload_call_data_works() -> anyhow::Result<()> {
todo!()
let (contracts_node_process, port, temp_dir) = start_test_environment().await?;
let localhost_url = format!("ws://127.0.0.1:{}", port);
sleep(Duration::from_secs(20)).await;

let up_contract_opts = UpContractCommand {
path: Some(temp_dir.path().join("testing")),
constructor: "new".to_string(),
args: vec![],
value: "0".to_string(),
gas_limit: None,
proof_size: None,
salt: None,
url: Url::parse(&localhost_url).expect("given url is valid"),
suri: "//Alice".to_string(),
dry_run: false,
upload_only: true,
skip_confirm: true,
use_wallet: true,
};

let rpc_client = subxt::backend::rpc::RpcClient::from_url(&up_contract_opts.url).await?;
let client = subxt::OnlineClient::<SubstrateConfig>::from_rpc_client(rpc_client).await?;

// Retrieve call data based on the above command options.
let (retrieved_call_data, _) = match up_contract_opts.get_contract_data().await {
Ok(data) => data,
Err(e) => {
error(format!("An error occurred getting the call data: {e}"))?;
return Err(e);
},
};
// We have retrieved some payload.
assert!(!retrieved_call_data.is_empty());

// Craft encoded call data for an upload code call.
let contract_code = get_contract_code(up_contract_opts.path.as_ref()).await?;
let storage_deposit_limit: Option<u128> = None;
let upload_code = contract_extrinsics::extrinsic_calls::UploadCode::new(
contract_code,
storage_deposit_limit,
contract_extrinsics::upload::Determinism::Enforced,
);
let expected_call_data = upload_code.build();
let mut encoded_expected_call_data = Vec::<u8>::new();
expected_call_data
.encode_call_data_to(&client.metadata(), &mut encoded_expected_call_data)?;

// Retrieved call data and calculated match.
assert_eq!(retrieved_call_data, encoded_expected_call_data);

// Stop running contracts-node
stop_test_environment(&contracts_node_process.id().to_string())?;
Ok(())
}

#[tokio::test]
async fn get_instantiate_call_data_works() -> anyhow::Result<()> {
todo!()
}
let (contracts_node_process, port, temp_dir) = start_test_environment().await?;
let localhost_url = format!("ws://127.0.0.1:{}", port);
sleep(Duration::from_secs(20)).await;

async fn wait_for_signature_works() -> anyhow::Result<()> {
todo!()
let up_contract_opts = UpContractCommand {
path: Some(temp_dir.path().join("testing")),
constructor: "new".to_string(),
args: vec!["false".to_string()],
value: "0".to_string(),
gas_limit: Some(200_000_000),
proof_size: Some(30_000),
salt: None,
url: Url::parse(&localhost_url).expect("given url is valid"),
suri: "//Alice".to_string(),
dry_run: false,
upload_only: false,
skip_confirm: true,
use_wallet: true,
};

let rpc_client = subxt::backend::rpc::RpcClient::from_url(&up_contract_opts.url).await?;
let client = subxt::OnlineClient::<SubstrateConfig>::from_rpc_client(rpc_client).await?;

// Retrieve call data based on the above command options.
let (retrieved_call_data, _) = match up_contract_opts.get_contract_data().await {
Ok(data) => data,
Err(e) => {
error(format!("An error occurred getting the call data: {e}"))?;
return Err(e);
},
};
// We have retrieved some payload.
assert!(!retrieved_call_data.is_empty());

// Craft instantiate call data.
let weight = Weight::from_parts(200_000_000, 30_000);
let expected_call_data =
get_instantiate_payload(set_up_deployment(up_contract_opts.into()).await?, weight)
.await?;
// Retrieved call data matches the one crafted above.
assert_eq!(retrieved_call_data, expected_call_data);

// Stop running contracts-node
stop_test_environment(&contracts_node_process.id().to_string())?;
Ok(())
}
}
60 changes: 0 additions & 60 deletions crates/pop-cli/src/common/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,63 +36,3 @@ pub async fn wait_for_signature(call_data: Vec<u8>, url: String) -> anyhow::Resu
let signed_payload = wallet.state.lock().await.signed_payload.clone();
Ok(signed_payload)
}

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

// TODO: delete this test.
// This is a helper test for an actual running pop CLI.
// It can serve as the "frontend" to query the payload, sign it
// and submit back to the CLI.
#[tokio::test]
async fn sign_call_data() -> anyhow::Result<()> {
use subxt::{config::DefaultExtrinsicParamsBuilder as Params, tx::Payload};
// This struct implements the [`Payload`] trait and is used to submit
// pre-encoded SCALE call data directly, without the dynamic construction of transactions.
struct CallData(Vec<u8>);

impl Payload for CallData {
fn encode_call_data_to(
&self,
_: &subxt::Metadata,
out: &mut Vec<u8>,
) -> Result<(), subxt::ext::subxt_core::Error> {
out.extend_from_slice(&self.0);
Ok(())
}
}

use subxt_signer::sr25519::dev;
let payload = reqwest::get(&format!("{}/payload", "http://127.0.0.1:9090"))
.await
.expect("Failed to get payload")
.json::<TransactionData>()
.await
.expect("Failed to parse payload");

let url = "ws://localhost:9944";
let rpc_client = subxt::backend::rpc::RpcClient::from_url(url).await?;
let client =
subxt::OnlineClient::<subxt::SubstrateConfig>::from_rpc_client(rpc_client).await?;

let signer = dev::alice();

let payload = CallData(payload.call_data());
let ext_params = Params::new().build();
let signed = client.tx().create_signed(&payload, &signer, ext_params).await?;

let response = reqwest::Client::new()
.post(&format!("{}/submit", "http://localhost:9090"))
.json(&to_hex(signed.encoded()))
.send()
.await
.expect("Failed to submit payload")
.text()
.await
.expect("Failed to parse JSON response");

Ok(())
}
}
Loading
Loading