diff --git a/bitcoin-rpc-provider/src/lib.rs b/bitcoin-rpc-provider/src/lib.rs index 43b2e217..9f44be59 100644 --- a/bitcoin-rpc-provider/src/lib.rs +++ b/bitcoin-rpc-provider/src/lib.rs @@ -183,12 +183,12 @@ impl ContractSignerProvider for BitcoinCoreProvider { "getaddressesbylabel", &[Value::String(keys_id.to_lower_hex_string())], ) - .map_err(rpc_err_to_manager_err)?; + .unwrap_or_default(); if let Some(address) = label_map.keys().next() { - // we should only have one address per keys_id - // if not something has gone wrong - assert_eq!(label_map.len(), 1); + // note: importing a private key seem to generate three different addresses, we thus + // check that we have exactly three addresses for a single `keys_id`. + assert_eq!(label_map.len(), 3); let sk = self .client @@ -274,7 +274,7 @@ impl Wallet for BitcoinCoreProvider { .unwrap() .call::>( "getrawchangeaddress", - &[Value::Null, opt_into_json(Some(AddressType::Bech32))?], + &[opt_into_json(Some(AddressType::Bech32))?], ) .map_err(rpc_err_to_manager_err)? .assume_checked()) @@ -391,11 +391,18 @@ impl Wallet for BitcoinCoreProvider { } fn unreserve_utxos(&self, outpoints: &[OutPoint]) -> Result<(), ManagerError> { - match self.client.lock().unwrap().unlock_unspent(outpoints).map_err(rpc_err_to_manager_err)? { + match self + .client + .lock() + .unwrap() + .unlock_unspent(outpoints) + .map_err(rpc_err_to_manager_err)? + { true => Ok(()), - false => Err(ManagerError::StorageError(format!("Failed to unlock utxos: {outpoints:?}"))) + false => Err(ManagerError::StorageError(format!( + "Failed to unlock utxos: {outpoints:?}" + ))), } - } } diff --git a/sample/tests/cli_tests.rs b/sample/tests/cli_tests.rs new file mode 100644 index 00000000..3eb5d0c0 --- /dev/null +++ b/sample/tests/cli_tests.rs @@ -0,0 +1,77 @@ +use std::process::Command; + +use assert_cmd::cargo::cargo_bin; +use dlc_manager::contract::contract_input::ContractInput; +use rexpect::session::spawn_command; +use time::Duration; + +#[test] +fn sample_cli_test() { + let contract_str = include_str!("../examples/contracts/numerical_contract_input.json"); + let mut contract: ContractInput = serde_json::from_str(&contract_str).unwrap(); + let time_now = std::time::SystemTime::now(); + let unix_time = (time_now + .duration_since(std::time::SystemTime::UNIX_EPOCH) + .unwrap() + + Duration::new(300, 0)) + .as_seconds_f32() as u32; + contract.contract_infos[0].oracles.event_id = format!("btcusd{}", unix_time); + + let alice_config_str = include_str!("../examples/configurations/alice.yml"); + let bob_config_str = include_str!("../examples/configurations/bob.yml"); + std::fs::write( + "./numerical_contract_input.json", + serde_json::to_string(&contract).unwrap(), + ) + .unwrap(); + std::fs::write("./alice.yml", alice_config_str).unwrap(); + std::fs::write("./bob.yml", bob_config_str).unwrap(); + + let bin_path = cargo_bin("sample"); + let mut command = Command::new(bin_path.to_str().unwrap()); + command.arg("./alice.yml"); + let mut alice_cli = spawn_command(command, Some(5000)).unwrap(); + + alice_cli.exp_regex("[a-f0-9]{66}").unwrap(); + alice_cli.exp_char('>').unwrap(); + + let mut command = Command::new(bin_path.to_str().unwrap()); + command.arg("./bob.yml"); + let mut bob_cli = spawn_command(command, Some(5000)).unwrap(); + + let (_, bob_ip) = bob_cli.exp_regex("[a-f0-9]{66}").unwrap(); + bob_cli.exp_char('>').unwrap(); + + alice_cli + .send_line(&format!( + "offercontract {}@127.0.0.1:9001 ./numerical_contract_input.json", + bob_ip + )) + .unwrap(); + + alice_cli.exp_char('>').unwrap(); + + std::thread::sleep(std::time::Duration::from_secs(1)); + + bob_cli.send_line("listoffers").unwrap(); + + bob_cli.exp_string("Offer").unwrap(); + let (_, offer_id) = bob_cli.exp_regex("[a-f0-9]{64}").unwrap(); + + bob_cli + .send_line(&format!("acceptoffer {}", offer_id)) + .unwrap(); + bob_cli.exp_char('>').unwrap(); + + std::thread::sleep(std::time::Duration::from_secs(3)); + + alice_cli.send_line("listcontracts").unwrap(); + alice_cli.exp_string("Signed contract").unwrap(); + alice_cli.exp_char('>').unwrap(); + + std::thread::sleep(std::time::Duration::from_secs(3)); + + bob_cli.send_line("listcontracts").unwrap(); + bob_cli.exp_string("Signed contract").unwrap(); + bob_cli.exp_char('>').unwrap(); +}