Skip to content

Commit

Permalink
Change the kickoff_utxo creating tx logic (#265)
Browse files Browse the repository at this point in the history
* Change the kickoff_utxo creating tx logic

* Remove unnecessary config files, apply review changes

* Fix small VarInt issue

* Add comment

* Fix CI check

* nits
  • Loading branch information
ozankaymak authored and ceyhunsen committed Sep 2, 2024
1 parent 279d791 commit 75fba4f
Show file tree
Hide file tree
Showing 18 changed files with 281 additions and 352 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,4 @@ jobs:
shared-key: "release-build"

- name: Run tests on mock RPC with release build
run: cargo test --verbose --features mock_rpc --release
run: cargo test --verbose --features mock_rpc --release
42 changes: 23 additions & 19 deletions core/src/aggregator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand All @@ -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)
}

Expand Down Expand Up @@ -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,
Expand All @@ -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()
Expand All @@ -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)
}

Expand Down
3 changes: 3 additions & 0 deletions core/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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(),
Expand Down
100 changes: 83 additions & 17 deletions core/src/database/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Option<UTXO>, 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,
Expand Down Expand Up @@ -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?;
Expand Down Expand Up @@ -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
Expand All @@ -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]
Expand Down
2 changes: 1 addition & 1 deletion core/src/database/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub struct AddressDB(pub Address<NetworkUnchecked>);
#[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)]
Expand Down
16 changes: 8 additions & 8 deletions core/src/musig2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,19 @@ pub fn create_key_agg_ctx(
.map(|pk| musig2::secp256k1::PublicKey::from_slice(&pk.serialize()).unwrap())
.collect::<Vec<musig2::secp256k1::PublicKey>>();
let key_agg_ctx_raw = KeyAggContext::new(musig_pks)?;
tracing::debug!(
"UNTWEAKED AGGREGATED PUBKEY: {:?}",
key_agg_ctx_raw.aggregated_pubkey::<musig2::secp256k1::PublicKey>()
);
// tracing::debug!(
// "UNTWEAKED AGGREGATED PUBKEY: {:?}",
// key_agg_ctx_raw.aggregated_pubkey::<musig2::secp256k1::PublicKey>()
// );
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::<musig2::secp256k1::PublicKey>()
);
// tracing::debug!(
// "TWEAKED AGGREGATED PUBKEY: {:?}",
// key_agg_ctx.aggregated_pubkey::<musig2::secp256k1::PublicKey>()
// );
Ok(key_agg_ctx)
} else {
if tweak.is_some() {
Expand Down
Loading

0 comments on commit 75fba4f

Please sign in to comment.