diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 26666a12..9fbdf795 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -123,6 +123,7 @@ jobs: bridge_amount_sats = 100000000 user_takes_after = 5 operator_takes_after = 5 + operator_num_kickoff_utxos_per_tx = 10 db_file_path = "database" confirmation_threshold = 1 network = "regtest" @@ -231,6 +232,7 @@ jobs: bridge_amount_sats = 100000000 user_takes_after = 5 operator_takes_after = 5 + operator_num_kickoff_utxos_per_tx = 10 db_file_path = "database" confirmation_threshold = 1 network = "regtest" diff --git a/core/src/aggregator.rs b/core/src/aggregator.rs index 5a27eb7a..cd3bba85 100644 --- a/core/src/aggregator.rs +++ b/core/src/aggregator.rs @@ -14,7 +14,6 @@ use crate::{ use async_trait::async_trait; use bitcoin::hashes::Hash; use bitcoin::{address::NetworkUnchecked, Address, OutPoint, Transaction}; -use bitcoincore_rpc::RawTx; use secp256k1::schnorr; /// Aggregator struct. @@ -65,12 +64,12 @@ impl Aggregator { self.config.operator_takes_after, self.config.bridge_amount_sats, ); - tracing::debug!("SLASH_OR_TAKE_TX: {:?}", tx); + // tracing::debug!("SLASH_OR_TAKE_TX: {:?}", tx); tracing::debug!("SLASH_OR_TAKE_TX weight: {:?}", tx.tx.weight()); let message: [u8; 32] = Actor::convert_tx_to_sighash_script_spend(&mut tx, 0, 0) .unwrap() .to_byte_array(); - tracing::debug!("aggregate SLASH_OR_TAKE_TX message: {:?}", message); + // tracing::debug!("aggregate SLASH_OR_TAKE_TX message: {:?}", message); let final_sig: [u8; 64] = aggregate_partial_signatures( self.config.verifiers_public_keys.clone(), None, @@ -79,15 +78,15 @@ impl Aggregator { partial_sigs, message, )?; - tracing::debug!("aggregate SLASH_OR_TAKE_TX final_sig: {:?}", final_sig); - tracing::debug!( - "aggregate SLASH_OR_TAKE_TX for verifiers: {:?}", - self.config.verifiers_public_keys.clone() - ); - tracing::debug!( - "aggregate SLASH_OR_TAKE_TX for operator: {:?}", - operator_xonly_pk - ); + // tracing::debug!("aggregate SLASH_OR_TAKE_TX final_sig: {:?}", final_sig); + // tracing::debug!( + // "aggregate SLASH_OR_TAKE_TX for verifiers: {:?}", + // self.config.verifiers_public_keys.clone() + // ); + // tracing::debug!( + // "aggregate SLASH_OR_TAKE_TX for operator: {:?}", + // operator_xonly_pk + // ); Ok(final_sig) } @@ -137,6 +136,11 @@ impl Aggregator { }, txout: slash_or_take_tx_handler.tx.output[0].clone(), }; + // tracing::debug!( + // "SERDE_UTXO: {:#?}", + // serde_json::to_string(&slash_or_take_utxo).unwrap() + // ); + let mut tx_handler = TransactionBuilder::create_operator_takes_tx( bridge_fund_outpoint, slash_or_take_utxo, @@ -146,12 +150,12 @@ impl Aggregator { self.config.operator_takes_after, self.config.bridge_amount_sats, ); - tracing::debug!( - "OPERATOR_TAKES_TX with operator_idx:{:?} {:?}", - operator_idx, - tx_handler.tx - ); - tracing::debug!("OPERATOR_TAKES_TX_HEX: {:?}", tx_handler.tx.raw_hex()); + // tracing::debug!( + // "OPERATOR_TAKES_TX with operator_idx:{:?} {:?}", + // operator_idx, + // tx_handler.tx + // ); + // tracing::debug!("OPERATOR_TAKES_TX_HEX: {:?}", tx_handler.tx.raw_hex()); tracing::debug!("OPERATOR_TAKES_TX weight: {:?}", tx_handler.tx.weight()); let message: [u8; 32] = Actor::convert_tx_to_sighash_pubkey_spend(&mut tx_handler, 0) .unwrap() @@ -164,7 +168,7 @@ impl Aggregator { partial_sigs, message, )?; - tracing::debug!("OPERATOR_TAKES_TX final_sig: {:?}", final_sig); + // tracing::debug!("OPERATOR_TAKES_TX final_sig: {:?}", final_sig); Ok(final_sig) } diff --git a/core/src/config.rs b/core/src/config.rs index 059daf28..663c4a9e 100644 --- a/core/src/config.rs +++ b/core/src/config.rs @@ -46,6 +46,8 @@ pub struct BridgeConfig { pub operator_takes_after: u32, /// Bridge amount in satoshis. pub bridge_amount_sats: u64, + /// Operator: number of kickoff UTXOs per funding transaction. + pub operator_num_kickoff_utxos_per_tx: usize, /// Threshold for confirmation. pub confirmation_threshold: u32, /// Bitcoin remote procedure call URL. @@ -142,6 +144,7 @@ impl Default for BridgeConfig { user_takes_after: 5, operator_takes_after: 5, bridge_amount_sats: 100_000_000, + operator_num_kickoff_utxos_per_tx: 10, confirmation_threshold: 1, network: Network::Regtest, bitcoin_rpc_url: "http://127.0.0.1:18443".to_string(), diff --git a/core/src/database/common.rs b/core/src/database/common.rs index e479fa7e..510be928 100644 --- a/core/src/database/common.rs +++ b/core/src/database/common.rs @@ -165,6 +165,61 @@ impl Database { } } + /// Operator: Get unused kickoff_utxo at ready if there are any. + pub async fn get_unused_kickoff_utxo_and_increase_idx( + &self, + ) -> Result, BridgeError> { + // Attempt to fetch the latest transaction details + let qr: Option<(TxidDB, i32, i32)> = sqlx::query_as( + "SELECT txid, num_kickoffs, cur_unused_kickoff_index FROM deposit_kickoff_generator_txs ORDER BY id DESC LIMIT 1;" + ) + .fetch_optional(&self.connection) + .await?; + + // If the table is empty, return None + let (txid, num_kickoffs, cur_unused_kickoff_index) = match qr { + Some(qr) => qr, + None => return Ok(None), + }; + + // Proceed with the rest of the logic only if there are unused kickoffs + if num_kickoffs <= cur_unused_kickoff_index { + Ok(None) + } else { + // Fetch the raw signed transaction + let db_transaction = self.begin_transaction().await?; + let qr_tx: (String,) = sqlx::query_as( + "SELECT raw_signed_tx FROM deposit_kickoff_generator_txs ORDER BY id DESC LIMIT 1;", + ) + .fetch_one(&self.connection) + .await?; + + // Deserialize the transaction + let tx: bitcoin::Transaction = + bitcoin::consensus::deserialize(&hex::decode(qr_tx.0).unwrap())?; + + // Create the outpoint and txout + let outpoint = OutPoint { + txid: tx.compute_txid(), + vout: cur_unused_kickoff_index as u32, + }; + let txout = tx.output[cur_unused_kickoff_index as usize].clone(); + + // Update the cur_unused_kickoff_index + sqlx::query( + "UPDATE deposit_kickoff_generator_txs SET cur_unused_kickoff_index = $1 WHERE txid = $2;" + ) + .bind(cur_unused_kickoff_index + 1) + .bind(txid) + .execute(&self.connection) + .await?; + db_transaction.commit().await?; + + // Return the UTXO + Ok(Some(UTXO { outpoint, txout })) + } + } + /// Verifier: Get the verified kickoff UTXOs for a deposit UTXO. pub async fn get_kickoff_utxos( &self, @@ -515,19 +570,21 @@ impl Database { } } + /// Operator: Save the signed kickoff UTXO generator tx. + /// Txid is the txid of the signed tx. + /// funding_txid is the txid of the input[0]. pub async fn add_deposit_kickoff_generator_tx( &self, txid: Txid, raw_hex: String, num_kickoffs: usize, - cur_unused_kickoff_index: usize, funding_txid: Txid, ) -> Result<(), BridgeError> { sqlx::query("INSERT INTO deposit_kickoff_generator_txs (txid, raw_signed_tx, num_kickoffs, cur_unused_kickoff_index, funding_txid) VALUES ($1, $2, $3, $4, $5);") .bind(TxidDB(txid)) .bind(raw_hex) .bind(num_kickoffs as i32) - .bind(cur_unused_kickoff_index as i32) + .bind(1) .bind(TxidDB(funding_txid)) .execute(&self.connection) .await?; @@ -977,20 +1034,15 @@ mod tests { let config = create_test_config_with_thread_name!("test_config.toml"); let db = Database::new(config).await.unwrap(); - let txid = Txid::from_byte_array([1u8; 32]); - let raw_hex = "raw_hex".to_string(); - let num_kickoffs = 10; - let cur_unused_kickoff_index = 5; - let funding_txid = Txid::from_byte_array([2u8; 32]); - db.add_deposit_kickoff_generator_tx( - txid, - raw_hex.clone(), - num_kickoffs, - cur_unused_kickoff_index, - funding_txid, - ) - .await - .unwrap(); + let raw_hex = "01000000000101308d840c736eefd114a8fad04cb0d8338b4a3034a2b517250e5498701b25eb360100000000fdffffff02401f00000000000022512024985a1ab5724a5164ae5e0026b3e7e22031e83948eedf99d438b866857946b81f7e000000000000225120f7298da2a2be5b6e02a076ff7d35a1fe6b54a2bc7938c1c86bede23cadb7d9650140ad2fdb01ec5e2772f682867c8c6f30697c63f622e338f7390d3abc6c905b9fd7e96496fdc34cb9e872387758a6a334ec1307b3505b73121e0264fe2ba546d78ad11b0d00".to_string(); + let tx: bitcoin::Transaction = + bitcoin::consensus::deserialize(&hex::decode(raw_hex.clone()).unwrap()).unwrap(); + let txid = tx.compute_txid(); + let num_kickoffs = 2; + let funding_txid = tx.input[0].previous_output.txid; + db.add_deposit_kickoff_generator_tx(txid, raw_hex.clone(), num_kickoffs, funding_txid) + .await + .unwrap(); let (db_raw_hex, db_num_kickoffs, db_cur_unused_kickoff_index, db_funding_txid) = db .get_deposit_kickoff_generator_tx(txid) .await @@ -1000,8 +1052,22 @@ mod tests { // Sanity check assert_eq!(db_raw_hex, raw_hex); assert_eq!(db_num_kickoffs, num_kickoffs); - assert_eq!(db_cur_unused_kickoff_index, cur_unused_kickoff_index); + assert_eq!(db_cur_unused_kickoff_index, 1); assert_eq!(db_funding_txid, funding_txid); + + let unused_utxo = db + .get_unused_kickoff_utxo_and_increase_idx() + .await + .unwrap() + .unwrap(); + tracing::info!("unused_utxo: {:?}", unused_utxo); + + // Sanity check + assert_eq!(unused_utxo.outpoint.txid, txid); + assert_eq!(unused_utxo.outpoint.vout, 1); + + let none_utxo = db.get_unused_kickoff_utxo_and_increase_idx().await.unwrap(); + assert!(none_utxo.is_none()); } #[tokio::test] diff --git a/core/src/database/wrapper.rs b/core/src/database/wrapper.rs index 326514df..3273635e 100644 --- a/core/src/database/wrapper.rs +++ b/core/src/database/wrapper.rs @@ -21,7 +21,7 @@ pub struct AddressDB(pub Address); #[derive(Serialize, Deserialize)] pub struct EVMAddressDB(pub EVMAddress); -#[derive(Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct TxidDB(pub Txid); #[derive(Serialize, Deserialize, sqlx::FromRow)] diff --git a/core/src/musig2.rs b/core/src/musig2.rs index db923fb7..80f7d6eb 100644 --- a/core/src/musig2.rs +++ b/core/src/musig2.rs @@ -56,19 +56,19 @@ pub fn create_key_agg_ctx( .map(|pk| musig2::secp256k1::PublicKey::from_slice(&pk.serialize()).unwrap()) .collect::>(); let key_agg_ctx_raw = KeyAggContext::new(musig_pks)?; - tracing::debug!( - "UNTWEAKED AGGREGATED PUBKEY: {:?}", - key_agg_ctx_raw.aggregated_pubkey::() - ); + // tracing::debug!( + // "UNTWEAKED AGGREGATED PUBKEY: {:?}", + // key_agg_ctx_raw.aggregated_pubkey::() + // ); if tweak_flag { let key_agg_ctx = match tweak { Some(scalar) => key_agg_ctx_raw.with_taproot_tweak(&scalar.to_byte_array())?, None => key_agg_ctx_raw.with_unspendable_taproot_tweak()?, }; - tracing::debug!( - "TWEAKED AGGREGATED PUBKEY: {:?}", - key_agg_ctx.aggregated_pubkey::() - ); + // tracing::debug!( + // "TWEAKED AGGREGATED PUBKEY: {:?}", + // key_agg_ctx.aggregated_pubkey::() + // ); Ok(key_agg_ctx) } else { if tweak.is_some() { diff --git a/core/src/operator.rs b/core/src/operator.rs index a24d2184..99686752 100644 --- a/core/src/operator.rs +++ b/core/src/operator.rs @@ -5,7 +5,7 @@ use crate::errors::BridgeError; use crate::extended_rpc::ExtendedRpc; use crate::musig2::AggregateFromPublicKeys; use crate::traits::rpc::OperatorRpcServer; -use crate::transaction_builder::TransactionBuilder; +use crate::transaction_builder::{TransactionBuilder, KICKOFF_UTXO_AMOUNT_SATS}; use crate::utils::handle_taproot_witness_new; use crate::{script_builder, utils, EVMAddress, UTXO}; use bitcoin::address::NetworkUnchecked; @@ -126,95 +126,122 @@ where return Ok((kickoff_utxo, sig)); } - // TODO: Later we can check if we have unused kickkoff UTXOs and use them instead of creating a new one - // 3. Create a kickoff transaction but do not broadcast it - // To create a kickoff tx, we first need a funding utxo - let funding_utxo = - self.db - .get_funding_utxo() - .await? - .ok_or(BridgeError::OperatorFundingUtxoNotFound( - self.signer.address.clone(), - ))?; - - // if the amount is not enough, return an error - if funding_utxo.txout.value.to_sat() < 150_000 { - // TODO: Change this amount - return Err(BridgeError::OperatorFundingUtxoAmountNotEnough( - self.signer.address.clone(), - )); - } - - let mut kickoff_tx_handler = TransactionBuilder::create_kickoff_utxo_tx( - &funding_utxo, - &self.nofn_xonly_pk, - &self.signer.xonly_public_key, - self.config.network, - ); - let sig = self - .signer - .sign_taproot_pubkey_spend(&mut kickoff_tx_handler, 0, None)?; - handle_taproot_witness_new(&mut kickoff_tx_handler, &[sig.as_ref()], 0, None)?; + // Check if we already have an unused kickoff UTXO available + let unused_kickoff_utxo = self.db.get_unused_kickoff_utxo_and_increase_idx().await?; + if let Some(unused_kickoff_utxo) = unused_kickoff_utxo { + let kickoff_sig_hash = crate::sha256_hash!( + deposit_outpoint.txid, + deposit_outpoint.vout.to_be_bytes(), + unused_kickoff_utxo.outpoint.txid, + unused_kickoff_utxo.outpoint.vout.to_be_bytes() + ); - // tracing::debug!( - // "For operator index: {:?} Kickoff tx handler: {:#?}", - // self.idx, - // kickoff_tx_handler - // ); + let sig = self + .signer + .sign(TapSighash::from_byte_array(kickoff_sig_hash)); - let change_utxo = UTXO { - outpoint: OutPoint { - txid: kickoff_tx_handler.tx.compute_txid(), - vout: 1, // TODO: This will equal to the number of kickoff_outputs in the kickoff tx - }, - txout: kickoff_tx_handler.tx.output[1].clone(), - }; + Ok((unused_kickoff_utxo, sig)) + } else { + // 3. Create a kickoff transaction but do not broadcast it + + // To create a kickoff tx, we first need a funding utxo + let funding_utxo = self.db.get_funding_utxo().await?.ok_or( + BridgeError::OperatorFundingUtxoNotFound(self.signer.address.clone()), + )?; + + // if the amount is not enough, return an error + // The amount will be calculated as if the transaction has 1 input + // and (num_kickoff_utxos + 2) outputs where the first k outputs are + // the kickoff outputs, the penultimante output is the change output, + // and the last output is the anyonecanpay output for fee bumping. + if funding_utxo.txout.value.to_sat() + < (KICKOFF_UTXO_AMOUNT_SATS * self.config.operator_num_kickoff_utxos_per_tx as u64 + + 2000) + { + // TODO: Change this amount + return Err(BridgeError::OperatorFundingUtxoAmountNotEnough( + self.signer.address.clone(), + )); + } - let kickoff_utxo = UTXO { - outpoint: OutPoint { - txid: kickoff_tx_handler.tx.compute_txid(), - vout: 0, - }, - txout: kickoff_tx_handler.tx.output[0].clone(), - }; + let mut kickoff_tx_handler = TransactionBuilder::create_kickoff_utxo_tx( + &funding_utxo, + &self.nofn_xonly_pk, + &self.signer.xonly_public_key, + self.config.network, + self.config.operator_num_kickoff_utxos_per_tx, + ); + let sig = self + .signer + .sign_taproot_pubkey_spend(&mut kickoff_tx_handler, 0, None)?; + handle_taproot_witness_new(&mut kickoff_tx_handler, &[sig.as_ref()], 0, None)?; + tracing::debug!( + "Created kickoff tx with weight: {:#?}", + kickoff_tx_handler.tx.weight() + ); + // tracing::debug!( + // "Created kickoff tx: {:#?}", + // kickoff_tx_handler.tx.raw_hex() + // ); + // tracing::debug!( + // "For operator index: {:?} Kickoff tx handler: {:#?}", + // self.idx, + // kickoff_tx_handler + // ); + + let change_utxo = UTXO { + outpoint: OutPoint { + txid: kickoff_tx_handler.tx.compute_txid(), + vout: self.config.operator_num_kickoff_utxos_per_tx as u32, + }, + txout: kickoff_tx_handler.tx.output[1].clone(), + }; + + let kickoff_utxo = UTXO { + outpoint: OutPoint { + txid: kickoff_tx_handler.tx.compute_txid(), + vout: 0, + }, + txout: kickoff_tx_handler.tx.output[0].clone(), + }; - let kickoff_sig_hash = crate::sha256_hash!( - deposit_outpoint.txid, - deposit_outpoint.vout.to_be_bytes(), - kickoff_utxo.outpoint.txid, - kickoff_utxo.outpoint.vout.to_be_bytes() - ); + let kickoff_sig_hash = crate::sha256_hash!( + deposit_outpoint.txid, + deposit_outpoint.vout.to_be_bytes(), + kickoff_utxo.outpoint.txid, + kickoff_utxo.outpoint.vout.to_be_bytes() + ); - let sig = self - .signer - .sign(TapSighash::from_byte_array(kickoff_sig_hash)); + let sig = self + .signer + .sign(TapSighash::from_byte_array(kickoff_sig_hash)); - // In a db tx, save the kickoff_utxo for this deposit_utxo - // and update the db with the new funding_utxo as the change + // In a db tx, save the kickoff_utxo for this deposit_utxo + // and update the db with the new funding_utxo as the change - let transaction = self.db.begin_transaction().await?; + let db_transaction = self.db.begin_transaction().await?; - // We save the funding txid and the kickoff txid to be able to track them later - self.db - .save_kickoff_utxo(deposit_outpoint, kickoff_utxo.clone()) - .await?; + // We save the funding txid and the kickoff txid to be able to track them later + self.db + .save_kickoff_utxo(deposit_outpoint, kickoff_utxo.clone()) + .await?; - self.db - .add_deposit_kickoff_generator_tx( - kickoff_tx_handler.tx.compute_txid(), - kickoff_tx_handler.tx.raw_hex(), - 1, - 1, - funding_utxo.outpoint.txid, - ) - .await?; + self.db + .add_deposit_kickoff_generator_tx( + kickoff_tx_handler.tx.compute_txid(), + kickoff_tx_handler.tx.raw_hex(), + self.config.operator_num_kickoff_utxos_per_tx, + funding_utxo.outpoint.txid, + ) + .await?; - self.db.set_funding_utxo(change_utxo).await?; + self.db.set_funding_utxo(change_utxo).await?; - transaction.commit().await?; + db_transaction.commit().await?; - Ok((kickoff_utxo, sig)) + Ok((kickoff_utxo, sig)) + } } /// Checks if utxo is valid, spendable by operator and not spent diff --git a/core/src/transaction_builder.rs b/core/src/transaction_builder.rs index 5a6efc59..23af958e 100644 --- a/core/src/transaction_builder.rs +++ b/core/src/transaction_builder.rs @@ -34,6 +34,7 @@ pub const MOVE_TX_MIN_RELAY_FEE: u64 = 305; pub const SLASH_OR_TAKE_TX_MIN_RELAY_FEE: u64 = 305; pub const WITHDRAWAL_TX_MIN_RELAY_FEE: u64 = 305; pub const OPERATOR_TAKES_TX_MIN_RELAY_FEE: u64 = 305; +pub const KICKOFF_UTXO_AMOUNT_SATS: u64 = 100_000; impl TransactionBuilder { /// Creates a new `TransactionBuilder`. @@ -201,8 +202,21 @@ impl TransactionBuilder { nofn_xonly_pk: &XOnlyPublicKey, operator_xonly_pk: &XOnlyPublicKey, network: bitcoin::Network, + num_kickoff_utxos_per_tx: usize, ) -> TxHandler { - let kickoff_tx_min_relay_fee = 197; // TODO: Change this with variable kickoff utxos per txs + // Here, we are calculating the minimum relay fee for the kickoff tx based on the number of kickoff utxos per tx. + // The formula is: 154 + 43 * num_kickoff_utxos_per_tx where + // 154 = (Signature as witness, 66 bytes + 2 bytes from flags) / 4 + // + 43 * 2 from change and anyone can spend txouts + // + 41 from the single input (32 + 8 + 1) + // 4 + 4 + 1 + 1 from locktime, version, and VarInt bases of + // the number of inputs and outputs. + let kickoff_tx_min_relay_fee = match num_kickoff_utxos_per_tx { + 0..=250 => 154 + 43 * num_kickoff_utxos_per_tx, // Handles all values from 0 to 250 + _ => 156 + 43 * num_kickoff_utxos_per_tx, // Handles all other values + }; + + // = 154 + 43 * num_kickoff_utxos_per_tx; let tx_ins = TransactionBuilder::create_tx_ins(vec![funding_utxo.outpoint]); let musig2_and_operator_script = script_builder::create_musig2_and_operator_multisig_script( nofn_xonly_pk, @@ -215,21 +229,24 @@ impl TransactionBuilder { ); let operator_address = Address::p2tr(&utils::SECP, *operator_xonly_pk, None, network); let change_amount = funding_utxo.txout.value - - Amount::from_sat(100_000) + - Amount::from_sat(KICKOFF_UTXO_AMOUNT_SATS * num_kickoff_utxos_per_tx as u64) - script_builder::anyone_can_spend_txout().value - - Amount::from_sat(kickoff_tx_min_relay_fee); + - Amount::from_sat(kickoff_tx_min_relay_fee as u64); - let tx_outs = TransactionBuilder::create_tx_outs(vec![ + let mut tx_outs_raw = vec![ ( - Amount::from_sat(100_000), // TODO: Change this to a constant + Amount::from_sat(KICKOFF_UTXO_AMOUNT_SATS), musig2_and_operator_address.script_pubkey(), - ), - (change_amount, operator_address.script_pubkey()), - ( - script_builder::anyone_can_spend_txout().value, - script_builder::anyone_can_spend_txout().script_pubkey, - ), - ]); + ); + num_kickoff_utxos_per_tx + ]; + + tx_outs_raw.push((change_amount, operator_address.script_pubkey())); + tx_outs_raw.push(( + script_builder::anyone_can_spend_txout().value, + script_builder::anyone_can_spend_txout().script_pubkey, + )); + let tx_outs = TransactionBuilder::create_tx_outs(tx_outs_raw); let tx = TransactionBuilder::create_btc_tx(tx_ins, tx_outs); let prevouts = vec![funding_utxo.txout.clone()]; let scripts = vec![vec![]]; @@ -273,12 +290,12 @@ impl TransactionBuilder { let (kickoff_utxo_address, kickoff_utxo_spend_info) = Self::create_kickoff_address(nofn_xonly_pk, operator_xonly_pk, network); - tracing::debug!( - "kickoff_utxo_script_pubkey: {:?}", - kickoff_utxo_address.script_pubkey() - ); - tracing::debug!("kickoff_utxo_spend_info: {:?}", kickoff_utxo_spend_info); - tracing::debug!("kickoff_utxooo: {:?}", kickoff_utxo); + // tracing::debug!( + // "kickoff_utxo_script_pubkey: {:?}", + // kickoff_utxo_address.script_pubkey() + // ); + // tracing::debug!("kickoff_utxo_spend_info: {:?}", kickoff_utxo_spend_info); + // tracing::debug!("kickoff_utxooo: {:?}", kickoff_utxo); let musig2_and_operator_script = script_builder::create_musig2_and_operator_multisig_script( nofn_xonly_pk, operator_xonly_pk, diff --git a/core/src/verifier.rs b/core/src/verifier.rs index 5f20d28b..99fe1337 100644 --- a/core/src/verifier.rs +++ b/core/src/verifier.rs @@ -7,7 +7,7 @@ use crate::musig2::{ self, AggregateFromPublicKeys, MuSigAggNonce, MuSigPartialSignature, MuSigPubNonce, }; use crate::traits::rpc::VerifierRpcServer; -use crate::transaction_builder::{TransactionBuilder, TxHandler}; +use crate::transaction_builder::{TransactionBuilder, TxHandler, KICKOFF_UTXO_AMOUNT_SATS}; use crate::{utils, EVMAddress, UTXO}; use bitcoin::address::NetworkUnchecked; use bitcoin::hashes::Hash; @@ -150,7 +150,7 @@ where for (i, kickoff_utxo) in kickoff_utxos.iter().enumerate() { let value = kickoff_utxo.txout.value; - if value.to_sat() < 100_000 { + if value.to_sat() < KICKOFF_UTXO_AMOUNT_SATS { return Err(BridgeError::InvalidKickoffUtxo); } @@ -329,19 +329,18 @@ where self.config.operator_takes_after, self.config.bridge_amount_sats, ); - // println!("Slash or take tx handler: {:?}", slash_or_take_tx_handler); let slash_or_take_sighash = Actor::convert_tx_to_sighash_script_spend(&mut slash_or_take_tx_handler, 0, 0) .unwrap(); - tracing::debug!( - "Verify SLASH_OR_TAKE_TX message: {:?}", - slash_or_take_sighash - ); - tracing::debug!("Verify SLASH_OR_TAKE_SIG: {:?}", slash_or_take_sigs[index]); - tracing::debug!( - "Verify SLASH_OR_TAKE_TX operator xonly_pk: {:?}", - self.operator_xonly_pks[index] - ); + // tracing::debug!( + // "Verify SLASH_OR_TAKE_TX message: {:?}", + // slash_or_take_sighash + // ); + // tracing::debug!("Verify SLASH_OR_TAKE_SIG: {:?}", slash_or_take_sigs[index]); + // tracing::debug!( + // "Verify SLASH_OR_TAKE_TX operator xonly_pk: {:?}", + // self.operator_xonly_pks[index] + // ); utils::SECP .verify_schnorr( &slash_or_take_sigs[index], diff --git a/core/tests/common.rs b/core/tests/common.rs index a368dbae..c06cabc2 100644 --- a/core/tests/common.rs +++ b/core/tests/common.rs @@ -38,7 +38,7 @@ pub async fn run_single_deposit( let rpc = create_extended_rpc!(config); let (verifiers, operators, aggregator) = - create_verifiers_and_operators("test_config_flow.toml").await; + create_verifiers_and_operators("test_config.toml").await; // println!("Operators: {:#?}", operators); // println!("Verifiers: {:#?}", verifiers); @@ -100,7 +100,7 @@ pub async fn run_single_deposit( txout: operator_funding_txout, }; - tracing::debug!("Operator {:?} funding utxo: {:?}", i, operator_funding_utxo); + // tracing::debug!("Operator {:?} funding utxo: {:?}", i, operator_funding_utxo); client .set_funding_utxo_rpc(operator_funding_utxo) .await @@ -194,7 +194,7 @@ pub async fn run_single_deposit( ) .await .unwrap(); - tracing::debug!("Move tx: {:#?}", move_tx); + // tracing::debug!("Move tx: {:#?}", move_tx); // tracing::debug!("Move tx_hex: {:?}", move_tx_handler.tx.raw_hex()); tracing::debug!("Move tx weight: {:?}", move_tx.weight()); let move_txid = rpc.send_raw_transaction(&move_tx).unwrap(); diff --git a/core/tests/data/test_config.toml b/core/tests/data/test_config.toml index 174baf48..5b148b86 100644 --- a/core/tests/data/test_config.toml +++ b/core/tests/data/test_config.toml @@ -21,6 +21,7 @@ num_operators = 5 bridge_amount_sats = 100000000 user_takes_after = 5 operator_takes_after = 5 +operator_num_kickoff_utxos_per_tx = 10 confirmation_threshold = 1 network = "regtest" bitcoin_rpc_url = "http://127.0.0.1:18443" diff --git a/core/tests/data/test_config_flow.toml b/core/tests/data/test_config_flow.toml deleted file mode 100644 index ad3c037c..00000000 --- a/core/tests/data/test_config_flow.toml +++ /dev/null @@ -1,47 +0,0 @@ -tracing_debug = "debug,bitcoincore_rpc=info,hyper=error" -host = "127.0.0.1" -port = 3000 -secret_key = "5555555555555555555555555555555555555555555555555555555555555555" -verifiers_public_keys = [ - "034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa", - "02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27", - "023c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1", - "032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991", - "029ac20335eb38768d2052be1dbbc3c8f6178407458e51e6b4ad22f1d91758895b", -] -num_verifiers = 5 -operators_xonly_pks = [ - "4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa", - "466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27", - "3c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1", - "2c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991", - "9ac20335eb38768d2052be1dbbc3c8f6178407458e51e6b4ad22f1d91758895b", -] -num_operators = 5 -bridge_amount_sats = 100000000 -user_takes_after = 5 -operator_takes_after = 5 -confirmation_threshold = 1 -network = "regtest" -bitcoin_rpc_url = "http://127.0.0.1:18443" -bitcoin_rpc_user = "admin" -bitcoin_rpc_password = "admin" -all_verifiers_secret_keys = [ - "1111111111111111111111111111111111111111111111111111111111111111", - "2222222222222222222222222222222222222222222222222222222222222222", - "3333333333333333333333333333333333333333333333333333333333333333", - "4444444444444444444444444444444444444444444444444444444444444444", - "5555555555555555555555555555555555555555555555555555555555555555", -] -all_operators_secret_keys = [ - "1111111111111111111111111111111111111111111111111111111111111111", - "2222222222222222222222222222222222222222222222222222222222222222", - "3333333333333333333333333333333333333333333333333333333333333333", - "4444444444444444444444444444444444444444444444444444444444444444", - "5555555555555555555555555555555555555555555555555555555555555555", -] -db_host = "127.0.0.1" -db_port = 5432 -db_user = "citrea" -db_password = "" -db_name = "clementine" diff --git a/core/tests/data/test_config_musig2.toml b/core/tests/data/test_config_musig2.toml deleted file mode 100644 index ad3c037c..00000000 --- a/core/tests/data/test_config_musig2.toml +++ /dev/null @@ -1,47 +0,0 @@ -tracing_debug = "debug,bitcoincore_rpc=info,hyper=error" -host = "127.0.0.1" -port = 3000 -secret_key = "5555555555555555555555555555555555555555555555555555555555555555" -verifiers_public_keys = [ - "034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa", - "02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27", - "023c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1", - "032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991", - "029ac20335eb38768d2052be1dbbc3c8f6178407458e51e6b4ad22f1d91758895b", -] -num_verifiers = 5 -operators_xonly_pks = [ - "4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa", - "466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27", - "3c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1", - "2c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991", - "9ac20335eb38768d2052be1dbbc3c8f6178407458e51e6b4ad22f1d91758895b", -] -num_operators = 5 -bridge_amount_sats = 100000000 -user_takes_after = 5 -operator_takes_after = 5 -confirmation_threshold = 1 -network = "regtest" -bitcoin_rpc_url = "http://127.0.0.1:18443" -bitcoin_rpc_user = "admin" -bitcoin_rpc_password = "admin" -all_verifiers_secret_keys = [ - "1111111111111111111111111111111111111111111111111111111111111111", - "2222222222222222222222222222222222222222222222222222222222222222", - "3333333333333333333333333333333333333333333333333333333333333333", - "4444444444444444444444444444444444444444444444444444444444444444", - "5555555555555555555555555555555555555555555555555555555555555555", -] -all_operators_secret_keys = [ - "1111111111111111111111111111111111111111111111111111111111111111", - "2222222222222222222222222222222222222222222222222222222222222222", - "3333333333333333333333333333333333333333333333333333333333333333", - "4444444444444444444444444444444444444444444444444444444444444444", - "5555555555555555555555555555555555555555555555555555555555555555", -] -db_host = "127.0.0.1" -db_port = 5432 -db_user = "citrea" -db_password = "" -db_name = "clementine" diff --git a/core/tests/data/test_config_taproot.toml b/core/tests/data/test_config_taproot.toml deleted file mode 100644 index 174baf48..00000000 --- a/core/tests/data/test_config_taproot.toml +++ /dev/null @@ -1,47 +0,0 @@ -tracing_debug = "debug,bitcoincore_rpc=info,hyper=error" -host = "127.0.0.1" -port = 3000 -secret_key = "5555555555555555555555555555555555555555555555555555555555555555" -verifiers_public_keys = [ - "034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa", - "02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27", - "023c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1", - "032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991", - "029ac20335eb38768d2052be1dbbc3c8f6178407458e51e6b4ad22f1d91758895b", -] -num_verifiers = 5 -operators_xonly_pks = [ - "4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa", - "466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27", - "3c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1", - "2c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991", - "9ac20335eb38768d2052be1dbbc3c8f6178407458e51e6b4ad22f1d91758895b", -] -num_operators = 5 -bridge_amount_sats = 100000000 -user_takes_after = 5 -operator_takes_after = 5 -confirmation_threshold = 1 -network = "regtest" -bitcoin_rpc_url = "http://127.0.0.1:18443" -bitcoin_rpc_user = "admin" -bitcoin_rpc_password = "admin" -all_verifiers_secret_keys = [ - "1111111111111111111111111111111111111111111111111111111111111111", - "2222222222222222222222222222222222222222222222222222222222222222", - "3333333333333333333333333333333333333333333333333333333333333333", - "4444444444444444444444444444444444444444444444444444444444444444", - "5555555555555555555555555555555555555555555555555555555555555555", -] -all_operators_secret_keys = [ - "1111111111111111111111111111111111111111111111111111111111111111", - "2222222222222222222222222222222222222222222222222222222222222222", - "3333333333333333333333333333333333333333333333333333333333333333", - "4444444444444444444444444444444444444444444444444444444444444444", - "5555555555555555555555555555555555555555555555555555555555555555", -] -db_host = "127.0.0.1" -db_port = 5432 -db_user = "clementine" -db_password = "" -db_name = "clementine" diff --git a/core/tests/data/test_config_verifier_down_for_withdrawal_signature.toml b/core/tests/data/test_config_verifier_down_for_withdrawal_signature.toml deleted file mode 100644 index 174baf48..00000000 --- a/core/tests/data/test_config_verifier_down_for_withdrawal_signature.toml +++ /dev/null @@ -1,47 +0,0 @@ -tracing_debug = "debug,bitcoincore_rpc=info,hyper=error" -host = "127.0.0.1" -port = 3000 -secret_key = "5555555555555555555555555555555555555555555555555555555555555555" -verifiers_public_keys = [ - "034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa", - "02466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27", - "023c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1", - "032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991", - "029ac20335eb38768d2052be1dbbc3c8f6178407458e51e6b4ad22f1d91758895b", -] -num_verifiers = 5 -operators_xonly_pks = [ - "4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa", - "466d7fcae563e5cb09a0d1870bb580344804617879a14949cf22285f1bae3f27", - "3c72addb4fdf09af94f0c94d7fe92a386a7e70cf8a1d85916386bb2535c7b1b1", - "2c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991", - "9ac20335eb38768d2052be1dbbc3c8f6178407458e51e6b4ad22f1d91758895b", -] -num_operators = 5 -bridge_amount_sats = 100000000 -user_takes_after = 5 -operator_takes_after = 5 -confirmation_threshold = 1 -network = "regtest" -bitcoin_rpc_url = "http://127.0.0.1:18443" -bitcoin_rpc_user = "admin" -bitcoin_rpc_password = "admin" -all_verifiers_secret_keys = [ - "1111111111111111111111111111111111111111111111111111111111111111", - "2222222222222222222222222222222222222222222222222222222222222222", - "3333333333333333333333333333333333333333333333333333333333333333", - "4444444444444444444444444444444444444444444444444444444444444444", - "5555555555555555555555555555555555555555555555555555555555555555", -] -all_operators_secret_keys = [ - "1111111111111111111111111111111111111111111111111111111111111111", - "2222222222222222222222222222222222222222222222222222222222222222", - "3333333333333333333333333333333333333333333333333333333333333333", - "4444444444444444444444444444444444444444444444444444444444444444", - "5555555555555555555555555555555555555555555555555555555555555555", -] -db_host = "127.0.0.1" -db_port = 5432 -db_user = "clementine" -db_password = "" -db_name = "clementine" diff --git a/core/tests/flow.rs b/core/tests/flow.rs index 4ed04a9c..768e6b51 100644 --- a/core/tests/flow.rs +++ b/core/tests/flow.rs @@ -14,7 +14,7 @@ mod common; #[tokio::test] async fn test_deposit() -> Result<(), BridgeError> { - match run_single_deposit("test_config_flow.toml").await { + match run_single_deposit("test_config.toml").await { Ok((_, _, _, deposit_outpoint)) => { // tracing::debug!("Verifiers: {:#?}", verifiers); // tracing::debug!("Operators: {:#?}", operators); @@ -32,7 +32,7 @@ async fn test_deposit() -> Result<(), BridgeError> { async fn test_honest_operator_takes_refund() { // let mut config = create_test_config_with_thread_name!("test_config_flow.toml"); let (_verifiers, operators, mut config, deposit_outpoint) = - run_single_deposit("test_config_flow.toml").await.unwrap(); + run_single_deposit("test_config.toml").await.unwrap(); let rpc = create_extended_rpc!(config); let secp = bitcoin::secp256k1::Secp256k1::new(); diff --git a/core/tests/musig2.rs b/core/tests/musig2.rs index d8e7c379..d2919d29 100644 --- a/core/tests/musig2.rs +++ b/core/tests/musig2.rs @@ -23,7 +23,7 @@ use std::thread; async fn test_musig2_key_spend() { let secp = bitcoin::secp256k1::Secp256k1::new(); - let mut config: BridgeConfig = create_test_config_with_thread_name!("test_config_musig2.toml"); + let mut config: BridgeConfig = create_test_config_with_thread_name!("test_config.toml"); let rpc: ExtendedRpc<_> = create_extended_rpc!(config); let sks = config.all_verifiers_secret_keys.unwrap(); let kp_vec: Vec = sks @@ -126,7 +126,7 @@ async fn test_musig2_key_spend() { async fn test_musig2_key_spend_with_script() { let secp = bitcoin::secp256k1::Secp256k1::new(); - let mut config: BridgeConfig = create_test_config_with_thread_name!("test_config_musig2.toml"); + let mut config: BridgeConfig = create_test_config_with_thread_name!("test_config.toml"); let rpc: ExtendedRpc<_> = create_extended_rpc!(config); let sks = config.all_verifiers_secret_keys.unwrap(); let kp_vec: Vec = sks @@ -230,7 +230,7 @@ async fn test_musig2_key_spend_with_script() { async fn test_musig2_script_spend() { let secp = bitcoin::secp256k1::Secp256k1::new(); - let mut config: BridgeConfig = create_test_config_with_thread_name!("test_config_musig2.toml"); + let mut config: BridgeConfig = create_test_config_with_thread_name!("test_config.toml"); let rpc: ExtendedRpc<_> = create_extended_rpc!(config); let sks = config.all_verifiers_secret_keys.unwrap(); let kp_vec: Vec = sks diff --git a/core/tests/taproot.rs b/core/tests/taproot.rs index 857f21ce..d1b19b60 100644 --- a/core/tests/taproot.rs +++ b/core/tests/taproot.rs @@ -19,7 +19,7 @@ use std::thread; async fn run() { let secp = bitcoin::secp256k1::Secp256k1::new(); - let mut config = create_test_config_with_thread_name!("test_config_taproot.toml"); + let mut config = create_test_config_with_thread_name!("test_config.toml"); let rpc = create_extended_rpc!(config); let (xonly_pk, _) = config.secret_key.public_key(&secp).x_only_public_key(); @@ -129,7 +129,7 @@ fn calculate_min_relay_fee(n: u64) -> u64 { #[tokio::test] async fn taproot_key_path_spend() { let secp = bitcoin::secp256k1::Secp256k1::new(); - let mut config = create_test_config_with_thread_name!("test_config_taproot.toml"); + let mut config = create_test_config_with_thread_name!("test_config.toml"); let rpc = create_extended_rpc!(config); let (xonly_pk, _) = config.secret_key.public_key(&secp).x_only_public_key(); @@ -184,7 +184,7 @@ async fn taproot_key_path_spend() { #[tokio::test] async fn taproot_key_path_spend_2() { - let mut config = create_test_config_with_thread_name!("test_config_taproot.toml"); + let mut config = create_test_config_with_thread_name!("test_config.toml"); let rpc = create_extended_rpc!(config); let actor = Actor::new(config.secret_key, config.network);