Skip to content

Commit

Permalink
Release 0.2 (#91)
Browse files Browse the repository at this point in the history
* Changing React application structure to handle concurrency

* Changing React application structure to handle concurrency

* Changing React application structure to handle concurrency

* Changing React application structure to handle concurrency

* Changing React application structure to handle concurrency

* Changing React application structure to handle concurrency

* Changing React application structure to handle concurrency

* Changing React application structure to handle concurrency

* Changing React application structure to handle concurrency

* Changing React application structure to handle concurrency

* add token server

* fixes

* Remove thunks

* Improve backup transactions database and view

* Improve GUI

* Fix some warnings

* Fix some warnings

* Improve update function

* Improve GUI

* Remove DB transaction to avoid race condition

* config

* config

* add token server

* Update tokens.md

* Update Token struct

* Add WASM packages

* Improve UI

* Change react-app config file

* chore: add changes to get locofy-ui working

* chore: add key to wizard

* chore: add deposit process ui

* chore: add token ui logic

* chore: huge locofy ai changes, remove old code as wasn't scalable, learned new locofy formats

* chore: fix up icons

* chore: hook token info card and deposit page

* chore: update token card UI

* chore: add more validation to deposit process, and modal windows

* chore: update deposit pages

* add expiry time

* fix

* fix

* chore: finish the tab ui logic

* chore: add changes to deposit, hook up live methods to the deposit process, add loading spinners and validation

* add key check

* fix serialisation

* chore: add token insertion into wallet object, various other changes, wasm error in deposit 2

* chore: fix wallet load code

* chore: add back in validation for wizard page 2, cleanup the main header panel ui

* chore: refactor, add a logged in wallet hook, add validation to wallet page 1

* chore: show seed key in wizard states

* chore: fix error if coins / activities is null

* Modify Token struct

* chore: fix error message ordering in wizard page

* chore: move order of destructure variable in main page

* chore: fix coin item, display some info to user about their statecoin

* chore: add changes to main header panel, add up btc values

* chore: fix deposit addresses

* chore: change to testnet server, add withdraw ui components

* chore: fix more withdrawal logic, fix  bug in deposit 3 page

* chore: do not show withdrawn coins

* chore: add send page and logic

* chore: fix receive page

* chore: fix activities table

* chore: fix some navigation errors and settings page errors

* Add Settings property to wallet

* chore: add password encrypted db wallets, add error message handling for it, remove certain coins from UI

* chore: add backup from file/load into db

* chore: add changes to main load wallet

* chore: get latest password

* chore: change settings page

* chore: remove manage transactions from settings page as will be in modal

* chore: add settings ui hooked with redux state and notifications

* chore: add the reloading of wallets within load wallet page

* chore: remove debugging, add check on wizard for encrypted wallets instead of live wallets

* chore: fix loading from backup file to include backup tx

* chore: add more responsive main bar page, and add modal ui

* chore: fix coin modal and help page

* chore: remove amount

* chore: downgrade sql

* chore: enable debug mode

* chore: replace icon of app

* chore: huge fix for resources in wallet

* chore: add build

* chore: add dev branch

* chore: fix clearnet config issues, start a build

* chore: change actions

* chore: remove mainnet

* chore: remove mainnet

* chore: change github actions

* chore: change app icon

* chore: change app icon

* chore: remove unused files

* version: update to 0.1.1

* DB file path

* Update atomic_transfer.md

* Update atomic_transfer.md

typo

* Update atomic_transfer.md

Fixed typo

* Update atomic_transfer.md

* Update protocol.md

* Update transfer_sender_sequence.md

* Update transfer_receiver_sequence.md

* Update transfer_sender_sequence.md

* Update transfer_receiver_sequence.md

* Update protocol.md

* Add ChaCha20-Poly1305 encryption scheme

This commit adds ChaCha20-Poly1305 algorithm to be used
to encrypt any enclave data instead of using the SGX built-in
functions.
This way, the data can be decrypted on another machine as long
the same encryption key be used.
SGX functions are still used to seal and unseal the encryption key.

* Add password to add-mnemonic call

* Add Dockerfiles to SGX SIM mode

* Add docker files to the server

* Update protocol.md

* Update README.md

* Update deposit_sequence.md

* Update transfer_sender_sequence.md

* Update transfer_receiver_sequence.md

* Add docker files to the enclave - HW mode

* Remove r2 and blind commitments

* Change HRP to 'ml' and 'tml'

* Add address validation and remove standalone rust client

* Update WASM and rename lib

* Update atomic_transfer.md

* Update atomic_transfer.md

* Add UniFFI

* Re-add nodejs client

* Add kotlin client

* Use TransferReceiverPostResponsePayload

* Add Atomic transfer

* Use statechain_info to verify transfers

* Add automatic seed generation and replication

* Update react-app package.json

* Increase the maximum amount of time to spend waiting for a connection to 30s

* Allow coin to be withdrawn if in IN_TRANSFER status

* Fix minor errors regarding IN_TRANSFER status

* Update Kotlin client

* fix: server config with env for mercury & token server

* feat: add docker build for github actions

* feat: add dev branch to yaml

* fix: token server port

* fix: expose port in dockerfile for token-server

* fix: move Rocket.toml from sub folder to parent folder

* fix: add tls feature to sqlx

* fix: route for endpoint /info

* feat: add explorer

* feat: add keylist cronjob

* fix: version for docker images in ci/cd

* fix: add dev2 branch to ci/cd

* fix: import error with token server

* fix: mercury server start cmd

* fix: start cmd for mercury server

* debug: mercury server dockerfile

* fix: config for mercury and token server

* fix: mercury server dockerfile

* fix: dockerfile for mercury server

* Fix the mainnet address conversion

* Add address reuse functionality

* Create rust client lib

* Create nodejs client lib

* Update ECIES package and restructure project folders

* Add a new test file that uses the nodejs lib

* Fix docker error preventing Mercury server from starting

* Move signature validation from rust client lib to Mercury lib

* Refactor `clients/libs/rust/src/transfer_receiver.rs`. No change in behavior

* Use `validateSignatureScheme` in `clients/libs/nodejs/transfer_receive.js`

* Use `validateSignatureScheme` in `clients/apps/kotlin/TransferReceive.kt`

* Add web client lib

* Add `max_fee_rate` setting to rust lib

* Add `max_fee_rate` setting to nodejs lib

* Create client_guide.md

* Add `max_fee_rate` setting to web lib

* Update client_guide.md

* Update client_guide.md

* Update client_guide.md

* Add `max_fee_rate` setting to Kotlin client

* Add multiple enclave support

* Remove outdated react-app

* Handle fee rate < 0 in broadcast command

* Feat/fee unit

* Add integration tests on regtest mode
-------
Co-authored-by: DhananjayPurohit <[email protected]>

* Add Lightning Latch atomic transfer

* Improve transfer message verification

* Add basic Rust integration tests

* Add `batchtimeout` to `/info/config`

* fix: directory for Rocket.toml

* feat: add tests for coin expiry

* fix: add test for transfer-sender that make coin expired by sending

* fix: assertion for broadcast tx

* fix: add dev3 for integration tests

* Add TB02 - Transfer Address Reuse

* Add TM01 - Sender Double Spends

* chore: remove dev3 branch from integration tests

* Add TA01 - 'signSecond not called' and return the pubnonce if the challenge is null

* Refactor transfer-receive to make it non-blocking

* Refactor transfer-receive in nodeJS library to make it non-blocking

* Adjust tests to the new transferReceive function

* Add web lib tests

* Fix minor error in nodeJS transfer-receive

* Add lightning latch functions to the nodeJS client

* Add Rust lightning latch test

* Add nodeJs lightning latch test

* Feat/tests for atomic swap (#72)

---------

Co-authored-by: S. Santos <[email protected]>

* Add lightning latch functions to web client

* Improve nodeJS API parameters

* Change fee rate to f64 instead of u64

* fix: ci build on main branch only (#78)

* Handle multiple deposit transactions

* Add multiple deposit support to the nodeJS client

* Update test_basic_workflow2 to support duplicated deposits

* Update web client to support multiple deposits

* Automate web client testing

* Add Vitest to web client tests

* Update Dockerfile (#81)

* Update Dockerfile

* Create Rocket2.toml

* Update Dockerfile

* Revert "Update Dockerfile (#81)" (#83)

This reverts commit e37b627.

* Add GET `/transfer/paymenthash/<batch_id>`

* Add payment hash verification to nodeJS client

* Fix/dockerfile token server (#85)

* fix: token server dockerfile

* fix: build release for token server

* fix: upgrade sqlx version

* Add payment hash verification to web client

* Add log crate to the server

* fix: The pre-image is now only revealed if the transfer is unlocked.

* Set getrandom version

* Add rust-toolchain file to wasm project

* feat: add LND containers for testing (#77)

* feat: add LND containers for testing

* fix: lightning latch test run on actions

* fix: install mocha

* fix: wallet names

* feat: add test to get preimage before batch unlock

* feat: add test for sender recover coin after batch timeout

* fix: increase test timeout

* feat: wallet creation on lnd nodes

* feat: wallet creation on lnd nodes

* fix: wallet creation on start of lnd

* fix: wallet unlock flag

* debug: lnd node logs

* fix: add sleep for lnd to sync with latest block

* fix: upgrade lnd version

* fix: zmq flags in bitcoind config

* fix: port for node second to listen

* feat: add script to open channel

* feat: add fn to generate invoice

* fix: test failure

* feat: add test to steal hold invoice amount

* fix: await for hold invoice payment

* fix: import error

* fix: upgrade docker image version in actions

* fix: install docker compose

* fix: container name

* fix: network name

* fix: add assertion for invoice payment failure

* feat: add test for sender sends coin without batch_id

* feat: add fn for invoice verification against payment hash

* feat: add test for invoice verification

fix: walletname for invoice verification test

fix: payment hash for invoice verification test

* feat: setup web client tests on actions

* feat: setup esplora for actions

fix: esplora and node server for web client

fix: host for node server for web client

fix: dir for node server for web client

fix: volume for esplora and node server

fix: node server volume

fix: explora volume mount

fix: bitcoin cli commands for esplora

fix: host for node server

debug: esplora and node server requests

debug: host for esplora

debug: containers

fix: node server exit

debug: node server logs

fix: node server restart

debug: esplora logs

fix: restart policy for esplora

debug: node server start command

fix: add npm install before node start

fix: install and start cmd for node server

* feat: add dockerfile for node server

fix: dir with node server build

fix: dockerfile for node server

fix: setup script for web client tests

fix: step for script execution for web client

fix: add npm install in script for web client

debug: post request for node server

fix: post request for node server

* feat: add wallet creation for esplora

fix: order for running script for web client

fix: add step to generate block on esplora

fix: host for esplora

debug: get request for esplora

fix: permission error

fix: permission issue for data_bitcoin_regtest folder

fix: web client tests order

* feat: add test for atomic swap for web client

* feat: add test for coin steal in atomic swap for web client

* feat: add test for lightning latch

* feat: add test for invoice for lightning latch

* Fix/dockerfile token server (#85)

* fix: token server dockerfile

* fix: build release for token server

* fix: upgrade sqlx version

* Add payment hash verification to web client

* Add log crate to the server

* fix: The pre-image is now only revealed if the transfer is unlocked.

* fix: import error

* feat: add endpoints for invoice ops on node server

fix: invoice generation from node server

* feat: add test for invoice handling for lightning latch

fix: import error

fix: verifyInvoice fn

fix: add bolt11 as package

fix: bolt11 import error

* feat: add endpoint for decode invoice

fix: invoice from post request

fix: invoice payment hash

debug: invoice decode

fix: payment hash in invoice generation

debug: invoice verification

fix: extract hash from decoded invoice

fix: long running test due to hold invoice

fix: payment hashes

fix: web client tests running order

fix: verify invoice test

* refactor: verify invoice test

---------

Co-authored-by: S. Santos <[email protected]>

* Update Cargo.toml

* fix: upgrade sqlx version

* Update sqlx and toolchain

* Change transaction sequence to 0

* Receiver now compares the backup transaction locktime with the current block height

* Validate backup transaction signatures using SIGHASH_ALL

* Validate transaction version

* Validate transaction output size

* Add blockheight in web library receive functionality

* Receiver constructs backup transactions for verification

* Add tx and locktime checks

* Version number

* Update Cargo.toml

---------

Co-authored-by: S. Santos <[email protected]>
Co-authored-by: Thomas Trevethan <[email protected]>
Co-authored-by: rk16449 <[email protected]>
Co-authored-by: rk16449 <[email protected]>
Co-authored-by: Nicholas Gregory <[email protected]>
Co-authored-by: DhananjayPurohit <[email protected]>
Co-authored-by: S. Santos <[email protected]>
  • Loading branch information
8 people authored Sep 5, 2024
1 parent 73c9bd4 commit 4bff319
Show file tree
Hide file tree
Showing 31 changed files with 679 additions and 140 deletions.
4 changes: 2 additions & 2 deletions clients/apps/rust/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ enum Commands {
BroadcastBackupTransaction {
wallet_name: String,
statechain_id: String,
to_address: String,
to_address: Option<String>,
/// Transaction fee rate in sats per byte
fee_rate: Option<f64>
},
Expand Down Expand Up @@ -115,7 +115,7 @@ async fn main() -> Result<()> {
},
Commands::BroadcastBackupTransaction { wallet_name, statechain_id, to_address, fee_rate } => {
mercuryrustlib::coin_status::update_coins(&client_config, &wallet_name).await?;
mercuryrustlib::broadcast_backup_tx::execute(&client_config, &wallet_name, &statechain_id, &to_address, fee_rate).await?;
mercuryrustlib::broadcast_backup_tx::execute(&client_config, &wallet_name, &statechain_id, to_address, fee_rate).await?;
},
Commands::ListStatecoins { wallet_name } => {
mercuryrustlib::coin_status::update_coins(&client_config, &wallet_name).await?;
Expand Down
67 changes: 39 additions & 28 deletions clients/libs/rust/src/broadcast_backup_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ use anyhow::{anyhow, Result};
use electrum_client::ElectrumApi;
use mercurylib::wallet::{cpfp_tx, CoinStatus};

pub async fn execute(client_config: &ClientConfig, wallet_name: &str, statechain_id: &str, to_address: &str, fee_rate: Option<f64>) -> Result<()> {
pub async fn execute(client_config: &ClientConfig, wallet_name: &str, statechain_id: &str, to_address: Option<String>, fee_rate: Option<f64>) -> Result<()> {

let mut wallet: mercurylib::wallet::Wallet = get_wallet(&client_config.pool, &wallet_name).await?;

let is_address_valid = mercurylib::validate_address(to_address, &wallet.network)?;
if to_address.is_some() {
let to_address = to_address.clone().unwrap();
let is_address_valid = mercurylib::validate_address(&to_address, &wallet.network)?;

if !is_address_valid {
return Err(anyhow!("Invalid address"));
if !is_address_valid {
return Err(anyhow!("Invalid address"));
}
}

let backup_txs = get_backup_txs(&client_config.pool, &statechain_id).await?;
Expand All @@ -34,38 +37,46 @@ pub async fn execute(client_config: &ClientConfig, wallet_name: &str, statechain

let backup_tx = cpfp_tx::latest_backup_tx_pays_to_user_pubkey(&backup_txs, &coin, &wallet.network)?;

let fee_rate = match fee_rate {
Some(fee_rate) => fee_rate,
None => {
let mut fee_rate_btc_per_kb = client_config.electrum_client.estimate_fee(1)?;
let cpfp_tx = if to_address.is_some() {

// Why does it happen?
if fee_rate_btc_per_kb <= 0.0 {
fee_rate_btc_per_kb = 0.00001;
}
let to_address = to_address.clone().unwrap();

let fee_rate_sats_per_byte = fee_rate_btc_per_kb * 100000.0;
let fee_rate = match fee_rate {
Some(fee_rate) => fee_rate,
None => {
let mut fee_rate_btc_per_kb = client_config.electrum_client.estimate_fee(1)?;

if fee_rate_sats_per_byte > client_config.max_fee_rate {
client_config.max_fee_rate
} else {
fee_rate_sats_per_byte
}
},
};
// Why does it happen?
if fee_rate_btc_per_kb <= 0.0 {
fee_rate_btc_per_kb = 0.00001;
}

let cpfp_tx = cpfp_tx::create_cpfp_tx(&backup_tx, &coin, to_address, fee_rate, &wallet.network)?;
let fee_rate_sats_per_byte = fee_rate_btc_per_kb * 100000.0;

let tx_bytes = hex::decode(&backup_tx.tx)?;
let txid = client_config.electrum_client.transaction_broadcast_raw(&tx_bytes)?;
println!("Broadcasting backup transaction: {}", txid);
if fee_rate_sats_per_byte > client_config.max_fee_rate {
client_config.max_fee_rate
} else {
fee_rate_sats_per_byte
}
},
};

let tx_bytes = hex::decode(&cpfp_tx)?;
let txid = client_config.electrum_client.transaction_broadcast_raw(&tx_bytes)?;
println!("Broadcasting CPFP transaction: {}", txid);
Some(cpfp_tx::create_cpfp_tx(&backup_tx, &coin, &to_address, fee_rate, &wallet.network)?)
} else {
None
};

let tx_bytes = hex::decode(&backup_tx.tx)?;
let mut txid = client_config.electrum_client.transaction_broadcast_raw(&tx_bytes)?;

if cpfp_tx.is_some() {
let cpfp_tx = cpfp_tx.unwrap();
let tx_bytes = hex::decode(&cpfp_tx)?;
txid = client_config.electrum_client.transaction_broadcast_raw(&tx_bytes)?;
}

coin.tx_cpfp = Some(txid.to_string());
coin.withdrawal_address = Some(to_address.to_string());
coin.withdrawal_address = if to_address.is_some() { Some(to_address.unwrap()) } else { Some(coin.backup_address.clone()) };
coin.status = CoinStatus::WITHDRAWING;

let signed_statechain_id = coin.signed_statechain_id.as_ref().unwrap().to_string();
Expand Down
11 changes: 8 additions & 3 deletions clients/libs/rust/src/transfer_receiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ pub async fn execute(client_config: &ClientConfig, wallet_name: &str) -> Result<
let mut temp_coins = wallet.coins.clone();
let mut temp_activities = wallet.activities.clone();

let block_header = client_config.electrum_client.block_headers_subscribe_raw()?;
let blockheight = block_header.height as u32;

for (key, values) in &enc_msgs_per_auth_pubkey {

let auth_pubkey = key.clone();
Expand All @@ -71,7 +74,7 @@ pub async fn execute(client_config: &ClientConfig, wallet_name: &str) -> Result<

let mut coin = coin.unwrap();

let message_result = process_encrypted_message(client_config, &mut coin, enc_message, &wallet.network, &info_config, &mut temp_activities).await;
let message_result = process_encrypted_message(client_config, &mut coin, enc_message, &wallet.network, &info_config, blockheight, &mut temp_activities).await;

if message_result.is_err() {
println!("Error: {}", message_result.err().unwrap().to_string());
Expand Down Expand Up @@ -99,7 +102,7 @@ pub async fn execute(client_config: &ClientConfig, wallet_name: &str) -> Result<

let mut new_coin = new_coin.unwrap();

let message_result = process_encrypted_message(client_config, &mut new_coin, enc_message, &wallet.network, &info_config, &mut temp_activities).await;
let message_result = process_encrypted_message(client_config, &mut new_coin, enc_message, &wallet.network, &info_config, blockheight, &mut temp_activities).await;

if message_result.is_err() {
println!("Error: {}", message_result.err().unwrap().to_string());
Expand Down Expand Up @@ -151,7 +154,7 @@ pub struct MessageResult {
pub statechain_id: Option<String>,
}

async fn process_encrypted_message(client_config: &ClientConfig, coin: &mut Coin, enc_message: &str, network: &str, info_config: &InfoConfig, activities: &mut Vec<Activity>) -> Result<MessageResult> {
async fn process_encrypted_message(client_config: &ClientConfig, coin: &mut Coin, enc_message: &str, network: &str, info_config: &InfoConfig, blockheight: u32, activities: &mut Vec<Activity>) -> Result<MessageResult> {

let client_auth_key = coin.auth_privkey.clone();
let new_user_pubkey = coin.user_pubkey.clone();
Expand Down Expand Up @@ -208,8 +211,10 @@ async fn process_encrypted_message(client_config: &ClientConfig, coin: &mut Coin
&transfer_msg,
&statechain_info,
&tx0_hex,
blockheight,
client_config.fee_rate_tolerance,
current_fee_rate_sats_per_byte,
info_config.initlock,
info_config.interval);

if previous_lock_time.is_err() {
Expand Down
11 changes: 8 additions & 3 deletions clients/libs/web/transfer_receive.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ const sendTransferReceiverRequestPayload = async (clientConfig, transferReceiver

}

const processEncryptedMessage = async (clientConfig, coin, encMessage, network, serverInfo, activities) => {
const processEncryptedMessage = async (clientConfig, coin, encMessage, network, serverInfo, blockheight, activities) => {
let clientAuthKey = coin.auth_privkey;
let newUserPubkey = coin.user_pubkey;

Expand Down Expand Up @@ -182,8 +182,10 @@ const processEncryptedMessage = async (clientConfig, coin, encMessage, network,
transferMsg,
statechainInfo,
tx0Hex,
blockheight,
feeRateTolerance,
currentFeeRateSatsPerByte,
serverInfo.initlock,
serverInfo.interval
)

Expand Down Expand Up @@ -283,6 +285,9 @@ const execute = async (clientConfig, walletName) => {
let tempCoins = [...wallet.coins];
let tempActivities = [...wallet.activities];

const response = await axios.get(`${clientConfig.esploraServer}/api/blocks/tip/height`);
const blockheight = response.data;

for (let [authPubkey, encMessages] of encMsgsPerAuthPubkey.entries()) {

for (let encMessage of encMessages) {
Expand All @@ -291,7 +296,7 @@ const execute = async (clientConfig, walletName) => {

if (coin) {
try {
let messageResult = await processEncryptedMessage(clientConfig, coin, encMessage, wallet.network, serverInfo, tempActivities);
let messageResult = await processEncryptedMessage(clientConfig, coin, encMessage, wallet.network, serverInfo, blockheight, tempActivities);

if (messageResult.isBatchLocked) {
isThereBatchLocked = true;
Expand All @@ -310,7 +315,7 @@ const execute = async (clientConfig, walletName) => {
let newCoin = await mercury_wasm.duplicateCoinToInitializedState(wallet, authPubkey);

if (newCoin) {
let messageResult = await processEncryptedMessage(clientConfig, newCoin, encMessage, wallet.network, serverInfo, tempActivities);
let messageResult = await processEncryptedMessage(clientConfig, newCoin, encMessage, wallet.network, serverInfo, blockheight, tempActivities);

if (messageResult.isBatchLocked) {
isThereBatchLocked = true;
Expand Down
5 changes: 5 additions & 0 deletions clients/tests/rust/src/electrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,9 @@ pub async fn check_address(client_config: &ClientConfig, address: &str, amount:
}

Ok(true)
}

pub async fn get_blockheight(client_config: &ClientConfig) -> Result<usize> {
let blockheight = client_config.electrum_client.block_headers_subscribe()?.height;
Ok(blockheight)
}
2 changes: 2 additions & 0 deletions clients/tests/rust/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod tb02_transfer_address_reuse;
pub mod tb03_simple_atomic_transfer;
pub mod tb04_simple_lightning_latch;
pub mod tm01_sender_double_spends;
mod tv05;
use anyhow::{Result, Ok};

#[tokio::main(flavor = "current_thread")]
Expand All @@ -20,6 +21,7 @@ async fn main() -> Result<()> {
tm01_sender_double_spends::execute().await?;
ta01_sign_second_not_called::execute().await?;
ta02_duplicate_deposits::execute().await?;
tv05::execute().await?;

Ok(())
}
103 changes: 103 additions & 0 deletions clients/tests/rust/src/tv05.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use std::{env, process::Command, thread, time::Duration};

use anyhow::{Result, Ok};
use mercuryrustlib::{client_config::ClientConfig, CoinStatus, Wallet};

use crate::{bitcoin_core, electrs};

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

let amount = 1000;

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();

assert!(new_coin.status == CoinStatus::CONFIRMED);

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

let batch_id = None;
let force_send = false;

let result = mercuryrustlib::transfer_sender::execute(&client_config, &wallet2_transfer_adress, &wallet1.name, &statechain_id, force_send, batch_id).await;
assert!(result.is_ok());

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

assert!(received_statechain_ids.contains(&statechain_id.to_string()));
assert!(received_statechain_ids.len() == 1);

mercuryrustlib::coin_status::update_coins(&client_config, &wallet2.name).await?;
let local_wallet_2: mercuryrustlib::Wallet = mercuryrustlib::sqlite_manager::get_wallet(&client_config.pool, &wallet2.name).await?;
let new_w2_coin = local_wallet_2.coins.iter().find(|&coin| coin.statechain_id == Some(statechain_id.clone())).unwrap();

assert!(new_coin.status == CoinStatus::CONFIRMED);
assert!(new_w2_coin.status == CoinStatus::CONFIRMED);

let fee_rate = None;

let core_wallet_address = Some(core_wallet_address);

let result = mercuryrustlib::broadcast_backup_tx::execute(&client_config, &wallet1.name, &statechain_id, core_wallet_address.clone(), fee_rate).await;

assert!(result.is_err());

let err = result.err().unwrap();

assert!(err.to_string() == "Electrum server error: {\"code\":2,\"message\":\"non-final\"}");

let _ = bitcoin_core::generatetoaddress(990, &core_wallet_address.clone().unwrap())?;

let result = mercuryrustlib::broadcast_backup_tx::execute(&client_config, &wallet2.name, &statechain_id, core_wallet_address, fee_rate).await;

assert!(result.is_ok());

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?;

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

println!("TV05 - Result as reported.");

Ok(())
}
Loading

0 comments on commit 4bff319

Please sign in to comment.