Skip to content

Commit

Permalink
Impl watchtower challenge page
Browse files Browse the repository at this point in the history
  • Loading branch information
ekrembal committed Dec 22, 2024
1 parent 903552e commit ad5df1d
Show file tree
Hide file tree
Showing 6 changed files with 331 additions and 160 deletions.
218 changes: 156 additions & 62 deletions core/src/builder/sighash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,59 +3,180 @@ use crate::errors::BridgeError;
use crate::UTXO;
use crate::{actor::Actor, builder, database::Database, EVMAddress};
use async_stream::try_stream;
use bitcoin::hashes::Hash;
use bitcoin::{address::NetworkUnchecked, Address, Amount, OutPoint};
use bitcoin::{TapSighash, Transaction};
use bitcoin::{TapSighash, Transaction, Txid};
use futures_core::stream::Stream;

pub fn create_nofn_sighash_stream(
pub async fn dummy(
db: Database,
config: BridgeConfig,
deposit_outpoint: OutPoint,
evm_address: EVMAddress,
recovery_taproot_address: Address<NetworkUnchecked>,
nofn_xonly_pk: secp256k1::XOnlyPublicKey,
user_takes_after: u64,
) -> impl Stream<Item = Result<TapSighash, BridgeError>> {
try_stream! {
// Collect kickoff transactions.
let kickoff_txs = collect_kickoff_txs(db, config.clone(), nofn_xonly_pk, evm_address).await?;

let mut wcp_txs = Vec::new();
for tx in kickoff_txs {
let kickoff_utxo = UTXO {
outpoint: OutPoint {
txid: tx.compute_txid(),
vout: 0
},
txout: tx.output[0].clone()
};
let mut watchtower_challenge_page_tx_handler = builder::transaction::create_watchtower_challenge_page_txhandler(
&kickoff_utxo,
nofn_xonly_pk,
config.bridge_amount_sats,
config.num_watchtowers as u32,
config.network,
collateral_funding_amount: Amount,
timeout_block_count: i64,
max_withdrawal_time_block_count: i64,
bridge_amount_sats: Amount,
network: bitcoin::Network,
) -> Result<(), BridgeError> {
let move_tx = builder::transaction::create_move_tx(
deposit_outpoint,
nofn_xonly_pk,
bridge_amount_sats,
network,
);
let move_txid = move_tx.compute_txid();

let operators: Vec<(secp256k1::XOnlyPublicKey, bitcoin::Address, Txid)> =
db.get_operators(None).await?;

if operators.len() < config.num_operators {
return Err(BridgeError::Error("Not enough operators".to_string()));
}

for (operator_idx, (operator_xonly_pk, operator_reimburse_address, collateral_funding_txid)) in
operators.iter().enumerate()
{
let mut input_txid = *collateral_funding_txid;
let mut input_amunt = collateral_funding_amount;

for _ in 0..config.num_time_txs {
let time_tx = builder::transaction::create_time_tx(
*operator_xonly_pk,
input_txid,
input_amunt,
timeout_block_count,
max_withdrawal_time_block_count,
network,
);
let time_txid = time_tx.compute_txid();

yield Actor::convert_tx_to_sighash_script_spend(&mut watchtower_challenge_page_tx_handler, 0, 0)?;
wcp_txs.push(watchtower_challenge_page_tx_handler);
}
// Now we have the time tx of interest here,

for watchtower in 0..config.num_watchtowers {
let utxo = UTXO { outpoint: OutPoint {
txid: wcp_txs[watchtower].tx.compute_txid(),
vout: watchtower as u32
}, txout: wcp_txs[watchtower].tx.output[watchtower].clone()
};
let mut watchtower_challenge_page_tx_2_handler = builder::transaction::create_watchtower_challenge_page_2_txhandler(
utxo,
let kickoff_tx = builder::transaction::create_kickoff_tx(
time_txid,
nofn_xonly_pk,
config.network,
move_txid,
operator_idx as usize,
network,
);

yield Actor::convert_tx_to_sighash_script_spend(&mut watchtower_challenge_page_tx_2_handler, 0, 0)?;
let kickoff_txid = kickoff_tx.compute_txid();

let mut watchtower_challenge_page_tx_handler =
builder::transaction::create_watchtower_challenge_page_txhandler(
kickoff_txid,
nofn_xonly_pk,
config.num_watchtowers as u32,
network,
);

let _yield = Actor::convert_tx_to_sighash_pubkey_spend(
&mut watchtower_challenge_page_tx_handler,
0,
)?;

let time2_tx = builder::transaction::create_time2_tx(
*operator_xonly_pk,
time_txid,
input_amunt,
network,
);

input_txid = time2_tx.compute_txid();
input_amunt = time2_tx.output[0].value;
}
}

Ok(())
}

pub fn create_nofn_sighash_stream(
db: Database,
config: BridgeConfig,
deposit_outpoint: OutPoint,
evm_address: EVMAddress,
recovery_taproot_address: Address<NetworkUnchecked>,
nofn_xonly_pk: secp256k1::XOnlyPublicKey,
user_takes_after: u64,
collateral_funding_amount: Amount,
timeout_block_count: i64,
max_withdrawal_time_block_count: i64,
bridge_amount_sats: Amount,
network: bitcoin::Network,
) -> impl Stream<Item = Result<TapSighash, BridgeError>> {
try_stream! {
let move_tx = builder::transaction::create_move_tx(
deposit_outpoint,
nofn_xonly_pk,
bridge_amount_sats,
network,
);
let move_txid = move_tx.compute_txid();

let operators: Vec<(secp256k1::XOnlyPublicKey, bitcoin::Address, Txid)> =
db.get_operators(None).await?;

if operators.len() < config.num_operators {
panic!("Not enough operators");
}

for (operator_idx, (operator_xonly_pk, operator_reimburse_address, collateral_funding_txid)) in
operators.iter().enumerate()
{
let mut input_txid = *collateral_funding_txid;
let mut input_amunt = collateral_funding_amount;

for _ in 0..config.num_time_txs {
let time_tx = builder::transaction::create_time_tx(
*operator_xonly_pk,
input_txid,
input_amunt,
timeout_block_count,
max_withdrawal_time_block_count,
network,
);
let time_txid = time_tx.compute_txid();

// Now we have the time tx of interest here,

let kickoff_tx = builder::transaction::create_kickoff_tx(
time_txid,
nofn_xonly_pk,
move_txid,
operator_idx as usize,
network,
);

let kickoff_txid = kickoff_tx.compute_txid();

let mut watchtower_challenge_page_tx_handler =
builder::transaction::create_watchtower_challenge_page_txhandler(
kickoff_txid,
nofn_xonly_pk,
config.num_watchtowers as u32,
network,
);

yield Actor::convert_tx_to_sighash_pubkey_spend(
&mut watchtower_challenge_page_tx_handler,
0,
)?;

let time2_tx = builder::transaction::create_time2_tx(
*operator_xonly_pk,
time_txid,
input_amunt,
network,
);

input_txid = time2_tx.compute_txid();
input_amunt = time2_tx.output[0].value;
}
}
// First iterate over operators
// For each operator, iterate over time txs
// For each time tx, create kickoff txid
Expand All @@ -69,33 +190,6 @@ pub fn create_nofn_sighash_stream(
}
}

async fn collect_kickoff_txs(
db: Database,
config: BridgeConfig,
nofn_xonly_pk: secp256k1::XOnlyPublicKey,
user_evm_address: EVMAddress,
) -> Result<Vec<Transaction>, BridgeError> {
let mut kickoff_txs: Vec<Transaction> = Vec::new();
for operator in 0..config.num_operators {
for time_tx in db.get_time_txs(None, operator as i32).await? {
let time_tx_outpoint = OutPoint {
txid: time_tx.1,
vout: 2,
};
let kickoff_tx = builder::transaction::create_kickoff_tx(
time_tx_outpoint,
nofn_xonly_pk,
user_evm_address,
config.network,
);

kickoff_txs.push(kickoff_tx);
}
}

Ok(kickoff_txs)
}

pub fn create_timout_tx_sighash_stream(
operator_xonly_pk: secp256k1::XOnlyPublicKey,
collateral_funding_txid: bitcoin::Txid,
Expand Down
Loading

0 comments on commit ad5df1d

Please sign in to comment.