Skip to content

Commit

Permalink
Add Rust lightning latch test
Browse files Browse the repository at this point in the history
  • Loading branch information
ssantos21 committed Jul 16, 2024
1 parent 31bb7ee commit db6d7af
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 9 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions clients/tests/rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ serde = { version = "1.0.163", features = ["derive"] }
serde_json = "1.0.96"
electrum-client = "0.18.0"
uuid = { version = "1.3.1", features = ["v4", "serde"] }
sha2 = "0.10.8"
hex = "0.4.3"
9 changes: 7 additions & 2 deletions clients/tests/rust/src/bitcoin_core.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::process::Command;
use std::{process::Command, thread};
use anyhow::{anyhow, Result, Ok};

pub fn get_container_id() -> Result<String> {
Expand Down Expand Up @@ -56,7 +56,12 @@ pub fn generatetoaddress(num_blocks: u32, address: &str) -> Result<String> {
"bitcoin-cli -regtest -rpcuser=user -rpcpassword=pass generatetoaddress {} {}", num_blocks, address
);

execute_bitcoin_command(&bitcoin_command)
let res = execute_bitcoin_command(&bitcoin_command);

// The command may take some time to execute
thread::sleep(std::time::Duration::from_secs(1));

res
}

pub fn getnewaddress() -> Result<String> {
Expand Down
4 changes: 3 additions & 1 deletion clients/tests/rust/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub mod tb02_transfer_address_reuse;
pub mod tb03_simple_atomic_transfer;
pub mod tm01_sender_double_spends;
pub mod ta01_sign_second_not_called;
pub mod tb04_simple_lightning_latch;
use anyhow::{Result, Ok};

#[tokio::main(flavor = "current_thread")]
Expand All @@ -14,8 +15,9 @@ async fn main() -> Result<()> {
tb01_simple_transfer::execute().await?;
tb02_transfer_address_reuse::execute().await?;
tb03_simple_atomic_transfer::execute().await?;
tb04_simple_lightning_latch::execute().await?;
tm01_sender_double_spends::execute().await?;
ta01_sign_second_not_called::execute().await?;

Ok(())
}
2 changes: 1 addition & 1 deletion clients/tests/rust/src/tb03_simple_atomic_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ pub async fn execute() -> Result<()> {

tb03(&client_config, &wallet1, &wallet2, &wallet3, &wallet4).await?;

println!("TB03- Simple Atomic Transfer Test completed successfully");
println!("TB03 - Simple Atomic Transfer Test completed successfully");

Ok(())
}
97 changes: 97 additions & 0 deletions clients/tests/rust/src/tb04_simple_lightning_latch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use std::{env, process::Command, thread, time::Duration};
use anyhow::{Result, Ok};
use mercuryrustlib::{client_config::ClientConfig, CoinStatus, Wallet};

use crate::{bitcoin_core, electrs};

use sha2::{Sha256, Digest};

pub async fn tb04(client_config: &ClientConfig, wallet1: &Wallet, wallet2: &Wallet) -> Result<()> {

let amount = 1000;

// Create first deposit address

let token_id = mercuryrustlib::deposit::get_token(client_config).await?;

let deposit_address = mercuryrustlib::deposit::get_deposit_bitcoin_address(&client_config, &wallet1.name, &token_id, amount).await?;

let _ = bitcoin_core::sendtoaddress(amount, &deposit_address)?;

let core_wallet_address = bitcoin_core::getnewaddress()?;
let remaining_blocks = client_config.confirmation_target;
let _ = bitcoin_core::generatetoaddress(remaining_blocks, &core_wallet_address)?;

// It appears that Electrs takes a few seconds to index the transaction
let mut is_tx_indexed = false;

while !is_tx_indexed {
is_tx_indexed = electrs::check_address(client_config, &deposit_address, amount).await?;
thread::sleep(Duration::from_secs(1));
}

mercuryrustlib::coin_status::update_coins(&client_config, &wallet1.name).await?;
let wallet1: mercuryrustlib::Wallet = mercuryrustlib::sqlite_manager::get_wallet(&client_config.pool, &wallet1.name).await?;
let new_coin = wallet1.coins.iter().find(|&coin| coin.aggregated_address == Some(deposit_address.clone()) && coin.status == CoinStatus::CONFIRMED).unwrap();
let statechain_id = new_coin.statechain_id.as_ref().unwrap();

let response = mercuryrustlib::lightning_latch::create_pre_image(&client_config, &wallet1.name, statechain_id).await?;

let batch_id = response.batch_id;
let hash = response.hash;

let wallet2_transfer_adress = mercuryrustlib::transfer_receiver::new_transfer_address(&client_config, &wallet2.name).await?;

mercuryrustlib::transfer_sender::execute(&client_config, &wallet2_transfer_adress, &wallet1.name, statechain_id, Some(batch_id.clone())).await?;

let transfer_receive_result = mercuryrustlib::transfer_receiver::execute(&client_config, &wallet2.name).await?;

assert!(transfer_receive_result.is_there_batch_locked);
assert!(transfer_receive_result.received_statechain_ids.is_empty());

mercuryrustlib::lightning_latch::confirm_pending_invoice(&client_config, &wallet1.name, &statechain_id).await?;

let transfer_receive_result = mercuryrustlib::transfer_receiver::execute(&client_config, &wallet2.name).await?;

assert!(!transfer_receive_result.is_there_batch_locked);
assert!(!transfer_receive_result.received_statechain_ids.is_empty());

let pre_image = mercuryrustlib::lightning_latch::retrieve_pre_image(&client_config, &wallet1.name, &statechain_id, &batch_id).await?;

let mut hasher = Sha256::new();
hasher.update(pre_image.as_bytes());
let result = hasher.finalize();

let sha256_pre_image = hex::encode(result);

assert!(sha256_pre_image == hash);

Ok(())
}

pub async fn execute() -> Result<()> {

let _ = Command::new("rm").arg("wallet.db").arg("wallet.db-shm").arg("wallet.db-wal").output().expect("failed to execute process");

env::set_var("ML_NETWORK", "regtest");

let client_config = mercuryrustlib::client_config::load().await;

let wallet1 = mercuryrustlib::wallet::create_wallet(
"wallet1",
&client_config).await?;

mercuryrustlib::sqlite_manager::insert_wallet(&client_config.pool, &wallet1).await?;

let wallet2 = mercuryrustlib::wallet::create_wallet(
"wallet2",
&client_config).await?;

mercuryrustlib::sqlite_manager::insert_wallet(&client_config.pool, &wallet2).await?;

tb04(&client_config, &wallet1, &wallet2).await?;

println!("TB04 - Simple Lightning Latch completed successfully");

Ok(())
}
1 change: 1 addition & 0 deletions server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ secp256k1-zkp = { git = "https://github.com/ssantos21/rust-secp256k1-zkp.git", b
# secp256k1-zkp = { path = "../ss-rust-secp256k1-zkp", features = [ "rand-std", "bitcoin_hashes", "std" ] }
mercurylib = { path = "../lib" }
chrono = "0.4.31"
sha2 = "0.10.8"
13 changes: 8 additions & 5 deletions server/src/endpoints/lightning_latch.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::str::FromStr;

use bitcoin::hashes::Hash;
use chrono::Duration;
use hex::encode;
use mercurylib::transfer::sender::{PaymentHashRequestPayload, PaymentHashResponsePayload, TransferPreimageRequestPayload, TransferPreimageResponsePayload};
Expand All @@ -9,6 +8,8 @@ use rocket::{State, serde::json::Json, response::status, http::Status};
use secp256k1_zkp::PublicKey;
use serde_json::{json, Value};

use sha2::{Sha256, Digest};

use crate::server::StateChainEntity;

#[post("/transfer/paymenthash", format = "json", data = "<payment_hash_payload>")]
Expand All @@ -30,17 +31,19 @@ pub async fn paymenthash(statechain_entity: &State<StateChainEntity>, payment_ha
let sender_auth_key = super::utils::get_auth_key_by_statechain_id(&statechain_entity.pool, &statechain_id).await.unwrap();

let buffer = rand::thread_rng().gen::<[u8; 32]>();
let pre_image = encode(&buffer.clone());
let pre_image = encode(buffer.clone());

let now = chrono::Utc::now();
let expiry_time = Duration::seconds(90000); // 25h
let expires_at = now + expiry_time;

crate::database::lightning_latch::insert_paymenthash(&statechain_entity.pool, &statechain_id, &sender_auth_key, &batch_id, &pre_image, &expires_at).await;

let result_hash = bitcoin::hashes::sha256::Hash::hash(&buffer);
let hash_bytes = result_hash.as_byte_array();
let payment_hash = encode(hash_bytes);
let mut hasher = Sha256::new();
hasher.update(pre_image.as_bytes());
let result = hasher.finalize();

let payment_hash = hex::encode(result);

let payment_hash_response_payload = PaymentHashResponsePayload {
hash: payment_hash,
Expand Down

0 comments on commit db6d7af

Please sign in to comment.