diff --git a/Cargo.toml b/Cargo.toml index 53da586e..a9c4714a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,10 +18,10 @@ sqlx = { version = "0.7.4", default-features = false } serial_test = "3.2.0" # bitcoin -bitcoin = "0.31.0" +bitcoin = "0.32.5" bitcoincore-rpc = "0.18.0" musig2 = { version = "0.0.11", features = ["serde"] } -secp256k1 = { version = "0.28.1", features = ["serde", "rand-std"] } +secp256k1 = { version = "0.29.1", features = ["serde", "rand-std"] } bitcoin-script = { git = "https://github.com/BitVM/rust-bitcoin-script", branch= "StructuredScript" } # async + gRPC @@ -41,18 +41,11 @@ borsh = { version = "1.5.1", features = ["derive"] } k256 = { version = "=0.13.3", default-features = false } risc0-build = "1.2" risc0-zkvm = { version = "1.2" } -circuits = { git = "https://github.com/chainwayxyz/risc0-to-bitvm2", branch = "downgrade_dependencies" } -bitvm = { git = "https://github.com/BitVM/BitVM" } +circuits = { git = "https://github.com/chainwayxyz/risc0-to-bitvm2", rev = "3b113b8" } +bitvm = { git = "https://github.com/BitVM/BitVM", rev = "f9cb29e" } [patch.crates-io] -bitcoincore-rpc = { version = "0.18.0", git = "https://github.com/chainwayxyz/rust-bitcoincore-rpc.git", branch = "downgrade_bitcoin" } -base58check = { git = "https://github.com/rust-bitcoin/rust-bitcoin", branch = "bitvm"} -bitcoin = { git = "https://github.com/rust-bitcoin/rust-bitcoin", branch = "bitvm"} -bitcoin_hashes = { git = "https://github.com/rust-bitcoin/rust-bitcoin", branch = "bitvm"} -bitcoin-internals = { git = "https://github.com/rust-bitcoin/rust-bitcoin", branch = "bitvm"} -bitcoin-io = { git = "https://github.com/rust-bitcoin/rust-bitcoin", branch = "bitvm"} -bitcoin-units = { git = "https://github.com/rust-bitcoin/rust-bitcoin", branch = "bitvm"} - +bitcoincore-rpc = { version = "0.18.0", git = "https://github.com/chainwayxyz/rust-bitcoincore-rpc.git", rev = "ca3cfa2" } ark-ff = { git = "https://github.com/chainwayxyz/algebra/", branch = "new-ate-loop" } ark-ec = { git = "https://github.com/chainwayxyz/algebra/", branch = "new-ate-loop" } ark-poly = { git = "https://github.com/chainwayxyz/algebra/", branch = "new-ate-loop" } diff --git a/core/src/errors.rs b/core/src/errors.rs index 23be532d..89fa3e04 100644 --- a/core/src/errors.rs +++ b/core/src/errors.rs @@ -13,9 +13,9 @@ use thiserror::Error; #[derive(Debug, Error)] #[non_exhaustive] pub enum BridgeError { - // /// Returned when the secp256k1 crate returns an error - // #[error("Secpk256Error: {0}")] - // Secp256k1Error(#[from] secp256k1::Error), + /// Returned when the secp256k1 crate returns an error + #[error("Secpk256Error: {0}")] + Secp256k1Error(#[from] secp256k1::Error), /// Returned when the bitcoin crate returns an error in the sighash taproot module #[error("BitcoinSighashTaprootError: {0}")] BitcoinSighashTaprootError(#[from] bitcoin::sighash::TaprootError), diff --git a/core/src/header_chain_prover/mod.rs b/core/src/header_chain_prover/mod.rs index 5cf5b0e9..622423e2 100644 --- a/core/src/header_chain_prover/mod.rs +++ b/core/src/header_chain_prover/mod.rs @@ -5,7 +5,7 @@ use crate::{ config::BridgeConfig, database::Database, errors::BridgeError, extended_rpc::ExtendedRpc, }; -use bitcoin::BlockHash; +use bitcoin::{hashes::Hash, BlockHash}; use bitcoincore_rpc::RpcApi; use circuits::header_chain::BlockHeaderCircuitOutput; use risc0_zkvm::Receipt; @@ -44,11 +44,9 @@ impl HeaderChainProver { .map_err(BridgeError::ProverDeSerializationError)?; // Create block entry, if not exists. - // TODO: Get this from chain_state struct. - let block_hash = rpc - .client - .get_block_hash(proof_output.chain_state.block_height.into()) - .await?; + let block_hash = BlockHash::from_raw_hash(Hash::from_slice( + &proof_output.chain_state.best_block_hash, + )?); let block_header = rpc.client.get_block_header(&block_hash).await?; // Ignore error if block entry is in database already. let _ = db diff --git a/core/src/header_chain_prover/prover.rs b/core/src/header_chain_prover/prover.rs index e283510b..0b715517 100644 --- a/core/src/header_chain_prover/prover.rs +++ b/core/src/header_chain_prover/prover.rs @@ -3,9 +3,8 @@ //! Prover is responsible for preparing RiscZero header chain prover proofs. use crate::{errors::BridgeError, header_chain_prover::HeaderChainProver}; -use bitcoin::hashes::Hash; use circuits::header_chain::{ - BlockHeader, BlockHeaderCircuitOutput, HeaderChainCircuitInput, HeaderChainPrevProofType, + BlockHeaderCircuitOutput, CircuitBlockHeader, HeaderChainCircuitInput, HeaderChainPrevProofType, }; use lazy_static::lazy_static; use risc0_zkvm::{compute_image_id, ExecutorEnv, Receipt}; @@ -13,7 +12,7 @@ use std::time::Duration; use tokio::time::sleep; // Prepare prover binary and calculate it's image id, before anything else. -const ELF: &[u8; 186232] = include_bytes!("../../../scripts/header-chain-guest"); +const ELF: &[u8; 195724] = include_bytes!("../../../scripts/header-chain-guest-regtest"); lazy_static! { static ref IMAGE_ID: [u32; 8] = compute_image_id(ELF) .unwrap() @@ -33,10 +32,10 @@ impl HeaderChainProver { /// # Returns /// /// - [`Receipt`]: Proved block headers' proof receipt. - async fn prove_block_headers( + fn prove_block_headers( &self, prev_receipt: Option, - block_headers: Vec, + block_headers: Vec, ) -> Result { // Prepare proof input. let (prev_proof, method_id) = match &prev_receipt { @@ -103,17 +102,9 @@ impl HeaderChainProver { current_block_hash ); - let header = BlockHeader { - version: current_block_header.version.to_consensus(), - prev_block_hash: current_block_header.prev_blockhash.to_byte_array(), - merkle_root: current_block_header.merkle_root.to_byte_array(), - time: current_block_header.time, - bits: current_block_header.bits.to_consensus(), - nonce: current_block_header.nonce, - }; - let receipt = prover - .prove_block_headers(Some(previous_proof), vec![header.clone()]) - .await; + let header: CircuitBlockHeader = current_block_header.into(); + let receipt = + prover.prove_block_headers(Some(previous_proof), vec![header.clone()]); match receipt { Ok(receipt) => { @@ -148,17 +139,28 @@ mod tests { hashes::Hash, BlockHash, CompactTarget, TxMerkleNode, }; - use borsh::BorshDeserialize; - use circuits::header_chain::{BlockHeader, BlockHeaderCircuitOutput}; + use bitcoincore_rpc::RpcApi; + use circuits::header_chain::{BlockHeaderCircuitOutput, CircuitBlockHeader}; use std::{env, thread}; - fn get_headers() -> Vec { - let headers = include_bytes!("../../../scripts/headers.bin"); + async fn mine_and_get_first_n_block_headers( + rpc: ExtendedRpc, + block_num: u64, + ) -> Vec { + let height = rpc.client.get_block_count().await.unwrap(); + if height < block_num { + rpc.mine_blocks(block_num - height).await.unwrap(); + } + + let mut headers = Vec::new(); + for i in 0..block_num { + let hash = rpc.client.get_block_hash(i).await.unwrap(); + let header = rpc.client.get_block_header(&hash).await.unwrap(); + + headers.push(CircuitBlockHeader::from(header)); + } headers - .chunks(80) - .map(|header| BlockHeader::try_from_slice(header).unwrap()) - .collect::>() } #[tokio::test] @@ -173,7 +175,7 @@ mod tests { .await; let prover = HeaderChainProver::new(&config, rpc.clone()).await.unwrap(); - let receipt = prover.prove_block_headers(None, vec![]).await.unwrap(); + let receipt = prover.prove_block_headers(None, vec![]).unwrap(); let output: BlockHeaderCircuitOutput = borsh::from_slice(&receipt.journal.bytes).unwrap(); println!("Proof journal output: {:?}", output); @@ -198,12 +200,11 @@ mod tests { let prover = HeaderChainProver::new(&config, rpc.clone()).await.unwrap(); // Prove genesis block and get it's receipt. - let receipt = prover.prove_block_headers(None, vec![]).await.unwrap(); + let receipt = prover.prove_block_headers(None, vec![]).unwrap(); - let block_headers = get_headers(); + let block_headers = mine_and_get_first_n_block_headers(rpc, 3).await; let receipt = prover .prove_block_headers(Some(receipt), block_headers[0..2].to_vec()) - .await .unwrap(); let output: BlockHeaderCircuitOutput = borsh::from_slice(&receipt.journal.bytes).unwrap(); @@ -223,29 +224,14 @@ mod tests { ) .await; let prover = HeaderChainProver::new(&config, rpc.clone()).await.unwrap(); - let block_headers = get_headers(); + let block_headers = mine_and_get_first_n_block_headers(rpc, 3).await; // Prove genesis block. - let receipt = prover.prove_block_headers(None, vec![]).await.unwrap(); + let receipt = prover.prove_block_headers(None, vec![]).unwrap(); let hash = BlockHash::from_raw_hash(Hash::from_slice(&block_headers[1].prev_block_hash).unwrap()); - let header = Header { - version: Version::from_consensus(block_headers[0].version), - prev_blockhash: BlockHash::from_raw_hash(Hash::from_byte_array( - block_headers[0].prev_block_hash, - )), - merkle_root: TxMerkleNode::from_raw_hash(Hash::from_byte_array( - block_headers[0].merkle_root, - )), - time: block_headers[0].time, - bits: CompactTarget::from_consensus(block_headers[0].bits), - nonce: block_headers[0].nonce, - }; - prover - .db - .save_new_block(None, hash, header, 0) - .await - .unwrap(); + let header: Header = block_headers[0].clone().into(); + let _ = prover.db.save_new_block(None, hash, header, 0).await; // TODO: Unwrapping this causes errors. prover .db .save_block_proof(None, hash, receipt.clone()) @@ -258,7 +244,6 @@ mod tests { // Prove second block. let receipt = prover .prove_block_headers(Some(receipt), block_headers[0..2].to_vec()) - .await .unwrap(); let hash = BlockHash::from_raw_hash(Hash::from_slice(&block_headers[2].prev_block_hash).unwrap()); diff --git a/core/src/test_utils.rs b/core/src/test_utils.rs index 5bb68105..ddb87fe7 100644 --- a/core/src/test_utils.rs +++ b/core/src/test_utils.rs @@ -62,6 +62,8 @@ macro_rules! create_test_config_with_thread_name { None }; + config.db_name = handle.to_string(); + // Overwrite user's environment to test's hard coded data if environment // file is specified. if let Some(env_config) = env_config { @@ -72,7 +74,6 @@ macro_rules! create_test_config_with_thread_name { config.db_name = env_config.db_name; }; - config.db_name = handle.to_string(); initialize_database!(&config); config diff --git a/core/tests/data/first_1.bin b/core/tests/data/first_1.bin index 65789975..1c11b061 100644 Binary files a/core/tests/data/first_1.bin and b/core/tests/data/first_1.bin differ diff --git a/scripts/header-chain-guest b/scripts/header-chain-guest deleted file mode 100755 index a8e5ff44..00000000 Binary files a/scripts/header-chain-guest and /dev/null differ diff --git a/scripts/header-chain-guest-regtest b/scripts/header-chain-guest-regtest new file mode 100755 index 00000000..56b2d35d Binary files /dev/null and b/scripts/header-chain-guest-regtest differ diff --git a/scripts/headers.bin b/scripts/headers.bin deleted file mode 100644 index f92d6c79..00000000 Binary files a/scripts/headers.bin and /dev/null differ