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

verifier_down_for_withdrawal_signature test. #200

Closed
wants to merge 2 commits into from
Closed
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
2 changes: 1 addition & 1 deletion core/src/database/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ impl Database {
idx: usize,
) -> Result<(Txid, secp256k1::schnorr::Signature), BridgeError> {
let qr: (String, String) =
sqlx::query_as("SELECT (bridge_fund_txid, sig) FROM withdrawal_sigs WHERE idx = $1;")
sqlx::query_as("SELECT bridge_fund_txid, sig FROM withdrawal_sigs WHERE idx = $1;")
.bind(idx as i64)
.fetch_one(&self.connection)
.await?;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
tracing_debug = "debug,bitcoincore_rpc=info,hyper=error"
host = "127.0.0.1"
port = 3000
secret_key = "5555555555555555555555555555555555555555555555555555555555555555"
verifiers_public_keys = [
"4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa",
"466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27",
"3c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1",
"2c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991",
"9ac20335eb38768d2052be1dbbc3c8f6178407458e51e6b4ad22f1d91758895b",
]
num_verifiers = 4
min_relay_fee = 305
user_takes_after = 5
confirmation_treshold = 1
network = "regtest"
bitcoin_rpc_url = "http://127.0.0.1:18443"
bitcoin_rpc_user = "admin"
bitcoin_rpc_password = "admin"
all_secret_keys = [
"1111111111111111111111111111111111111111111111111111111111111111",
"2222222222222222222222222222222222222222222222222222222222222222",
"3333333333333333333333333333333333333333333333333333333333333333",
"4444444444444444444444444444444444444444444444444444444444444444",
"5555555555555555555555555555555555555555555555555555555555555555",
]
db_host = "127.0.0.1"
db_port = 5432
db_user = "citrea"
db_password = ""
db_name = "clementine"
115 changes: 115 additions & 0 deletions core/tests/flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use clementine_core::servers::*;
use clementine_core::traits::rpc::OperatorRpcClient;
use clementine_core::transaction_builder::{CreateTxOutputs, TransactionBuilder};
use clementine_core::utils::handle_taproot_witness_new;
use clementine_core::utils::SECP;
use clementine_core::EVMAddress;
use clementine_core::{
create_extended_rpc, create_test_config, create_test_config_with_thread_name,
Expand Down Expand Up @@ -220,3 +221,117 @@ async fn test_flow_2() {
.unwrap();
tracing::debug!("User takes back tx: {:#?}", user_takes_back_tx);
}

#[tokio::test]
async fn verifier_down_for_withdrawal_signature() {
let mut config = create_test_config_with_thread_name!(
"test_config_verifier_down_for_withdrawal_signature.toml"
);
let rpc = create_extended_rpc!(config);
let handle = thread::current()
.name()
.unwrap()
.split(':')
.last()
.unwrap()
.to_owned();
for i in 0..4 {
create_test_config!(
handle.clone() + i.to_string().as_str(),
"test_config_verifier_down_for_withdrawal_signature.toml"
);
}

let (xonly_pk, _) = config.secret_key.public_key(&SECP).x_only_public_key();
let taproot_address = Address::p2tr(&SECP, xonly_pk, None, config.network);

let tx_builder = TransactionBuilder::new(config.verifiers_public_keys.clone(), config.network);

let (operator_client, _operator_handler, results) =
create_operator_and_verifiers(config.clone(), rpc.clone()).await;

let evm_addresses = [
EVMAddress([1u8; 20]),
EVMAddress([2u8; 20]),
EVMAddress([3u8; 20]),
EVMAddress([4u8; 20]),
];
let deposit_addresses = evm_addresses
.iter()
.map(|evm_address| {
tx_builder
.generate_deposit_address(
taproot_address.as_unchecked(),
evm_address,
BRIDGE_AMOUNT_SATS,
config.user_takes_after,
)
.unwrap()
.0
})
.collect::<Vec<_>>();
println!("Deposit addresses: {:#?}", deposit_addresses);

for (idx, deposit_address) in deposit_addresses.iter().enumerate() {
let deposit_utxo = rpc
.send_to_address(deposit_address, BRIDGE_AMOUNT_SATS)
.unwrap();
println!("Deposit UTXO #{}: {:#?}", idx, deposit_utxo);

rpc.mine_blocks(18).unwrap();

let output = operator_client
.new_deposit_rpc(
deposit_utxo,
taproot_address.as_unchecked().clone(),
evm_addresses[idx],
)
.await
.unwrap();
println!("Output #{}: {:#?}", idx, output);
}

// Assume one of the verifier is down.
const VERIFIER_IDX: usize = 3;
results.get(VERIFIER_IDX).unwrap().1.stop().unwrap();

let withdrawal_address = Address::p2tr(&SECP, xonly_pk, None, config.network);

if let Ok(_withdraw_txid) = operator_client
.new_withdrawal_direct_rpc(0, withdrawal_address.as_unchecked().clone())
.await
{
println!(
"Verifier {} is down, this should not be possible.",
VERIFIER_IDX
);
assert!(false);
};

// Restart all servers.
results.iter().for_each(|server| {
let _ = server.1.stop();
});
let (operator_client, _operator_handler, _results) =
create_operator_and_verifiers(config.clone(), rpc.clone()).await;

let withdraw_txid = operator_client
.new_withdrawal_direct_rpc(0, withdrawal_address.as_unchecked().clone())
.await
.unwrap();
println!("Withdrawal send to address: {:?}", withdrawal_address);
println!("Withdrawal TXID: {:#?}", withdraw_txid);

// check whether it has an output with the withdrawal address
let tx = rpc.get_raw_transaction(&withdraw_txid, None).unwrap();
let rpc_withdraw_script = tx.output[0].script_pubkey.clone();
let rpc_withdraw_amount = tx.output[0].value;
let expected_withdraw_script = withdrawal_address.script_pubkey();
assert_eq!(rpc_withdraw_script, expected_withdraw_script);

// check if the amounts match
let anyone_can_spend_amount = script_builder::anyone_can_spend_txout().value;
let expected_withdraw_amount = Amount::from_sat(BRIDGE_AMOUNT_SATS - 2 * config.min_relay_fee)
- anyone_can_spend_amount * 2;
assert_eq!(expected_withdraw_amount, rpc_withdraw_amount);
}
Loading