Skip to content

Commit

Permalink
Move withdrawal code to grpc (payout tx creator) and enable withdrawa…
Browse files Browse the repository at this point in the history
…l tests (#505)

* refactor: Uncomment new_withdrawal_sig in operator module and fix compilation errors.

* feat: Add payout tx creator in builder.

* feat: Add witness element in create_payout_txhandler input.

* feat: Add witness element in create_payout_txhandler input.

* feat: Implement operator::new_withdrawal_sig call.

* chore: Re-enable rpc::run_single_deposit common function.

* test: Add client creation for create_actors and return them.

* test: Don't unwrap and return err in run_single_deposit.

* test: Enable honest_operator_takes_refund test.

* chore: Remove required std::{env, thread} use from create_test_config_with_thread_name macro.

* chore: Remove unused code.

* test: Disable honest_operator_takes_refund test in rpc test.

* feat: Re-add WithdrawalScript to script builder.

* chore: Fix compilation errors caused by the merge.

* chore: Remove unnecessary generate_witness from WithdrawalScript in builder::script.

* chore: Fix compilation errors caused by the merge.

* fix: Return error if operator::new_withdrawal_sig rpc call's input doesn't include users_intent_outpoint.

* test: Add key-spend spend path to withdrawal tx input in generate_withdrawal_transaction_and_signature macro.

* chore: Convert if let else to a one liner.

* chore: Convert UnspentTxOut::new to UnspentTxOut::from_partial in create_payout_txhandler.

* fix: Make some txhandler functions available for both signed and unsigned variants.

* fix: Return a signed txhandler in create_payout_txhandler and remove anchor output.

* docs: Add comment about a Citrea request.
  • Loading branch information
ceyhunsen authored Feb 8, 2025
1 parent 4e3372e commit aa0864a
Show file tree
Hide file tree
Showing 25 changed files with 825 additions and 755 deletions.
494 changes: 271 additions & 223 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions core/src/actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,7 @@ mod tests {
treepp::script,
};
use secp256k1::rand;
use std::env;
use std::str::FromStr;
use std::thread;

/// Returns a valid [`TxHandler`].
fn create_valid_mock_tx_handler(actor: &Actor) -> TxHandler {
Expand Down
30 changes: 29 additions & 1 deletion core/src/builder/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
// Currently generate_witness functions are not yet used.
#![allow(dead_code)]

use crate::EVMAddress;
use crate::{utils, EVMAddress};
use bitcoin::opcodes::OP_TRUE;
use bitcoin::script::PushBytesBuf;
use bitcoin::secp256k1::schnorr;
use bitcoin::{
opcodes::{all::*, OP_FALSE},
Expand Down Expand Up @@ -241,6 +242,33 @@ impl DepositScript {
}
}

/// Struct for withdrawal script.
pub struct WithdrawalScript(usize);

impl SpendableScript for WithdrawalScript {
fn as_any(&self) -> &dyn Any {
self
}

fn to_script_buf(&self) -> ScriptBuf {
let mut push_bytes = PushBytesBuf::new();
push_bytes
.extend_from_slice(&utils::usize_to_var_len_bytes(self.0))
.expect("Not possible to panic while adding a 4 to 8 bytes of slice");

Builder::new()
.push_opcode(OP_RETURN)
.push_slice(push_bytes)
.into_script()
}
}

impl WithdrawalScript {
pub fn new(index: usize) -> Self {
Self(index)
}
}

#[cfg(test)]
fn get_script_from_arr<T: SpendableScript>(
arr: &Vec<Box<dyn SpendableScript>>,
Expand Down
1 change: 0 additions & 1 deletion core/src/builder/sighash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,6 @@ mod tests {
use bitcoin::{Amount, OutPoint, ScriptBuf, TapSighash, Txid, XOnlyPublicKey};
use futures::StreamExt;
use std::pin::pin;
use std::{env, thread};

#[tokio::test]
async fn calculate_num_required_nofn_sigs() {
Expand Down
40 changes: 36 additions & 4 deletions core/src/builder/transaction/operator_reimburse.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
use super::input::SpendableTxIn;
use super::txhandler::DEFAULT_SEQUENCE;
use crate::builder::script::{CheckSig, TimelockScript};
use super::Signed;
use crate::builder::script::{CheckSig, SpendableScript, TimelockScript, WithdrawalScript};
use crate::builder::transaction::output::UnspentTxOut;
use crate::builder::transaction::txhandler::{TxHandler, TxHandlerBuilder};
use crate::constants::{BLOCKS_PER_WEEK, MIN_TAPROOT_AMOUNT};
use crate::errors::BridgeError;
use crate::rpc::clementine::NormalSignatureKind;
use crate::{builder, utils};
use crate::{builder, utils, UTXO};
use bitcoin::hashes::Hash;
use bitcoin::script::PushBytesBuf;
use bitcoin::XOnlyPublicKey;
use bitcoin::{Network, Sequence, TxOut, Txid};
use bitcoin::secp256k1::schnorr::Signature;
use bitcoin::{Amount, Network, Sequence, TxOut, Txid};
use bitcoin::{Witness, XOnlyPublicKey};
use std::sync::Arc;

/// Creates a [`TxHandler`] for the `kickoff_tx`. This transaction will be sent by the operator
Expand Down Expand Up @@ -202,3 +205,32 @@ pub fn create_reimburse_txhandler(
))
.finalize())
}

/// Creates a [`TxHandler`] for the `payout_tx`. This transaction will be sent by the operator
/// for withdrawals.
pub fn create_payout_txhandler(
input_utxo: UTXO,
output_txout: TxOut,
operator_idx: usize,
user_sig: Signature,
network: bitcoin::Network,
) -> Result<TxHandler<Signed>, BridgeError> {
let user_sig_wrapped = bitcoin::taproot::Signature {
signature: user_sig,
sighash_type: bitcoin::sighash::TapSighashType::SinglePlusAnyoneCanPay,
};
let witness = Witness::p2tr_key_spend(&user_sig_wrapped);
let txin = SpendableTxIn::new_partial(input_utxo.outpoint, input_utxo.txout);

let output_txout = UnspentTxOut::from_partial(output_txout.clone());

let scripts: Vec<Arc<dyn SpendableScript>> =
vec![Arc::new(WithdrawalScript::new(operator_idx))];
let op_return_txout = UnspentTxOut::from_scripts(Amount::from_sat(0), scripts, None, network);

TxHandlerBuilder::new()
.add_input_with_witness(txin, DEFAULT_SEQUENCE, witness)
.add_output(output_txout)
.add_output(op_return_txout)
.finalize_signed()
}
6 changes: 2 additions & 4 deletions core/src/builder/transaction/txhandler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,7 @@ impl<T: State> TxHandler<T> {
let txin = self.txins.get(idx).ok_or(BridgeError::TxInputNotFound)?;
Ok(txin.get_signature_id())
}
}

impl TxHandler<Unsigned> {
pub fn get_cached_tx(&self) -> &Transaction {
&self.cached_tx
}
Expand Down Expand Up @@ -150,7 +148,9 @@ impl TxHandler<Unsigned> {

Ok(sig_hash)
}
}

impl TxHandler<Unsigned> {
pub fn promote(self) -> Result<TxHandler<Signed>, BridgeError> {
if self.txins.iter().any(|s| s.get_witness().is_none()) {
return Err(BridgeError::MissingWitnessData);
Expand All @@ -164,9 +164,7 @@ impl TxHandler<Unsigned> {
phantom: PhantomData::<Signed>,
})
}
}

impl TxHandler<Unsigned> {
/// Constructs the witness for a script path spend of a transaction input.
///
/// # Arguments
Expand Down
1 change: 0 additions & 1 deletion core/src/database/header_chain_prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ mod tests {
use bitcoin::{BlockHash, CompactTarget, TxMerkleNode};
use borsh::BorshDeserialize;
use risc0_zkvm::Receipt;
use std::{env, thread};

#[tokio::test]
async fn save_get_new_block() {
Expand Down
1 change: 0 additions & 1 deletion core/src/database/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ mod tests {
use crate::create_test_config_with_thread_name;
use crate::{config::BridgeConfig, database::Database};
use crate::{initialize_database, utils::initialize_logger};
use std::{env, thread};

#[tokio::test]
async fn valid_database_connection() {
Expand Down
1 change: 0 additions & 1 deletion core/src/database/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,6 @@ mod tests {
};
use crate::{create_test_config_with_thread_name, UTXO};
use std::str::FromStr;
use std::{env, thread};

#[tokio::test]
async fn save_get_operators() {
Expand Down
1 change: 0 additions & 1 deletion core/src/database/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,6 @@ mod tests {
};
use crypto_bigint::rand_core::OsRng;
use secp256k1::musig::MusigPubNonce;
use std::{env, thread};

#[tokio::test]
async fn test_verifiers_kickoff_utxos_1() {
Expand Down
1 change: 0 additions & 1 deletion core/src/database/watchtower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ mod tests {
use bitcoin::{ScriptBuf, XOnlyPublicKey};
use bitvm::signatures::winternitz::{self};
use secp256k1::rand;
use std::{env, thread};

#[tokio::test]
async fn set_get_winternitz_public_key() {
Expand Down
1 change: 0 additions & 1 deletion core/src/database/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,6 @@ mod tests {
Amount, BlockHash, CompactTarget, OutPoint, ScriptBuf, TxMerkleNode, TxOut, Txid,
};
use sqlx::{Executor, Type};
use std::{env, thread};

macro_rules! test_encode_decode_invariant {
($db_type:ty, $inner:ty, $db_wrapper:expr, $table_name:expr, $column_type:expr) => {
Expand Down
1 change: 0 additions & 1 deletion core/src/header_chain_prover/blockgazer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,6 @@ mod tests {
};
use bitcoin::BlockHash;
use bitcoincore_rpc::RpcApi;
use std::{env, thread};

async fn mine_and_save_blocks(prover: &HeaderChainProver, height: u64) -> Vec<BlockHash> {
let mut fork_block_hashes = Vec::new();
Expand Down
1 change: 0 additions & 1 deletion core/src/header_chain_prover/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ mod tests {
use borsh::BorshDeserialize;
use risc0_zkvm::Receipt;
use std::time::Duration;
use std::{env, thread};
use tokio::time::sleep;

#[tokio::test]
Expand Down
1 change: 0 additions & 1 deletion core/src/header_chain_prover/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ mod tests {
};
use bitcoincore_rpc::RpcApi;
use header_chain::header_chain::{BlockHeaderCircuitOutput, CircuitBlockHeader};
use std::{env, thread};

async fn mine_and_get_first_n_block_headers(
rpc: ExtendedRpc,
Expand Down
Loading

0 comments on commit aa0864a

Please sign in to comment.