diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..73faadeb --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,57 @@ +name: Cargo Build & Test + +on: + push: + branches: + - main + pull_request: + branches: + - main + +env: + CARGO_TERM_COLOR: always + +jobs: + fmt: + name: Rustfmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - run: rustup component add rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + clippy: + name: Clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: nightly + override: true + - run: rustup component add clippy + - run: cargo clippy --all-targets -- -D warnings + test: + name: Cargo Test + runs-on: ubuntu-latest + environment: + GOAT_CHAIN_URL: https://rpc.testnet3.goat.network + GOAT_GATEWAY_CONTRACT_ADDRESS: 0xeD8AeeD334fA446FA03Aa00B28aFf02FA8aC02df + GOAT_GATEWAY_CONTRACT_CREATION: 0 + GOAT_CHAIN_ID: 48816 + RUST_LOG: info" + strategy: + matrix: + toolchain: + - nightly + steps: + - uses: actions/checkout@v2 + - run: cargo test -r diff --git a/Cargo.toml b/Cargo.toml index 6ff6a702..67057d36 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,8 +9,6 @@ members = [ "crates/store", "crates/identity", "node", "crates/spv", "crates/client", ] -default-members = ["node"] - [workspace.dependencies] bitvm = { git = "https://github.com/GOATNetwork/BitVM.git", branch = "goat-test" } goat = { git = "https://github.com/GOATNetwork/BitVM.git", branch = "goat-test" } @@ -72,6 +70,7 @@ tracing-subscriber = "0.3.19" anyhow = "1.0.97" axum = "0.8.1" +axum-extra = { version = "0.8" } http = "1.3.1" uuid = { version = "1.7", features = ["v4", "serde"] } zeroize = "1.8.1" diff --git a/crates/bitvm2/src/challenger/mod.rs b/crates/bitvm2/src/challenger/mod.rs deleted file mode 100644 index b93cf3ff..00000000 --- a/crates/bitvm2/src/challenger/mod.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn add(left: u64, right: u64) -> u64 { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} diff --git a/crates/bitvm2/src/committee/api.rs b/crates/bitvm2/src/committee/api.rs index db37e76f..d4db7dee 100644 --- a/crates/bitvm2/src/committee/api.rs +++ b/crates/bitvm2/src/committee/api.rs @@ -1,7 +1,7 @@ use crate::types::Bitvm2Graph; -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; use bitcoin::PublicKey; -use bitcoin::{hex::FromHex, key::Keypair, TapSighashType, Witness}; +use bitcoin::{TapSighashType, Witness, hex::FromHex, key::Keypair}; use goat::connectors::{connector_0::Connector0, connector_5::Connector5, connector_d::ConnectorD}; use goat::contexts::base::generate_n_of_n_public_key; use goat::transactions::signing_musig2::{ @@ -11,7 +11,7 @@ use goat::transactions::{ base::BaseTransaction, pre_signed::PreSignedTransaction, pre_signed_musig2::get_nonce_message, signing_musig2::generate_taproot_partial_signature, }; -use musig2::{secp256k1::schnorr::Signature, AggNonce, PartialSignature, PubNonce, SecNonce}; +use musig2::{AggNonce, PartialSignature, PubNonce, SecNonce, secp256k1::schnorr::Signature}; use sha2::{Digest, Sha256}; pub const COMMITTEE_PRE_SIGN_NUM: usize = 5; diff --git a/crates/bitvm2/src/committee/mod.rs b/crates/bitvm2/src/committee/mod.rs index 3b048931..3a281e03 100644 --- a/crates/bitvm2/src/committee/mod.rs +++ b/crates/bitvm2/src/committee/mod.rs @@ -1,7 +1,7 @@ mod api; pub use api::{ - committee_pre_sign, generate_keypair_from_seed, generate_nonce_from_seed, key_aggregation, - nonce_aggregation, nonces_aggregation, push_committee_pre_signatures, - signature_aggregation_and_push, COMMITTEE_PRE_SIGN_NUM, + COMMITTEE_PRE_SIGN_NUM, committee_pre_sign, generate_keypair_from_seed, + generate_nonce_from_seed, key_aggregation, nonce_aggregation, nonces_aggregation, + push_committee_pre_signatures, signature_aggregation_and_push, }; diff --git a/crates/bitvm2/src/keys.rs b/crates/bitvm2/src/keys.rs index 7974000c..ae487bea 100644 --- a/crates/bitvm2/src/keys.rs +++ b/crates/bitvm2/src/keys.rs @@ -1,10 +1,10 @@ use super::{ - committee::{generate_keypair_from_seed, generate_nonce_from_seed, COMMITTEE_PRE_SIGN_NUM}, + committee::{COMMITTEE_PRE_SIGN_NUM, generate_keypair_from_seed, generate_nonce_from_seed}, operator::generate_wots_keys, types::{WotsPublicKeys, WotsSecretKeys}, }; use bitcoin::key::Keypair; -use musig2::{secp256k1::schnorr::Signature, PubNonce, SecNonce}; +use musig2::{PubNonce, SecNonce, secp256k1::schnorr::Signature}; use sha2::{Digest, Sha256}; use uuid::Uuid; diff --git a/crates/bitvm2/src/lib.rs b/crates/bitvm2/src/lib.rs index b9589f58..bd41c20b 100644 --- a/crates/bitvm2/src/lib.rs +++ b/crates/bitvm2/src/lib.rs @@ -1,4 +1,3 @@ -pub mod challenger; pub mod committee; pub mod operator; pub mod verifier; diff --git a/crates/bitvm2/src/operator/api.rs b/crates/bitvm2/src/operator/api.rs index e3b35a58..1ccd9fe3 100644 --- a/crates/bitvm2/src/operator/api.rs +++ b/crates/bitvm2/src/operator/api.rs @@ -1,19 +1,19 @@ use crate::types::{ - get_magic_bytes, Bitvm2Graph, Bitvm2Parameters, CustomInputs, Groth16Proof, - Groth16WotsPublicKeys, Groth16WotsSignatures, PublicInputs, VerifyingKey, WotsPublicKeys, - WotsSecretKeys, + Bitvm2Graph, Bitvm2Parameters, CustomInputs, Groth16Proof, Groth16WotsPublicKeys, + Groth16WotsSignatures, PublicInputs, VerifyingKey, WotsPublicKeys, WotsSecretKeys, + get_magic_bytes, }; -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; use bitcoin::Transaction; -use bitcoin::{key::Keypair, Amount, OutPoint, Witness, XOnlyPublicKey}; +use bitcoin::{Amount, OutPoint, Witness, XOnlyPublicKey, key::Keypair}; use bitvm::chunk::api::{ - api_generate_full_tapscripts, api_generate_partial_script, generate_signatures_lit, - type_conversion_utils::utils_raw_witnesses_from_signatures, NUM_HASH, NUM_PUBS, NUM_U256, + NUM_HASH, NUM_PUBS, NUM_U256, api_generate_full_tapscripts, api_generate_partial_script, + generate_signatures_lit, type_conversion_utils::utils_raw_witnesses_from_signatures, }; use bitvm::signatures::{ - signing_winternitz::{WinternitzPublicKey, WinternitzSecret, WinternitzSigningInputs, LOG_D}, + signing_winternitz::{LOG_D, WinternitzPublicKey, WinternitzSecret, WinternitzSigningInputs}, winternitz::Parameters, - wots_api::{wots256, wots_hash}, + wots_api::{wots_hash, wots256}, }; use bitvm::treepp::*; use goat::commitments::{CommitmentMessageId, KICKOFF_MSG_SIZE, NUM_KICKOFF}; @@ -28,8 +28,8 @@ use goat::transactions::{ assert::assert_final::AssertFinalTransaction, assert::assert_initial::AssertInitialTransaction, assert::utils::{ - convert_to_connector_c_commits_public_key, AllCommitConnectorsE, AssertCommitConnectorsF, - COMMIT_TX_NUM, + AllCommitConnectorsE, AssertCommitConnectorsF, COMMIT_TX_NUM, + convert_to_connector_c_commits_public_key, }, base::Input, challenge::ChallengeTransaction, diff --git a/crates/bitvm2/src/pegin.rs b/crates/bitvm2/src/pegin.rs index c6bb05ce..ba716660 100644 --- a/crates/bitvm2/src/pegin.rs +++ b/crates/bitvm2/src/pegin.rs @@ -1,6 +1,6 @@ use bitcoin::opcodes::all::OP_RETURN; use bitcoin::script::Instruction; -use bitcoin::{script, Network, Script}; +use bitcoin::{Network, Script, script}; use crate::types::get_magic_bytes; diff --git a/crates/bitvm2/src/types.rs b/crates/bitvm2/src/types.rs index 2d90e8ea..1aa6fef9 100644 --- a/crates/bitvm2/src/types.rs +++ b/crates/bitvm2/src/types.rs @@ -1,7 +1,7 @@ use bitcoin::TapNodeHash; -use bitcoin::{key::Keypair, Address, Amount, Network, PrivateKey, PublicKey, XOnlyPublicKey}; +use bitcoin::{Address, Amount, Network, PrivateKey, PublicKey, XOnlyPublicKey, key::Keypair}; use bitvm::chunk::api::{ - PublicKeys as ApiWotsPublicKeys, Signatures as ApiWotsSignatures, NUM_HASH, NUM_PUBS, NUM_U256, + NUM_HASH, NUM_PUBS, NUM_U256, PublicKeys as ApiWotsPublicKeys, Signatures as ApiWotsSignatures, }; use bitvm::signatures::signing_winternitz::{WinternitzPublicKey, WinternitzSecret}; use goat::commitments::NUM_KICKOFF; @@ -15,7 +15,7 @@ use goat::transactions::{ kick_off::KickOffTransaction, peg_in::peg_in::PegInTransaction, peg_out_confirm::PreKickoffTransaction, take_1::Take1Transaction, take_2::Take2Transaction, }; -use rand::{distributions::Alphanumeric, Rng}; +use rand::{Rng, distributions::Alphanumeric}; use secp256k1::SECP256K1; use serde::{Deserialize, Serialize}; @@ -172,7 +172,7 @@ pub fn get_magic_bytes(net: &Network) -> Vec { } pub mod node_serializer { - use serde::{self, ser::Error, Deserialize, Deserializer, Serializer}; + use serde::{self, Deserialize, Deserializer, Serializer, ser::Error}; use std::str::FromStr; pub mod address { @@ -203,7 +203,7 @@ pub mod node_serializer { use crate::types::WotsPublicKeys; use bitvm::chunk::api::{NUM_HASH, NUM_PUBS, NUM_U256}; use bitvm::signatures::signing_winternitz::WinternitzPublicKey; - use bitvm::signatures::wots_api::{wots256, wots_hash}; + use bitvm::signatures::wots_api::{wots_hash, wots256}; use goat::commitments::NUM_KICKOFF; use std::collections::HashMap; @@ -214,17 +214,17 @@ pub mod node_serializer { let mut pubkeys_map: HashMap>> = HashMap::new(); let mut index = 0; // wots pk for groth16 proof - for pk in pubkeys.1 .0 { + for pk in pubkeys.1.0 { let v: Vec> = pk.iter().map(|x| x.to_vec()).collect(); pubkeys_map.insert(index, v); index += 1; } - for pk in pubkeys.1 .1 { + for pk in pubkeys.1.1 { let v: Vec> = pk.iter().map(|x| x.to_vec()).collect(); pubkeys_map.insert(index, v); index += 1; } - for pk in pubkeys.1 .2 { + for pk in pubkeys.1.2 { let v: Vec> = pk.iter().map(|x| x.to_vec()).collect(); pubkeys_map.insert(index, v); index += 1; @@ -359,11 +359,11 @@ pub mod node_serializer { pub mod wots_seckeys { use serde::de::{SeqAccess, Visitor}; use serde::ser::SerializeTuple; - use serde::{de::Error as DeError, ser::Error, Deserializer, Serializer}; + use serde::{Deserializer, Serializer, de::Error as DeError, ser::Error}; use std::fmt; use crate::types::{ - Groth16WotsSecretKeys, KickoffWotsSecretKeys, WotsSecretKeys, NUM_KICKOFF, NUM_SIGS, + Groth16WotsSecretKeys, KickoffWotsSecretKeys, NUM_KICKOFF, NUM_SIGS, WotsSecretKeys, }; pub fn serialize(keys: &WotsSecretKeys, serializer: S) -> Result @@ -445,7 +445,7 @@ pub mod node_serializer { #[cfg(test)] mod tests { use crate::operator::generate_wots_keys; - use crate::types::{node_serializer, WotsPublicKeys, WotsSecretKeys}; + use crate::types::{WotsPublicKeys, WotsSecretKeys, node_serializer}; use serde::{Deserialize, Serialize}; use std::fmt::Debug; diff --git a/crates/bitvm2/src/verifier/api.rs b/crates/bitvm2/src/verifier/api.rs index 7fe5bdc8..c0475013 100644 --- a/crates/bitvm2/src/verifier/api.rs +++ b/crates/bitvm2/src/verifier/api.rs @@ -1,14 +1,15 @@ use crate::types::{ Bitvm2Graph, Groth16WotsPublicKeys, Groth16WotsSignatures, VerifyingKey, WotsPublicKeys, }; -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; use bitcoin::{Address, Amount, Transaction}; use bitvm::chunk::api::{ - type_conversion_utils::{script_to_witness, utils_signatures_from_raw_witnesses, RawWitness}, - validate_assertions, NUM_TAPS, + NUM_TAPS, + type_conversion_utils::{RawWitness, script_to_witness, utils_signatures_from_raw_witnesses}, + validate_assertions, }; use bitvm::treepp::*; -use goat::connectors::connector_c::{get_commit_from_assert_commit_tx, ConnectorC}; +use goat::connectors::connector_c::{ConnectorC, get_commit_from_assert_commit_tx}; use goat::transactions::assert::utils::*; use goat::transactions::{base::BaseTransaction, pre_signed::PreSignedTransaction}; diff --git a/crates/bitvm2/tests/e2e.rs b/crates/bitvm2/tests/e2e.rs index 5629164a..24562fe7 100644 --- a/crates/bitvm2/tests/e2e.rs +++ b/crates/bitvm2/tests/e2e.rs @@ -18,6 +18,7 @@ use secp256k1::SECP256K1; use std::str::FromStr; #[test] +#[ignore] fn e2e_test() { let network = Network::Testnet; // key generation diff --git a/crates/client/src/chain/chain_adaptor.rs b/crates/client/src/chain/chain_adaptor.rs index 6904ff1a..9484b9d4 100644 --- a/crates/client/src/chain/chain_adaptor.rs +++ b/crates/client/src/chain/chain_adaptor.rs @@ -172,7 +172,7 @@ pub struct BitcoinTx { pub fn get_chain_adaptor( network: GoatNetwork, - goat_config: Option, + goat_config: GoatInitConfig, mock_adaptor_config: Option, ) -> Box { match network { diff --git a/crates/client/src/chain/goat_adaptor.rs b/crates/client/src/chain/goat_adaptor.rs index 402a6e33..2dc0f9d5 100644 --- a/crates/client/src/chain/goat_adaptor.rs +++ b/crates/client/src/chain/goat_adaptor.rs @@ -6,16 +6,16 @@ use alloy::primitives::TxHash; use alloy::{ eips::BlockNumberOrTag, network::{ - eip2718::Encodable2718, Ethereum, EthereumWallet, NetworkWallet, TransactionBuilder, - TxSigner, TxSignerSync, + Ethereum, EthereumWallet, NetworkWallet, TransactionBuilder, TxSigner, TxSignerSync, + eip2718::Encodable2718, }, primitives::{Address as EvmAddress, Bytes, ChainId, FixedBytes, U256}, providers::{Provider, ProviderBuilder, RootProvider}, rpc::types::TransactionRequest, - signers::{local::PrivateKeySigner, Signer}, + signers::{Signer, local::PrivateKeySigner}, sol, sol_types::SolEvent, - transports::http::{reqwest::Url, Client, Http}, + transports::http::{Client, Http, reqwest::Url}, }; use anyhow::format_err; use async_trait::async_trait; @@ -287,7 +287,7 @@ impl ChainAdaptor for GoatAdaptor { .await?; Ok(WithdrawData { pegin_txid: res._0.0, - operator_address: res._1.0 .0, + operator_address: res._1.0.0, status: res._2.into(), instance_id: Uuid::from_slice(res._3.as_slice())?, lock_amount: res._4, @@ -541,40 +541,8 @@ impl ChainAdaptor for GoatAdaptor { } impl GoatAdaptor { - pub fn new(config: Option) -> Self { - if let Some(_config) = config { - Self::from_config(_config) - } else { - dotenv::dotenv().ok(); - let rpc_url_str = dotenv::var("GATE_CHAIN_ADAPTOR_GOAT_RPC_URL") - .expect("Failed to read GATE_CHAIN_ADAPTOR_GOAT_RPC_URL variable"); - let gateway_address_str = dotenv::var("GATEWAY_CHAIN_ADAPTOR_GOAT_GATE_ADDRESS") - .expect("Failed to read GATE_CHAIN_ADAPTOR_GOAT_GATE_ADDRESS variable"); - let gateway_creation = dotenv::var("GATE_CHAIN_ADAPTOR_GOAT_GATE_CREATION") - .expect("Failed to read GATE_CHAIN_ADAPTOR_GOAT_GATE_CREATION variable"); - let to_block = dotenv::var("GATE_CHAIN_ADAPTOR_GOAT_TO_BLOCK"); - - let private_key = match dotenv::var("GATE_CHAIN_ADAPTOR_GOAT_PRIVATE_KEY") { - Ok(key) => Some(key), - Err(_) => None, - }; - let chain_id = dotenv::var("GATE_CHAIN_ADAPTOR_GOAT_CHAIN_ID") - .expect("Failed to read GATE_CHAIN_ADAPTOR_GOAT_CHAIN_ID variable"); - - let rpc_url = rpc_url_str.parse::(); - let gateway_address = gateway_address_str.parse::(); - Self::from_config(GoatInitConfig { - rpc_url: rpc_url.unwrap(), - gateway_address: gateway_address.unwrap(), - gateway_creation_block: gateway_creation.parse::().unwrap(), - to_block: match to_block { - Ok(block) => Some(BlockNumberOrTag::from_str(block.as_str()).unwrap()), - Err(_) => Some(BlockNumberOrTag::Finalized), - }, - private_key, - chain_id: chain_id.parse().expect("fail to parse int"), - }) - } + pub fn new(config: GoatInitConfig) -> Self { + Self::from_config(config) } fn from_config(config: GoatInitConfig) -> Self { diff --git a/crates/client/src/client.rs b/crates/client/src/client.rs index a7b4d57a..9f7b20c3 100644 --- a/crates/client/src/client.rs +++ b/crates/client/src/client.rs @@ -1,6 +1,6 @@ use crate::chain::chain::Chain; use crate::chain::chain_adaptor::{ - get_chain_adaptor, ChainAdaptor, GoatNetwork, OperatorData, PeginData, WithdrawData, + ChainAdaptor, GoatNetwork, OperatorData, PeginData, WithdrawData, get_chain_adaptor, }; use crate::chain::goat_adaptor::GoatInitConfig; use crate::esplora::get_esplora_url; @@ -26,7 +26,7 @@ impl BitVM2Client { esplora_url: Option<&str>, btc_network: Network, goat_network: GoatNetwork, - goat_config: Option, + goat_config: GoatInitConfig, ) -> Self { let local_db = LocalDB::new(&format!("sqlite:{db_path}"), true).await; local_db.migrate().await; diff --git a/crates/client/src/lib.rs b/crates/client/src/lib.rs index 43a2984f..107745ba 100644 --- a/crates/client/src/lib.rs +++ b/crates/client/src/lib.rs @@ -29,7 +29,7 @@ mod tests { None, Network::Testnet, GoatNetwork::Test, - Some(global_init_config), + global_init_config , ) .await; let tx_id = diff --git a/crates/identity/src/musig2.rs b/crates/identity/src/musig2.rs index c3e1f058..9032fe4b 100644 --- a/crates/identity/src/musig2.rs +++ b/crates/identity/src/musig2.rs @@ -9,14 +9,14 @@ use std::{ use tokio::sync::mpsc::{self, Receiver, Sender}; use libp2p::{ - core::{multiaddr::Protocol, Multiaddr}, + core::{Multiaddr, multiaddr::Protocol}, identify, identity, noise, swarm::{NetworkBehaviour, SwarmEvent}, tcp, yamux, }; +use musig2::KeyAggContext; use musig2::k256::PublicKey; use musig2::secp::Scalar; -use musig2::KeyAggContext; use musig2::{ AggNonce, CompactSignature, FirstRound, PartialSignature, PubNonce, SecNonce, SecNonceSpices, SecondRound, diff --git a/crates/spv/src/header_chain.rs b/crates/spv/src/header_chain.rs index 1bbc6422..79702646 100644 --- a/crates/spv/src/header_chain.rs +++ b/crates/spv/src/header_chain.rs @@ -1,7 +1,7 @@ use bitcoin::{ + BlockHash, CompactTarget, TxMerkleNode, block::{Header, Version}, hashes::Hash, - BlockHash, CompactTarget, TxMerkleNode, }; use borsh::{BorshDeserialize, BorshSerialize}; use serde::{Deserialize, Serialize}; diff --git a/crates/spv/src/lib.rs b/crates/spv/src/lib.rs index 02a62940..09cfb3cb 100644 --- a/crates/spv/src/lib.rs +++ b/crates/spv/src/lib.rs @@ -151,7 +151,7 @@ mod tests { ]; #[test] fn test_spv() { - let mut mmr_native = MMRNative::new(); + let mut mmr_native = MMRHost::new(); let mut mmr_guest = MMRGuest::new(); let block_headers = MAINNET_BLOCK_HEADERS .iter() diff --git a/crates/spv/src/merkle_tree.rs b/crates/spv/src/merkle_tree.rs index 1729fe26..12210a59 100644 --- a/crates/spv/src/merkle_tree.rs +++ b/crates/spv/src/merkle_tree.rs @@ -137,9 +137,9 @@ pub fn verify_merkle_proof( mod tests { use crate::transaction::CircuitTransaction; + use bitcoin::Block; use bitcoin::hashes::Hash; use bitcoin::hex::FromHex; - use bitcoin::Block; use super::*; diff --git a/crates/store/src/ipfs.rs b/crates/store/src/ipfs.rs index ba9ccb7c..34060208 100644 --- a/crates/store/src/ipfs.rs +++ b/crates/store/src/ipfs.rs @@ -1,7 +1,7 @@ -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; use futures::TryStreamExt; -use reqwest::multipart::{Form, Part}; use reqwest::Client; +use reqwest::multipart::{Form, Part}; use serde::Deserialize; use std::path::Path; use tokio::fs::File; diff --git a/crates/store/src/localdb.rs b/crates/store/src/localdb.rs index 067cb4e1..616c7dff 100644 --- a/crates/store/src/localdb.rs +++ b/crates/store/src/localdb.rs @@ -1,14 +1,14 @@ use crate::schema::NODE_STATUS_OFFLINE; use crate::schema::NODE_STATUS_ONLINE; use crate::{ - GrapRpcQueryData, Graph, Instance, Message, Node, NodesOverview, NonceCollect, - NonceCollectMetaData, PubKeyCollect, PubKeyCollectMetaData, COMMITTEE_PRE_SIGN_NUM, + COMMITTEE_PRE_SIGN_NUM, GrapRpcQueryData, Graph, Instance, Message, Node, NodesOverview, + NonceCollect, NonceCollectMetaData, PubKeyCollect, PubKeyCollectMetaData, }; use futures::future::ok; use sqlx::migrate::Migrator; use sqlx::pool::PoolConnection; use sqlx::types::Uuid; -use sqlx::{migrate::MigrateDatabase, Row, Sqlite, SqliteConnection, SqlitePool, Transaction}; +use sqlx::{Row, Sqlite, SqliteConnection, SqlitePool, Transaction, migrate::MigrateDatabase}; use std::time::{SystemTime, UNIX_EPOCH}; #[derive(Clone)] diff --git a/node/Cargo.toml b/node/Cargo.toml index f3b5315a..31107d04 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -70,6 +70,7 @@ goat = { workspace = true } web3 = { workspace = true } uuid = { workspace = true } hex = { workspace = true } +alloy = { workspace = true } sha2 = { workspace = true } bincode = "1.3.3" diff --git a/node/src/action.rs b/node/src/action.rs index 8024c624..a823393a 100644 --- a/node/src/action.rs +++ b/node/src/action.rs @@ -3,7 +3,7 @@ use crate::middleware::AllBehaviours; use crate::rpc_service::current_time_secs; use anyhow::Result; use bitcoin::PublicKey; -use bitcoin::{key::Keypair, Amount, Network, OutPoint, Txid}; +use bitcoin::{Amount, Network, OutPoint, Txid, key::Keypair}; use bitvm2_lib::actors::Actor; use bitvm2_lib::keys::*; use bitvm2_lib::types::{ @@ -14,7 +14,7 @@ use bitvm2_lib::{committee::*, operator::*, verifier::*}; use client::client::BitVM2Client; use goat::transactions::{assert::utils::COMMIT_TX_NUM, pre_signed::PreSignedTransaction}; use libp2p::gossipsub::MessageId; -use libp2p::{gossipsub, PeerId, Swarm}; +use libp2p::{PeerId, Swarm, gossipsub}; use musig2::{AggNonce, PartialSignature, PubNonce, SecNonce}; use reqwest::Request; use serde::de::DeserializeOwned; @@ -220,7 +220,7 @@ pub mod todo_funcs { use bitcoin::{ Address, EcdsaSighashType, ScriptBuf, Sequence, Transaction, TxIn, TxOut, Witness, }; - use bitcoin_script::{script, Script}; + use bitcoin_script::{Script, script}; use bitvm::chunk::api::NUM_TAPS; use bitvm2_lib::types::WotsPublicKeys; use client::chain::chain_adaptor::WithdrawStatus; diff --git a/node/src/bitcoin/checker.rs b/node/src/bitcoin/checker.rs index 93d58096..40386ea1 100644 --- a/node/src/bitcoin/checker.rs +++ b/node/src/bitcoin/checker.rs @@ -1,9 +1,9 @@ -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; use bitcoin::blockdata::script::Script; use bitcoin::hashes::Hash; use bitcoin::{Amount, Block, Network, Transaction, Txid}; use esplora_client::{AsyncClient, Builder, Tx}; -use futures::{stream, StreamExt}; +use futures::{StreamExt, stream}; use spv::verify_merkle_proof; use spv::{ BitcoinMerkleTree, BlockInclusionProof, CircuitBlockHeader, CircuitTransaction, MMRGuest, @@ -142,7 +142,7 @@ pub async fn check_pegin_tx( #[cfg(test)] pub mod test { use super::*; - use futures::{stream, StreamExt}; + use futures::{StreamExt, stream}; #[tokio::test] async fn test_check_pegin_tx() { // tx: https://mempool.space/testnet/tx/e413208c6644d51f4f3adf3a5aad425da817ac825e56352e7164de1e2a4d9394 diff --git a/node/src/env.rs b/node/src/env.rs index fed74b5c..cce98706 100644 --- a/node/src/env.rs +++ b/node/src/env.rs @@ -1,5 +1,17 @@ -use bitcoin::{key::Keypair, Network, PublicKey}; +use alloy::eips::BlockNumberOrTag; +use alloy::primitives::Address as EvmAddress; +use bitcoin::{Network, PublicKey, key::Keypair}; use bitvm2_lib::keys::NodeMasterKey; +use client::chain::goat_adaptor::GoatInitConfig; +use reqwest::Url; +use std::str::FromStr; + +pub const ENV_GOAT_CHAIN_URL: &str = "GOAT_CHAIN_URL"; +pub const ENV_GOAT_GATEWAY_CONTRACT_ADDRESS: &str = "GOAT_GATEWAY_CONTRACT_ADDRESS"; +pub const ENV_GOAT_GATEWAY_CONTRACT_CREATION: &str = "GOAT_GATEWAY_CONTRACT_CREATION"; +pub const ENV_GOAT_GATEWAY_CONTRACT_TO_BLOCK: &str = "GOAT_GATEWAY_CONTRACT_TO_BLOCK"; +pub const ENV_GOAT_PRIVATE_KEY: &str = "GOAT_PRIVATE_KEY"; +pub const ENV_GOAT_CHAIN_ID: &str = "GOAT_CHAIN_ID"; pub const SCRIPT_CACHE_FILE_NAME: &str = "cache/partial_script.bin"; pub const DUST_AMOUNT: u64 = goat::transactions::base::DUST_AMOUNT; @@ -42,3 +54,33 @@ pub fn get_node_pubkey() -> Result> { pub fn get_committee_member_num() -> usize { COMMITTEE_MEMBER_NUMBER } + +pub fn get_bitvm2_client_config() -> GoatInitConfig { + let rpc_url_str = std::env::var(ENV_GOAT_CHAIN_URL) + .expect(format!("Failed to read {} variable", ENV_GOAT_CHAIN_URL).as_str()); + let gateway_address_str = std::env::var(ENV_GOAT_GATEWAY_CONTRACT_ADDRESS) + .expect(format!("Failed to read {} variable", ENV_GOAT_GATEWAY_CONTRACT_ADDRESS).as_str()); + let gateway_creation = std::env::var(ENV_GOAT_GATEWAY_CONTRACT_CREATION) + .expect(format!("Failed to read {} variable", ENV_GOAT_GATEWAY_CONTRACT_CREATION).as_str()); + let to_block = std::env::var(ENV_GOAT_GATEWAY_CONTRACT_TO_BLOCK); + let private_key = match std::env::var(ENV_GOAT_PRIVATE_KEY) { + Ok(key) => Some(key), + Err(_) => None, + }; + let chain_id = std::env::var(ENV_GOAT_CHAIN_ID) + .expect(format!("Failed to read {} variable", ENV_GOAT_CHAIN_ID).as_str()); + + let rpc_url = rpc_url_str.parse::(); + let gateway_address = gateway_address_str.parse::(); + GoatInitConfig { + rpc_url: rpc_url.unwrap(), + gateway_address: gateway_address.unwrap(), + gateway_creation_block: gateway_creation.parse::().unwrap(), + to_block: match to_block { + Ok(block) => Some(BlockNumberOrTag::from_str(block.as_str()).unwrap()), + Err(_) => Some(BlockNumberOrTag::Finalized), + }, + private_key, + chain_id: chain_id.parse().expect("fail to parse int"), + } +} diff --git a/node/src/main.rs b/node/src/main.rs index 013edd8a..bbc8e607 100644 --- a/node/src/main.rs +++ b/node/src/main.rs @@ -1,10 +1,10 @@ #![feature(trivial_bounds)] use base64::Engine; -use clap::{command, Parser, Subcommand}; +use clap::{Parser, Subcommand, command}; +use libp2p::PeerId; use libp2p::bytes::BufMut; use libp2p::futures::StreamExt; use libp2p::identity::Keypair; -use libp2p::PeerId; use libp2p::{ gossipsub, kad, mdns, multiaddr::{Multiaddr, Protocol}, @@ -26,10 +26,10 @@ use std::{ }; use tokio::{io, io::AsyncBufReadExt, select}; -use opentelemetry::{trace::TracerProvider as _, KeyValue}; +use opentelemetry::{KeyValue, trace::TracerProvider as _}; use opentelemetry_sdk::{runtime, trace::TracerProvider}; use tracing::log::__private_api::loc; -use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Layer}; +use tracing_subscriber::{EnvFilter, Layer, layer::SubscriberExt, util::SubscriberInitExt}; use zeroize::Zeroizing; @@ -45,7 +45,7 @@ mod rpc_service; use crate::action::GOATMessage; use crate::middleware::behaviour::AllBehavioursEvent; -use anyhow::{bail, Result}; +use anyhow::{Result, bail}; use libp2p::gossipsub::{MessageId, Topic}; use middleware::AllBehaviours; use tokio::time::interval; diff --git a/node/src/metrics_service.rs b/node/src/metrics_service.rs index 4439d8e8..de778daf 100644 --- a/node/src/metrics_service.rs +++ b/node/src/metrics_service.rs @@ -6,15 +6,15 @@ use std::{ use crate::rpc_service::AppState; use axum::middleware::{FromFnLayer, Next}; use axum::{ - extract::Request, extract::State, http::StatusCode, middleware, response::IntoResponse, - routing::get, Router, + Router, extract::Request, extract::State, http::StatusCode, middleware, response::IntoResponse, + routing::get, }; use http::HeaderMap; use libp2p_metrics::Registry; use prometheus_client::encoding::text::encode; use prometheus_client::metrics::counter::Counter; use prometheus_client::metrics::family::Family; -use prometheus_client::metrics::histogram::{exponential_buckets, Histogram}; +use prometheus_client::metrics::histogram::{Histogram, exponential_buckets}; use tokio::net::TcpListener; use tokio::time::Instant; diff --git a/node/src/middleware/behaviour.rs b/node/src/middleware/behaviour.rs index 1a7cfcdf..bd24e72c 100644 --- a/node/src/middleware/behaviour.rs +++ b/node/src/middleware/behaviour.rs @@ -2,7 +2,7 @@ use libp2p::identity::Keypair; use libp2p::{ gossipsub, kad, - kad::{store::MemoryStore, Mode}, + kad::{Mode, store::MemoryStore}, mdns, noise, swarm::{StreamProtocol, SwarmEvent}, tcp, yamux, diff --git a/node/src/rpc_service/handler/bitvm2_handler.rs b/node/src/rpc_service/handler/bitvm2_handler.rs index f4ec04e3..d21c70b6 100644 --- a/node/src/rpc_service/handler/bitvm2_handler.rs +++ b/node/src/rpc_service/handler/bitvm2_handler.rs @@ -1,8 +1,8 @@ use crate::rpc_service::bitvm2::*; use crate::rpc_service::node::ALIVE_TIME_JUDGE_THRESHOLD; -use crate::rpc_service::{current_time_secs, AppState}; -use axum::extract::{Path, Query, State}; +use crate::rpc_service::{AppState, current_time_secs}; use axum::Json; +use axum::extract::{Path, Query, State}; use bitcoin::Txid; use esplora_client::AsyncClient; use http::StatusCode; diff --git a/node/src/rpc_service/handler/node_handler.rs b/node/src/rpc_service/handler/node_handler.rs index ecf80f28..0450696f 100644 --- a/node/src/rpc_service/handler/node_handler.rs +++ b/node/src/rpc_service/handler/node_handler.rs @@ -1,14 +1,14 @@ use crate::rpc_service::node::{ - NodeDesc, NodeListResponse, NodeOverViewResponse, NodeQueryParams, UpdateOrInsertNodeRequest, - ALIVE_TIME_JUDGE_THRESHOLD, + ALIVE_TIME_JUDGE_THRESHOLD, NodeDesc, NodeListResponse, NodeOverViewResponse, NodeQueryParams, + UpdateOrInsertNodeRequest, }; -use crate::rpc_service::{current_time_secs, AppState}; -use axum::extract::{Path, Query, State}; +use crate::rpc_service::{AppState, current_time_secs}; use axum::Json; +use axum::extract::{Path, Query, State}; use http::StatusCode; use std::sync::Arc; use std::time::UNIX_EPOCH; -use store::{Node, NODE_STATUS_OFFLINE, NODE_STATUS_ONLINE}; +use store::{NODE_STATUS_OFFLINE, NODE_STATUS_ONLINE, Node}; #[axum::debug_handler] pub async fn create_node( diff --git a/node/src/rpc_service/mod.rs b/node/src/rpc_service/mod.rs index 6882f99a..089ec698 100644 --- a/node/src/rpc_service/mod.rs +++ b/node/src/rpc_service/mod.rs @@ -5,7 +5,7 @@ use std::str::FromStr; mod handler; mod node; -use crate::metrics_service::{metrics_handler, metrics_middleware, MetricsState}; +use crate::metrics_service::{MetricsState, metrics_handler, metrics_middleware}; use crate::rpc_service::handler::{bitvm2_handler::*, node_handler::*}; use axum::body::Body; use axum::extract::Request; @@ -13,15 +13,14 @@ use axum::middleware::Next; use axum::response::Response; use axum::routing::put; use axum::{ - middleware, + Router, middleware, routing::{get, post}, - Router, }; use bitcoin::Network; use bitvm2_lib::actors::Actor; use client::chain::chain_adaptor::GoatNetwork; use client::client::BitVM2Client; -use http::{HeaderMap, StatusCode}; +use http::{HeaderMap, Method, StatusCode}; use http_body_util::BodyExt; use prometheus_client::registry::Registry; use std::sync::{Arc, Mutex}; @@ -29,8 +28,10 @@ use std::time::{Duration, UNIX_EPOCH}; use store::localdb::LocalDB; use tokio::net::TcpListener; use tower_http::classify::ServerErrorsFailureClass; +use tower_http::cors::{CorsLayer, Any}; use tower_http::trace::{DefaultMakeSpan, TraceLayer}; use tracing::Level; +use crate::env::get_bitvm2_client_config; #[inline(always)] pub fn current_time_secs() -> i64 { @@ -51,7 +52,7 @@ impl AppState { registry: Arc>, ) -> anyhow::Result> { let bitvm2_client = - BitVM2Client::new(db_path, None, Network::Testnet, GoatNetwork::Test, None).await; + BitVM2Client::new(db_path, None, Network::Testnet, GoatNetwork::Test, get_bitvm2_client_config()).await; let metrics_state = MetricsState::new(registry); let actor = Actor::from_str(std::env::var("ACTOR").unwrap_or("Challenger".to_string()).as_str()) @@ -114,6 +115,10 @@ pub(crate) async fn serve( .route("/v1/graphs/presign_check", post(graph_presign_check)) .route("/metrics", get(metrics_handler)) .layer(middleware::from_fn(print_req_and_resp_detail)) + .layer(CorsLayer::new() + .allow_headers(Any) + .allow_origin(Any) + .allow_methods(vec![Method::GET, Method::POST, Method::PUT, Method::DELETE, Method::OPTIONS])) .layer( TraceLayer::new_for_http() .make_span_with(DefaultMakeSpan::new().level(Level::INFO))