From f0aec42305a626e25edc510a65bbed1a39fbe81b Mon Sep 17 00:00:00 2001 From: bennyhodl Date: Fri, 6 Sep 2024 15:23:31 -0400 Subject: [PATCH] Update to Bitcoin 32 --- bitcoin-rpc-provider/Cargo.toml | 8 +- bitcoin-rpc-provider/src/lib.rs | 54 ++-- bitcoin-test-utils/Cargo.toml | 6 +- dlc-manager/Cargo.toml | 20 +- dlc-manager/src/chain_monitor.rs | 6 +- dlc-manager/src/channel_updater.rs | 82 +++--- dlc-manager/src/contract/accepted_contract.rs | 6 +- dlc-manager/src/contract/contract_info.rs | 7 +- dlc-manager/src/contract/contract_input.rs | 4 +- dlc-manager/src/contract/enum_descriptor.rs | 7 +- dlc-manager/src/contract_updater.rs | 30 ++- dlc-manager/src/conversion_utils.rs | 8 +- dlc-manager/src/error.rs | 10 + dlc-manager/src/lib.rs | 10 +- dlc-manager/src/manager.rs | 52 ++-- dlc-manager/src/utils.rs | 8 +- dlc-messages/Cargo.toml | 16 +- dlc-messages/src/lib.rs | 4 +- dlc-messages/src/message_handler.rs | 21 +- dlc-messages/src/oracle_msgs.rs | 23 +- dlc-messages/src/ser_impls.rs | 38 ++- dlc-sled-storage-provider/Cargo.toml | 8 +- dlc-sled-storage-provider/src/lib.rs | 14 +- dlc-trie/Cargo.toml | 12 +- dlc/Cargo.toml | 19 +- dlc/src/channel/mod.rs | 75 +++--- dlc/src/lib.rs | 116 +++++---- dlc/src/secp_utils.rs | 22 +- dlc/src/util.rs | 31 +-- electrs-blockchain-provider/Cargo.toml | 6 +- electrs-blockchain-provider/src/lib.rs | 26 +- fuzz/Cargo.toml | 2 +- mocks/Cargo.toml | 6 +- mocks/src/mock_blockchain.rs | 4 +- mocks/src/mock_oracle_provider.rs | 18 +- mocks/src/mock_wallet.rs | 25 +- p2pd-oracle-client/Cargo.toml | 2 +- p2pd-oracle-client/src/lib.rs | 4 +- sample/Cargo.toml | 6 +- sample/src/cli.rs | 16 +- sample/src/disk.rs | 3 +- simple-wallet/Cargo.toml | 10 +- simple-wallet/src/lib.rs | 233 +++--------------- 43 files changed, 490 insertions(+), 588 deletions(-) diff --git a/bitcoin-rpc-provider/Cargo.toml b/bitcoin-rpc-provider/Cargo.toml index 2796eb2d..18174438 100644 --- a/bitcoin-rpc-provider/Cargo.toml +++ b/bitcoin-rpc-provider/Cargo.toml @@ -5,12 +5,12 @@ name = "bitcoin-rpc-provider" version = "0.1.0" [dependencies] -bitcoin = {version = "0.30.2"} -bitcoincore-rpc = {version = "0.17.0"} -bitcoincore-rpc-json = {version = "0.17.0"} +bitcoin = {version = "0.32.2"} +bitcoincore-rpc = {version = "0.19.0"} +bitcoincore-rpc-json = {version = "0.19.0"} dlc-manager = {path = "../dlc-manager"} hex = { package = "hex-conservative", version = "0.1" } -lightning = { version = "0.0.121" } +lightning = { version = "0.0.124" } log = "0.4.14" rust-bitcoin-coin-selection = { version = "0.1.0", git = "https://github.com/p2pderivatives/rust-bitcoin-coin-selection", rev = "405451929568422f7df809e35d6ad8f36fccce90", features = ["rand"] } simple-wallet = {path = "../simple-wallet"} diff --git a/bitcoin-rpc-provider/src/lib.rs b/bitcoin-rpc-provider/src/lib.rs index 9f44be59..7fa1c687 100644 --- a/bitcoin-rpc-provider/src/lib.rs +++ b/bitcoin-rpc-provider/src/lib.rs @@ -8,13 +8,11 @@ use std::time::Duration; use bitcoin::address::NetworkUnchecked; use bitcoin::consensus::encode::Error as EncodeError; use bitcoin::hashes::serde; -use bitcoin::psbt::PartiallySignedTransaction; +use bitcoin::psbt::Psbt; use bitcoin::secp256k1::rand::thread_rng; -use bitcoin::secp256k1::{PublicKey, SecretKey}; -use bitcoin::{ - consensus::Decodable, network::constants::Network, Amount, PrivateKey, Transaction, Txid, -}; -use bitcoin::{Address, OutPoint, ScriptBuf, TxOut}; +use bitcoin::secp256k1::SecretKey; +use bitcoin::{consensus::Decodable, Network, PrivateKey, Transaction, Txid}; +use bitcoin::{secp256k1::PublicKey, Address, OutPoint, ScriptBuf, TxOut}; use bitcoincore_rpc::jsonrpc::serde_json; use bitcoincore_rpc::jsonrpc::serde_json::Value; use bitcoincore_rpc::{json, Auth, Client, RpcApi}; @@ -106,7 +104,7 @@ impl BitcoinCoreProvider { pub fn new_from_rpc_client(rpc_client: Client) -> Self { let client = Arc::new(Mutex::new(rpc_client)); let mut fees: HashMap = HashMap::with_capacity(7); - fees.insert(ConfirmationTarget::OnChainSweep, AtomicU32::new(5000)); + fees.insert(ConfirmationTarget::UrgentOnChainSweep, AtomicU32::new(5000)); fees.insert( ConfirmationTarget::MinAllowedAnchorChannelRemoteFee, AtomicU32::new(MIN_FEERATE), @@ -155,7 +153,7 @@ struct UtxoWrap(Utxo); impl rust_bitcoin_coin_selection::Utxo for UtxoWrap { fn get_value(&self) -> u64 { - self.0.tx_out.value + self.0.tx_out.value.to_sat() } } @@ -206,7 +204,7 @@ impl ContractSignerProvider for BitcoinCoreProvider { .import_private_key( &PrivateKey { compressed: true, - network, + network: network.into(), inner: sk, }, Some(&keys_id.to_lower_hex_string()), @@ -219,12 +217,8 @@ impl ContractSignerProvider for BitcoinCoreProvider { } fn get_secret_key_for_pubkey(&self, pubkey: &PublicKey) -> Result { - let b_pubkey = bitcoin::PublicKey { - compressed: true, - inner: *pubkey, - }; - let address = - Address::p2wpkh(&b_pubkey, self.get_network()?).or(Err(Error::BitcoinError))?; + let b_pubkey = bitcoin::CompressedPublicKey(*pubkey); + let address = Address::p2wpkh(&b_pubkey, self.get_network()?); let pk = self .client @@ -244,7 +238,7 @@ impl ContractSignerProvider for BitcoinCoreProvider { .import_private_key( &PrivateKey { compressed: true, - network, + network: network.into(), inner: sk, }, None, @@ -296,7 +290,7 @@ impl Wallet for BitcoinCoreProvider { .map(|x| { Ok(UtxoWrap(Utxo { tx_out: TxOut { - value: x.amount.to_sat(), + value: x.amount, script_pubkey: x.script_pub_key.clone(), }, outpoint: OutPoint { @@ -338,11 +332,7 @@ impl Wallet for BitcoinCoreProvider { .map_err(rpc_err_to_manager_err) } - fn sign_psbt_input( - &self, - psbt: &mut PartiallySignedTransaction, - input_index: usize, - ) -> Result<(), ManagerError> { + fn sign_psbt_input(&self, psbt: &mut Psbt, input_index: usize) -> Result<(), ManagerError> { let outpoint = &psbt.unsigned_tx.input[input_index].previous_output; let tx_out = if let Some(input) = psbt.inputs.get(input_index) { if let Some(wit_utxo) = &input.witness_utxo { @@ -370,7 +360,7 @@ impl Wallet for BitcoinCoreProvider { vout: outpoint.vout, script_pub_key: tx_out.script_pubkey.clone(), redeem_script, - amount: Some(Amount::from_sat(tx_out.value)), + amount: Some(tx_out.value), }; let sign_result = self @@ -417,25 +407,13 @@ impl Blockchain for BitcoinCoreProvider { } fn get_network(&self) -> Result { - let network = match self + let network = self .client .lock() .unwrap() .get_blockchain_info() .map_err(rpc_err_to_manager_err)? - .chain - .as_ref() - { - "main" => Network::Bitcoin, - "test" => Network::Testnet, - "regtest" => Network::Regtest, - "signet" => Network::Signet, - _ => { - return Err(ManagerError::BlockchainError( - "Unknown Bitcoin network".to_string(), - )) - } - }; + .chain; Ok(network) } @@ -547,7 +525,7 @@ fn poll_for_fee_estimates( }; match query_fee_estimate(&client, 6, EstimateMode::Conservative) { Ok(fee_rate) => { - fees.get(&ConfirmationTarget::OnChainSweep) + fees.get(&ConfirmationTarget::UrgentOnChainSweep) .unwrap() .store(fee_rate, Ordering::Release); } diff --git a/bitcoin-test-utils/Cargo.toml b/bitcoin-test-utils/Cargo.toml index a2cde5b9..08244cae 100644 --- a/bitcoin-test-utils/Cargo.toml +++ b/bitcoin-test-utils/Cargo.toml @@ -4,6 +4,6 @@ name = "bitcoin-test-utils" version = "0.1.0" [dependencies] -bitcoin = { version = "0.30.2", default-features = false } -bitcoincore-rpc = {version = "0.17"} -bitcoincore-rpc-json = {version = "0.17"} +bitcoin = { version = "0.32.2", default-features = false } +bitcoincore-rpc = {version = "0.19"} +bitcoincore-rpc-json = {version = "0.19"} diff --git a/dlc-manager/Cargo.toml b/dlc-manager/Cargo.toml index 90fbf204..d14423d1 100644 --- a/dlc-manager/Cargo.toml +++ b/dlc-manager/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://github.com/p2pderivatives/rust-dlc" license-file = "../LICENSE" name = "dlc-manager" repository = "https://github.com/p2pderivatives/rust-dlc/tree/master/dlc-manager" -version = "0.5.0" +version = "0.6.0" [features] default = ["std"] @@ -17,29 +17,29 @@ use-serde = ["serde", "dlc/use-serde", "dlc-messages/use-serde", "dlc-trie/use-s [dependencies] async-trait = "0.1.50" -bitcoin = { version = "0.30.2", default-features = false } -dlc = { version = "0.5.0", default-features = false, path = "../dlc" } -dlc-messages = { version = "0.5.0", default-features = false, path = "../dlc-messages" } -dlc-trie = { version = "0.5.0", default-features = false, path = "../dlc-trie" } +bitcoin = { version = "0.32.2", default-features = false } +dlc = { version = "0.6.0", default-features = false, path = "../dlc" } +dlc-messages = { version = "0.6.0", default-features = false, path = "../dlc-messages" } +dlc-trie = { version = "0.6.0", default-features = false, path = "../dlc-trie" } hex = { package = "hex-conservative", version = "0.1" } -lightning = { version = "0.0.121", default-features = false, features = ["grind_signatures"] } +lightning = { version = "0.0.124", default-features = false, features = ["grind_signatures"] } log = "0.4.14" rand_chacha = {version = "0.3.1", optional = true} -secp256k1-zkp = {version = "0.9.2"} +secp256k1-zkp = {version = "0.11.0"} serde = {version = "1.0", optional = true} [dev-dependencies] bitcoin-rpc-provider = {path = "../bitcoin-rpc-provider"} bitcoin-test-utils = {path = "../bitcoin-test-utils"} -bitcoincore-rpc = {version = "0.17"} -bitcoincore-rpc-json = {version = "0.17"} +bitcoincore-rpc = {version = "0.19"} +bitcoincore-rpc-json = {version = "0.19"} criterion = "0.4.0" dlc-manager = { path = ".", default-features = false, features = ["use-serde"] } dlc-messages = { path = "../dlc-messages", default-features = false, features = ["serde"] } electrs-blockchain-provider = {path = "../electrs-blockchain-provider"} env_logger = "0.9.1" mocks = {path = "../mocks"} -secp256k1-zkp = {version = "0.9.2", features = ["bitcoin_hashes", "rand", "rand-std", "global-context", "serde"]} +secp256k1-zkp = {version = "0.11.0", features = ["hashes", "rand", "rand-std", "global-context", "serde"]} serde = "1.0" serde_json = "1.0" simple-wallet = {path = "../simple-wallet"} diff --git a/dlc-manager/src/chain_monitor.rs b/dlc-manager/src/chain_monitor.rs index 7760d15e..5344da2c 100644 --- a/dlc-manager/src/chain_monitor.rs +++ b/dlc-manager/src/chain_monitor.rs @@ -132,7 +132,7 @@ impl ChainMonitor { assert_eq!(self.last_height + 1, height); for tx in block.txdata.iter() { - if let Some(state) = self.watched_tx.get_mut(&tx.txid()) { + if let Some(state) = self.watched_tx.get_mut(&tx.compute_txid()) { state.confirm(tx.clone()); } @@ -190,7 +190,7 @@ impl WatchState { WatchState::Registered { ref channel_info } => { log::info!( "Transaction {} confirmed: {channel_info:?}", - transaction.txid() + transaction.compute_txid() ); *self = WatchState::Confirmed { @@ -204,7 +204,7 @@ impl WatchState { } => { log::error!( "Transaction {} already confirmed: {channel_info:?}", - transaction.txid() + transaction.compute_txid() ); } } diff --git a/dlc-manager/src/channel_updater.rs b/dlc-manager/src/channel_updater.rs index 0ebda631..e55d475c 100644 --- a/dlc-manager/src/channel_updater.rs +++ b/dlc-manager/src/channel_updater.rs @@ -220,7 +220,7 @@ where let own_secret_key = derive_private_key(secp, &first_per_update_point, &own_base_secret_key); let channel_id = crate::utils::compute_id( - dlc_transactions.fund.txid(), + dlc_transactions.fund.compute_txid(), dlc_transactions.get_fund_output_index() as u16, &offered_channel.temporary_channel_id, ); @@ -228,7 +228,7 @@ where let buffer_adaptor_signature = get_tx_adaptor_signature( secp, &buffer_transaction, - dlc_transactions.get_fund_output().value, + dlc_transactions.get_fund_output().value.to_sat(), &dlc_transactions.funding_script_pubkey, &signer.get_secret_key()?, &offer_revoke_params.publish_pk.inner, @@ -240,7 +240,7 @@ where &accept_params, &funding_inputs, &own_secret_key, - buffer_transaction.output[0].value, + buffer_transaction.output[0].value.to_sat(), Some(&buffer_script_pubkey), &dlc_transactions, )?; @@ -349,7 +349,7 @@ where )?; let channel_id = crate::utils::compute_id( - dlc_transactions.fund.txid(), + dlc_transactions.fund.compute_txid(), dlc_transactions.get_fund_output_index() as u16, &offered_channel.temporary_channel_id, ); @@ -363,7 +363,7 @@ where &accept_channel.funding_inputs, &accept_channel.refund_signature, &accept_cet_adaptor_signatures, - buffer_transaction.output[0].value, + buffer_transaction.output[0].value.to_sat(), wallet, &offer_own_sk, Some(&buffer_script_pubkey), @@ -375,7 +375,7 @@ where verify_tx_adaptor_signature( secp, &buffer_transaction, - dlc_transactions.get_fund_output().value, + dlc_transactions.get_fund_output().value.to_sat(), &dlc_transactions.funding_script_pubkey, &signed_contract.accepted_contract.accept_params.fund_pubkey, &offer_revoke_params.publish_pk.inner, @@ -385,14 +385,14 @@ where let own_buffer_adaptor_signature = get_tx_adaptor_signature( secp, &buffer_transaction, - dlc_transactions.get_fund_output().value, + dlc_transactions.get_fund_output().value.to_sat(), &dlc_transactions.funding_script_pubkey, &offer_fund_sk.get_secret_key()?, &accept_revoke_params.publish_pk.inner, )?; chain_monitor.lock().unwrap().add_tx( - buffer_transaction.txid(), + buffer_transaction.compute_txid(), ChannelInfo { channel_id, tx_type: TxType::BufferTx, @@ -471,7 +471,11 @@ where verify_tx_adaptor_signature( secp, &accepted_channel.buffer_transaction, - accepted_contract.dlc_transactions.get_fund_output().value, + accepted_contract + .dlc_transactions + .get_fund_output() + .value + .to_sat(), &accepted_contract.dlc_transactions.funding_script_pubkey, &accepted_contract.offered_contract.offer_params.fund_pubkey, &own_publish_pk, @@ -486,7 +490,7 @@ where &sign_channel.refund_signature, &cet_adaptor_signatures, &sign_channel.funding_signatures, - accepted_channel.buffer_transaction.output[0].value, + accepted_channel.buffer_transaction.output[0].value.to_sat(), Some(&accepted_channel.buffer_script_pubkey), Some(counter_own_pk), wallet, @@ -494,7 +498,7 @@ where )?; chain_monitor.lock().unwrap().add_tx( - accepted_channel.buffer_transaction.txid(), + accepted_channel.buffer_transaction.compute_txid(), ChannelInfo { channel_id: accepted_channel.channel_id, tx_type: TxType::BufferTx, @@ -714,7 +718,7 @@ where )?; chain_monitor.lock().unwrap().add_tx( - settle_tx.txid(), + settle_tx.compute_txid(), ChannelInfo { channel_id: channel.channel_id, tx_type: TxType::SettleTx, @@ -808,7 +812,7 @@ where )?; chain_monitor.lock().unwrap().add_tx( - settle_tx.txid(), + settle_tx.compute_txid(), ChannelInfo { channel_id: channel.channel_id, tx_type: TxType::SettleTx, @@ -905,7 +909,9 @@ where verify_tx_adaptor_signature( secp, settle_tx, - channel.fund_tx.output[channel.fund_output_index].value, + channel.fund_tx.output[channel.fund_output_index] + .value + .to_sat(), &channel.fund_script_pubkey, &channel.counter_params.fund_pubkey, &accept_revoke_params.publish_pk.inner, @@ -1307,7 +1313,7 @@ where &signed_channel.own_params, &[], &own_secret_key, - buffer_transaction.output[0].value, + buffer_transaction.output[0].value.to_sat(), Some(&buffer_script_pubkey), &dlc_transactions, )?; @@ -1411,7 +1417,7 @@ where &[], &renew_accept.refund_signature, &cet_adaptor_signatures, - buffer_transaction.output[0].value, + buffer_transaction.output[0].value.to_sat(), wallet, &offer_own_sk, Some(&buffer_script_pubkey), @@ -1423,7 +1429,7 @@ where let own_buffer_adaptor_signature = get_tx_adaptor_signature( secp, &buffer_transaction, - dlc_transactions.get_fund_output().value, + dlc_transactions.get_fund_output().value.to_sat(), &dlc_transactions.funding_script_pubkey, &contract_signer.get_secret_key()?, &accept_revoke_params.publish_pk.inner, @@ -1504,7 +1510,9 @@ where verify_tx_adaptor_signature( secp, buffer_transaction, - signed_channel.fund_tx.output[signed_channel.fund_output_index].value, + signed_channel.fund_tx.output[signed_channel.fund_output_index] + .value + .to_sat(), &signed_channel.fund_script_pubkey, counter_buffer_own_pk, &own_publish_pk, @@ -1520,7 +1528,7 @@ where &FundingSignatures { funding_signatures: Vec::new(), }, - buffer_transaction.output[0].value, + buffer_transaction.output[0].value.to_sat(), Some(buffer_script_pubkey), Some(counter_own_pk), wallet, @@ -1551,7 +1559,7 @@ where let buffer_adaptor_signature = get_tx_adaptor_signature( secp, buffer_transaction, - buffer_input_value, + buffer_input_value.to_sat(), &signed_channel.fund_script_pubkey, &own_fund_sk, &offer_revoke_params.publish_pk.inner, @@ -1561,7 +1569,7 @@ where signed_channel.own_params.collateral + signed_channel.counter_params.collateral; chain_monitor.lock().unwrap().add_tx( - buffer_transaction.txid(), + buffer_transaction.compute_txid(), ChannelInfo { channel_id: signed_channel.channel_id, tx_type: TxType::BufferTx, @@ -1630,7 +1638,7 @@ where verify_tx_adaptor_signature( secp, buffer_transaction, - buffer_input_value, + buffer_input_value.to_sat(), &signed_channel.fund_script_pubkey, counter_buffer_own_pk, &offer_revoke_params.publish_pk.inner, @@ -1795,10 +1803,10 @@ where &signed_channel.counter_params, counter_payout, OutPoint { - txid: signed_channel.fund_tx.txid(), + txid: signed_channel.fund_tx.compute_txid(), vout: signed_channel.fund_output_index as u32, }, - fund_output_value, + fund_output_value.to_sat(), ); let keys_id = signed_channel @@ -1811,7 +1819,7 @@ where &close_tx, 0, &signed_channel.fund_script_pubkey, - fund_output_value, + fund_output_value.to_sat(), &contract_signer.get_secret_key()?, )?; @@ -1870,10 +1878,10 @@ where &signed_channel.own_params, close_offer.counter_payout, OutPoint { - txid: signed_channel.fund_tx.txid(), + txid: signed_channel.fund_tx.compute_txid(), vout: signed_channel.fund_output_index as u32, }, - fund_output_value, + fund_output_value.to_sat(), ); let mut state = SignedChannelState::CollaborativeCloseOffered { @@ -1922,7 +1930,7 @@ where &signed_channel.counter_params.fund_pubkey, &own_fund_sk, &signed_channel.fund_script_pubkey, - fund_out_amount, + fund_out_amount.to_sat(), 0, )?; @@ -1961,7 +1969,7 @@ fn get_settle_tx_and_adaptor_sig( let fund_tx_in = TxIn { previous_output: bitcoin::OutPoint { - txid: fund_tx.txid(), + txid: fund_tx.compute_txid(), vout: fund_vout as u32, }, script_sig: ScriptBuf::new(), @@ -1989,7 +1997,7 @@ fn get_settle_tx_and_adaptor_sig( accept_payout, csv_timelock, lock_time, - fund_tx.output[fund_vout].value, + fund_tx.output[fund_vout].value.to_sat(), fee_rate_per_vb, )?; @@ -1997,7 +2005,7 @@ fn get_settle_tx_and_adaptor_sig( verify_tx_adaptor_signature( secp, &settle_tx, - fund_tx.output[fund_vout].value, + fund_tx.output[fund_vout].value.to_sat(), funding_script_pubkey, &fund_pk, &offer_revoke_params.publish_pk.inner, @@ -2014,7 +2022,7 @@ fn get_settle_tx_and_adaptor_sig( let settle_adaptor_signature = dlc::channel::get_tx_adaptor_signature( secp, &settle_tx, - fund_tx.output[fund_vout].value, + fund_tx.output[fund_vout].value.to_sat(), funding_script_pubkey, own_fund_sk, &counter_pk, @@ -2087,7 +2095,9 @@ where &signed_channel.counter_params.fund_pubkey, &buffer_input_sk, &signed_channel.fund_script_pubkey, - signed_channel.fund_tx.output[signed_channel.fund_output_index].value, + signed_channel.fund_tx.output[signed_channel.fund_output_index] + .value + .to_sat(), 0, )?; @@ -2193,7 +2203,7 @@ where dlc::channel::sign_cet( secp, &mut cet, - buffer_transaction.output[0].value, + buffer_transaction.output[0].value.to_sat(), &offer_revoke_params, &accept_revoke_params, &own_sk, @@ -2254,7 +2264,9 @@ where &signed_channel.counter_params.fund_pubkey, &fund_sk, &signed_channel.fund_script_pubkey, - signed_channel.fund_tx.output[signed_channel.fund_output_index].value, + signed_channel.fund_tx.output[signed_channel.fund_output_index] + .value + .to_sat(), 0, )?; diff --git a/dlc-manager/src/contract/accepted_contract.rs b/dlc-manager/src/contract/accepted_contract.rs index 1549ce98..6e507170 100644 --- a/dlc-manager/src/contract/accepted_contract.rs +++ b/dlc-manager/src/contract/accepted_contract.rs @@ -36,7 +36,7 @@ impl AcceptedContract { /// pub fn get_contract_id(&self) -> [u8; 32] { crate::utils::compute_id( - self.dlc_transactions.fund.txid(), + self.dlc_transactions.fund.compute_txid(), self.dlc_transactions.get_fund_output_index() as u16, &self.offered_contract.id, ) @@ -89,7 +89,7 @@ impl AcceptedContract { .iter() .find_map(|x| { if &x.script_pubkey == v0_witness_payout_script { - Some(x.value) + Some(x.value.to_sat()) } else { None } @@ -101,7 +101,7 @@ impl AcceptedContract { #[cfg(test)] mod tests { - use std::io::Cursor; + use lightning::io::Cursor; use lightning::util::ser::Readable; diff --git a/dlc-manager/src/contract/contract_info.rs b/dlc-manager/src/contract/contract_info.rs index 887c6f21..dada1dcf 100644 --- a/dlc-manager/src/contract/contract_info.rs +++ b/dlc-manager/src/contract/contract_info.rs @@ -4,6 +4,7 @@ use super::AdaptorInfo; use super::ContractDescriptor; use crate::error::Error; use crate::ContractSigner; +use bitcoin::hashes::Hash; use bitcoin::{Script, Transaction}; use dlc::{OracleInfo, Payout}; use dlc_messages::oracle_msgs::{EventDescriptor, OracleAnnouncement}; @@ -294,9 +295,9 @@ impl ContractInfo { for nonce in nonces { let mut points = Vec::with_capacity(base); for j in 0..base { - let msg = Message::from_hashed_data::( - j.to_string().as_bytes(), - ); + let hash = + sha256::Hash::hash(j.to_string().as_bytes()).to_byte_array(); + let msg = Message::from_digest(hash); let sig_point = dlc::secp_utils::schnorrsig_compute_sig_point( secp, pubkey, nonce, &msg, )?; diff --git a/dlc-manager/src/contract/contract_input.rs b/dlc-manager/src/contract/contract_input.rs index 7b7f9efd..ad5ed1af 100644 --- a/dlc-manager/src/contract/contract_input.rs +++ b/dlc-manager/src/contract/contract_input.rs @@ -104,7 +104,7 @@ impl ContractInput { #[cfg(test)] mod tests { use dlc::{EnumerationPayout, Payout}; - use secp256k1_zkp::{KeyPair, SecretKey, SECP256K1}; + use secp256k1_zkp::{Keypair, SecretKey, SECP256K1}; use crate::contract::enum_descriptor::EnumDescriptor; @@ -136,7 +136,7 @@ mod tests { }), oracles: OracleInput { public_keys: vec![ - XOnlyPublicKey::from_keypair(&KeyPair::from_secret_key( + XOnlyPublicKey::from_keypair(&Keypair::from_secret_key( SECP256K1, &SecretKey::from_slice(&secp256k1_zkp::constants::ONE).unwrap(), )) diff --git a/dlc-manager/src/contract/enum_descriptor.rs b/dlc-manager/src/contract/enum_descriptor.rs index a90abb16..7e007715 100644 --- a/dlc-manager/src/contract/enum_descriptor.rs +++ b/dlc-manager/src/contract/enum_descriptor.rs @@ -4,6 +4,7 @@ use super::contract_info::OracleIndexAndPrefixLength; use super::utils::{get_majority_combination, unordered_equal}; use super::AdaptorInfo; use crate::error::Error; +use bitcoin::hashes::Hash; use bitcoin::{Script, Transaction}; use dlc::OracleInfo; use dlc::{EnumerationPayout, Payout}; @@ -240,9 +241,9 @@ impl EnumDescriptor { .outcome_payouts .iter() .map(|x| { - let message = vec![Message::from_hashed_data::< - secp256k1_zkp::hashes::sha256::Hash, - >(x.outcome.as_bytes())]; + let hash = + secp256k1_zkp::hashes::sha256::Hash::hash(x.outcome.as_bytes()).to_byte_array(); + let message = vec![Message::from_digest(hash)]; std::iter::repeat(message).take(threshold).collect() }) .collect(); diff --git a/dlc-manager/src/contract_updater.rs b/dlc-manager/src/contract_updater.rs index 2f42a49c..939da0c3 100644 --- a/dlc-manager/src/contract_updater.rs +++ b/dlc-manager/src/contract_updater.rs @@ -2,7 +2,7 @@ use std::ops::Deref; -use bitcoin::psbt::PartiallySignedTransaction; +use bitcoin::psbt::Psbt; use bitcoin::{consensus::Decodable, Script, Transaction, Witness}; use dlc::{DlcTransactions, PartyParams}; use dlc_messages::FundingInput; @@ -120,7 +120,7 @@ where &accept_params, &funding_inputs, &signer.get_secret_key()?, - fund_output_value, + fund_output_value.to_sat(), None, &dlc_transactions, )?; @@ -282,7 +282,7 @@ where &accept_msg.funding_inputs, &accept_msg.refund_signature, &cet_adaptor_signatures, - fund_output_value, + fund_output_value.to_sat(), wallet, &signer, None, @@ -296,10 +296,7 @@ where Ok((signed_contract, signed_msg)) } -fn populate_psbt( - psbt: &mut PartiallySignedTransaction, - all_funding_inputs: &[&FundingInput], -) -> Result<(), Error> { +fn populate_psbt(psbt: &mut Psbt, all_funding_inputs: &[&FundingInput]) -> Result<(), Error> { // add witness utxo to fund_psbt for all inputs for (input_index, x) in all_funding_inputs.iter().enumerate() { let tx = Transaction::consensus_decode(&mut x.prev_tx.as_slice()).map_err(|_| { @@ -344,7 +341,7 @@ where funding_script_pubkey, } = dlc_transactions; - let mut fund_psbt = PartiallySignedTransaction::from_unsigned_tx(fund.clone()) + let mut fund_psbt = Psbt::from_unsigned_tx(fund.clone()) .map_err(|_| Error::InvalidState("Tried to create PSBT from signed tx".to_string()))?; let mut cets = cets.clone(); @@ -536,7 +533,11 @@ where &sign_msg.refund_signature, &cet_adaptor_signatures, &sign_msg.funding_signatures, - accepted_contract.dlc_transactions.get_fund_output().value, + accepted_contract + .dlc_transactions + .get_fund_output() + .value + .to_sat(), None, None, wallet, @@ -595,7 +596,7 @@ where } let fund_tx = &accepted_contract.dlc_transactions.fund; - let mut fund_psbt = PartiallySignedTransaction::from_unsigned_tx(fund_tx.clone()) + let mut fund_psbt = Psbt::from_unsigned_tx(fund_tx.clone()) .map_err(|_| Error::InvalidState("Tried to create PSBT from signed tx".to_string()))?; // get all funding inputs @@ -655,7 +656,9 @@ where channel_id, }; - Ok((signed_contract, fund_psbt.extract_tx())) + let transaction = fund_psbt.extract_tx_unchecked_fee_rate(); + + Ok((signed_contract, transaction)) } /// Signs and return the CET that can be used to close the given contract. @@ -708,7 +711,8 @@ where .accepted_contract .dlc_transactions .get_fund_output() - .value, + .value + .to_sat(), )?; Ok(cet) @@ -748,7 +752,7 @@ where other_fund_pubkey, &fund_priv_key, funding_script_pubkey, - fund_output_value, + fund_output_value.to_sat(), 0, )?; Ok(refund) diff --git a/dlc-manager/src/conversion_utils.rs b/dlc-manager/src/conversion_utils.rs index 8642935b..b7f15202 100644 --- a/dlc-manager/src/conversion_utils.rs +++ b/dlc-manager/src/conversion_utils.rs @@ -9,7 +9,7 @@ use crate::payout_curve::{ HyperbolaPayoutCurvePiece, PayoutFunction, PayoutFunctionPiece, PayoutPoint, PolynomialPayoutCurvePiece, RoundingInterval, RoundingIntervals, }; -use bitcoin::{consensus::encode::Decodable, OutPoint, Transaction}; +use bitcoin::{consensus::encode::Decodable, Amount, OutPoint, Transaction}; use dlc::{EnumerationPayout, Payout, TxInputInfo}; use dlc_messages::oracle_msgs::{ MultiOracleInfo, OracleInfo as SerOracleInfo, OracleParams, SingleOracleInfo, @@ -72,7 +72,7 @@ impl From for Error { pub fn get_tx_input_infos( funding_inputs: &[FundingInput], ) -> Result<(Vec, u64), Error> { - let mut input_amount = 0; + let mut input_amount = Amount::ZERO; let mut inputs = Vec::new(); for fund_input in funding_inputs { @@ -85,7 +85,7 @@ pub fn get_tx_input_infos( input_amount += tx_out.value; inputs.push(TxInputInfo { outpoint: OutPoint { - txid: tx.txid(), + txid: tx.compute_txid(), vout, }, max_witness_len: 107, @@ -94,7 +94,7 @@ pub fn get_tx_input_infos( }); } - Ok((inputs, input_amount)) + Ok((inputs, input_amount.to_sat())) } pub(crate) fn get_contract_info_and_announcements( diff --git a/dlc-manager/src/error.rs b/dlc-manager/src/error.rs index 98409155..9f0ff5c4 100644 --- a/dlc-manager/src/error.rs +++ b/dlc-manager/src/error.rs @@ -9,6 +9,8 @@ pub enum Error { Conversion(crate::conversion_utils::Error), /// An IO error. IOError(lightning::io::Error), + /// Deserialize error + Deserialize(bitcoin::consensus::encode::Error), /// Some invalid parameters were provided. InvalidParameters(String), /// An invalid state was encounter, likely to indicate a bug. @@ -32,6 +34,7 @@ impl fmt::Display for Error { match *self { Error::Conversion(_) => write!(f, "Conversion error"), Error::IOError(_) => write!(f, "IO error"), + Error::Deserialize(ref s) => write!(f, "Deserialize error: {}", s), Error::InvalidState(ref s) => write!(f, "Invalid state: {}", s), Error::InvalidParameters(ref s) => write!(f, "Invalid parameters were provided: {}", s), Error::WalletError(ref e) => write!(f, "Wallet error {}", e), @@ -74,12 +77,19 @@ impl From for Error { } } +impl From for Error { + fn from(e: bitcoin::consensus::encode::Error) -> Self { + Error::Deserialize(e) + } +} + #[cfg(feature = "std")] impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { Error::Conversion(e) => Some(e), Error::IOError(e) => Some(e), + Error::Deserialize(e) => Some(e), Error::InvalidParameters(_) => None, Error::InvalidState(_) => None, Error::WalletError(_) => None, diff --git a/dlc-manager/src/lib.rs b/dlc-manager/src/lib.rs index 524c6951..b5250c00 100644 --- a/dlc-manager/src/lib.rs +++ b/dlc-manager/src/lib.rs @@ -36,7 +36,7 @@ pub mod manager; pub mod payout_curve; mod utils; -use bitcoin::psbt::PartiallySignedTransaction; +use bitcoin::psbt::Psbt; use bitcoin::{Address, Block, OutPoint, ScriptBuf, Transaction, TxOut, Txid}; use chain_monitor::ChainMonitor; use channel::offered_channel::OfferedChannel; @@ -162,11 +162,7 @@ pub trait Wallet { /// Import the provided address. fn import_address(&self, address: &Address) -> Result<(), Error>; /// Signs a transaction input - fn sign_psbt_input( - &self, - psbt: &mut PartiallySignedTransaction, - input_index: usize, - ) -> Result<(), Error>; + fn sign_psbt_input(&self, psbt: &mut Psbt, input_index: usize) -> Result<(), Error>; /// Unlock reserved utxo fn unreserve_utxos(&self, outpoints: &[OutPoint]) -> Result<(), Error>; } @@ -176,7 +172,7 @@ pub trait Blockchain { /// Broadcast the given transaction to the bitcoin network. fn send_transaction(&self, transaction: &Transaction) -> Result<(), Error>; /// Returns the network currently used (mainnet, testnet or regtest). - fn get_network(&self) -> Result; + fn get_network(&self) -> Result; /// Returns the height of the blockchain fn get_blockchain_height(&self) -> Result; /// Returns the block at given height diff --git a/dlc-manager/src/manager.rs b/dlc-manager/src/manager.rs index eb3c0354..9335970d 100644 --- a/dlc-manager/src/manager.rs +++ b/dlc-manager/src/manager.rs @@ -520,7 +520,11 @@ where fn check_signed_contract(&self, contract: &SignedContract) -> Result<(), Error> { let confirmations = self.blockchain.get_transaction_confirmations( - &contract.accepted_contract.dlc_transactions.fund.txid(), + &contract + .accepted_contract + .dlc_transactions + .fund + .compute_txid(), )?; if confirmations >= NB_CONFIRMATIONS { self.store @@ -721,7 +725,7 @@ where } fn check_preclosed_contract(&self, contract: &PreClosedContract) -> Result<(), Error> { - let broadcasted_txid = contract.signed_cet.txid(); + let broadcasted_txid = contract.signed_cet.compute_txid(); let confirmations = self .blockchain .get_transaction_confirmations(&broadcasted_txid)?; @@ -760,7 +764,7 @@ where ) -> Result { let confirmations = self .blockchain - .get_transaction_confirmations(&signed_cet.txid())?; + .get_transaction_confirmations(&signed_cet.compute_txid())?; if confirmations < 1 { // TODO(tibo): if this fails because another tx is already in @@ -812,7 +816,7 @@ where let refund = accepted_contract.dlc_transactions.refund.clone(); let confirmations = self .blockchain - .get_transaction_confirmations(&refund.txid())?; + .get_transaction_confirmations(&refund.compute_txid())?; if confirmations == 0 { let offer = &contract.accepted_contract.offered_contract; let signer = self.signer_provider.derive_contract_signer(offer.keys_id)?; @@ -850,7 +854,13 @@ where } // check if it is the refund tx (easy case) - if contract.accepted_contract.dlc_transactions.refund.txid() == closing_tx.txid() { + if contract + .accepted_contract + .dlc_transactions + .refund + .compute_txid() + == closing_tx.compute_txid() + { let refunded = Contract::Refunded(contract.clone()); self.store.update_contract(&refunded)?; return Ok(refunded); @@ -1224,7 +1234,7 @@ where )?; self.chain_monitor.lock().unwrap().add_tx( - close_tx.txid(), + close_tx.compute_txid(), ChannelInfo { channel_id: *channel_id, tx_type: TxType::CollaborativeClose, @@ -1296,7 +1306,7 @@ where if self .blockchain - .get_transaction_confirmations(&buffer_tx.txid())? + .get_transaction_confirmations(&buffer_tx.compute_txid())? >= CET_NSEQUENCE { log::info!( @@ -1440,7 +1450,7 @@ where } = &signed_channel.state { self.chain_monitor.lock().unwrap().add_tx( - buffer_transaction.txid(), + buffer_transaction.compute_txid(), ChannelInfo { channel_id: signed_channel.channel_id, tx_type: TxType::BufferTx, @@ -1506,7 +1516,7 @@ where } = &signed_channel.state { self.chain_monitor.lock().unwrap().add_tx( - buffer_transaction.txid(), + buffer_transaction.compute_txid(), ChannelInfo { channel_id: signed_channel.channel_id, tx_type: TxType::BufferTx, @@ -1593,7 +1603,7 @@ where signed_contract_id )?; - let prev_buffer_txid = prev_buffer_tx.txid(); + let prev_buffer_txid = prev_buffer_tx.compute_txid(); let own_buffer_adaptor_signature = *own_buffer_adaptor_signature; let is_offer = *is_offer; let signed_contract_id = *signed_contract_id; @@ -1651,7 +1661,7 @@ where let own_buffer_adaptor_signature = *own_buffer_adaptor_signature; let is_offer = *is_offer; - let buffer_txid = buffer_tx.txid(); + let buffer_txid = buffer_tx.compute_txid(); let signed_contract_id = *signed_contract_id; crate::channel_updater::settle_channel_on_finalize( @@ -1791,7 +1801,7 @@ where is_offer: false, revoked_tx_type: RevokedTxType::Buffer, }, - buffer_transaction.txid(), + buffer_transaction.compute_txid(), Some(closed_contract), ) } @@ -1806,7 +1816,7 @@ where is_offer: false, revoked_tx_type: RevokedTxType::Settle, }, - settle_tx.txid(), + settle_tx.compute_txid(), None, ), s => { @@ -1886,7 +1896,7 @@ where is_offer: false, revoked_tx_type: RevokedTxType::Buffer, }, - buffer_transaction.txid(), + buffer_transaction.compute_txid(), Some(Contract::Closed(closed_contract)), ) } @@ -1901,7 +1911,7 @@ where is_offer: false, revoked_tx_type: RevokedTxType::Settle, }, - settle_tx.txid(), + settle_tx.compute_txid(), None, ), s => { @@ -1930,7 +1940,7 @@ where get_signed_channel_state!(signed_channel, Established, ref buffer_transaction)?; self.chain_monitor.lock().unwrap().add_tx( - buffer_tx.txid(), + buffer_tx.compute_txid(), ChannelInfo { channel_id: signed_channel.channel_id, tx_type: TxType::BufferTx, @@ -2016,7 +2026,7 @@ where &mut funding_input.prev_tx.as_slice(), ) .expect("Transaction Decode Error") - .txid(); + .compute_txid(); let vout = funding_input.prev_tx_vout; OutPoint { txid, vout } }) @@ -2235,7 +2245,7 @@ where }; let fee_rate_per_vb: u64 = (self.fee_estimator.get_est_sat_per_1000_weight( - lightning::chain::chaininterface::ConfirmationTarget::OnChainSweep, + lightning::chain::chaininterface::ConfirmationTarget::UrgentOnChainSweep, ) / 250) .into(); @@ -2278,7 +2288,7 @@ where counter_party: signed_channel.counter_party, temporary_channel_id: signed_channel.temporary_channel_id, channel_id: signed_channel.channel_id, - punish_txid: signed_tx.txid(), + punish_txid: signed_tx.compute_txid(), }); //TODO(tibo): should probably make sure the tx is confirmed somewhere before @@ -2498,7 +2508,7 @@ where self.chain_monitor .lock() .unwrap() - .remove_tx(&buffer_transaction.txid()); + .remove_tx(&buffer_transaction.compute_txid()); self.store .upsert_channel(Channel::Signed(signed_channel), None)?; @@ -2524,7 +2534,7 @@ where if self .blockchain - .get_transaction_confirmations(&settle_tx.txid()) + .get_transaction_confirmations(&settle_tx.compute_txid()) .unwrap_or(0) == 0 { diff --git a/dlc-manager/src/utils.rs b/dlc-manager/src/utils.rs index 7edd8828..f206b4fa 100644 --- a/dlc-manager/src/utils.rs +++ b/dlc-manager/src/utils.rs @@ -1,7 +1,7 @@ //! #Utils use std::ops::Deref; -use bitcoin::{consensus::Encodable, Txid}; +use bitcoin::{consensus::Encodable, Amount, Txid}; use dlc::{PartyParams, TxInputInfo}; use dlc_messages::{ oracle_msgs::{OracleAnnouncement, OracleAttestation}, @@ -117,7 +117,7 @@ where let mut funding_inputs: Vec = Vec::new(); let mut funding_tx_info: Vec = Vec::new(); - let mut total_input = 0; + let mut total_input = Amount::ZERO; for utxo in utxos { let prev_tx = blockchain.get_transaction(&utxo.outpoint.txid)?; let mut writer = Vec::new(); @@ -147,7 +147,7 @@ where payout_serial_id, inputs: funding_tx_info, collateral: own_collateral, - input_amount: total_input, + input_amount: total_input.to_sat(), }; Ok((party_params, funding_inputs)) @@ -236,7 +236,7 @@ mod tests { "81db60dcbef10a2d0cb92cb78400a96ee6a9b6da785d0230bdabf1e18a2d6ffb", ); - let id = compute_id(transaction.txid(), output_index, &temporary_id); + let id = compute_id(transaction.compute_txid(), output_index, &temporary_id); assert_eq!(expected_id, id); } diff --git a/dlc-messages/Cargo.toml b/dlc-messages/Cargo.toml index 3470aaa1..fad8f59c 100644 --- a/dlc-messages/Cargo.toml +++ b/dlc-messages/Cargo.toml @@ -5,24 +5,24 @@ homepage = "https://github.com/p2pderivatives/rust-dlc" license-file = "../LICENSE" name = "dlc-messages" repository = "https://github.com/p2pderivatives/rust-dlc/tree/master/dlc-messages" -version = "0.5.0" +version = "0.6.0" [features] default = ["std"] std = ["dlc/std", "bitcoin/std", "lightning/std"] -no-std = ["bitcoin/no-std", "dlc/no-std", "lightning/no-std"] +no-std = ["dlc/no-std", "lightning/no-std"] use-serde = ["serde", "secp256k1-zkp/serde", "bitcoin/serde"] [dependencies] -bitcoin = { version = "0.30.2", default-features = false } -dlc = { version = "0.5.0", path = "../dlc", default-features = false } -lightning = { version = "0.0.121", default-features = false } -secp256k1-zkp = {version = "0.9.2"} +bitcoin = { version = "0.32.2", default-features = false } +dlc = { version = "0.6.0", path = "../dlc", default-features = false } +lightning = { version = "0.0.124", default-features = false } +secp256k1-zkp = {version = "0.11.0"} serde = {version = "1.0", features = ["derive"], optional = true} [dev-dependencies] -bitcoin = { version = "0.30.2", default-features = false, features = ["serde"] } +bitcoin = { version = "0.32.2", default-features = false, features = ["serde"] } dlc-messages = {path = "./", default-features = false, features = ["use-serde"]} -secp256k1-zkp = {version = "0.9.2", features = ["serde", "global-context"]} +secp256k1-zkp = {version = "0.11.0", features = ["serde", "global-context"]} serde = {version = "1.0", features = ["derive"]} serde_json = "1.0" diff --git a/dlc-messages/src/lib.rs b/dlc-messages/src/lib.rs index 4f0395bb..719350af 100644 --- a/dlc-messages/src/lib.rs +++ b/dlc-messages/src/lib.rs @@ -132,7 +132,7 @@ impl From<&FundingInput> for TxInputInfo { outpoint: OutPoint { txid: Transaction::consensus_decode(&mut funding_input.prev_tx.as_slice()) .expect("Transaction Decode Error") - .txid(), + .compute_txid(), vout: funding_input.prev_tx_vout, }, max_witness_len: (funding_input.max_witness_len as usize), @@ -603,7 +603,7 @@ mod tests { fn test_roundtrip(msg: T) { let mut buf = Vec::new(); msg.write(&mut buf).expect("Error writing message"); - let mut cursor = std::io::Cursor::new(&buf); + let mut cursor = lightning::io::Cursor::new(buf); let deser = Readable::read(&mut cursor).expect("Error reading message"); assert_eq!(msg, deser); } diff --git a/dlc-messages/src/message_handler.rs b/dlc-messages/src/message_handler.rs index c6eaeb09..6e587871 100644 --- a/dlc-messages/src/message_handler.rs +++ b/dlc-messages/src/message_handler.rs @@ -86,7 +86,7 @@ macro_rules! handle_read_dlc_messages { ($msg_type:ident, $buffer:ident, $(($type_id:ident, $variant:ident)),*) => {{ let decoded = match $msg_type { $( - $crate::$type_id => Message::$variant(Readable::read(&mut $buffer)?), + $crate::$type_id => Message::$variant(Readable::read($buffer)?), )* _ => return Ok(None), }; @@ -97,7 +97,7 @@ macro_rules! handle_read_dlc_messages { /// Parses a DLC message from a buffer. pub fn read_dlc_message( msg_type: u16, - mut buffer: &mut R, + buffer: &mut R, ) -> Result, DecodeError> { handle_read_dlc_messages!( msg_type, @@ -128,14 +128,14 @@ impl CustomMessageReader for MessageHandler { fn read( &self, msg_type: u16, - mut buffer: &mut R, + buffer: &mut R, ) -> Result, DecodeError> { let decoded = match msg_type { crate::segmentation::SEGMENT_START_TYPE => { - WireMessage::SegmentStart(Readable::read(&mut buffer)?) + WireMessage::SegmentStart(Readable::read(buffer)?) } crate::segmentation::SEGMENT_CHUNK_TYPE => { - WireMessage::SegmentChunk(Readable::read(&mut buffer)?) + WireMessage::SegmentChunk(Readable::read(buffer)?) } _ => return read_dlc_message(msg_type, buffer), }; @@ -147,6 +147,17 @@ impl CustomMessageReader for MessageHandler { /// Implementation of the `CustomMessageHandler` trait is required to handle /// custom messages in the LDK. impl CustomMessageHandler for MessageHandler { + fn peer_connected( + &self, + _their_node_id: &PublicKey, + _msg: &lightning::ln::msgs::Init, + _inbound: bool, + ) -> Result<(), ()> { + Ok(()) + } + + fn peer_disconnected(&self, _their_node_id: &PublicKey) {} + fn handle_custom_message( &self, msg: WireMessage, diff --git a/dlc-messages/src/oracle_msgs.rs b/dlc-messages/src/oracle_msgs.rs index 651163bc..e8cab9e9 100644 --- a/dlc-messages/src/oracle_msgs.rs +++ b/dlc-messages/src/oracle_msgs.rs @@ -4,6 +4,7 @@ use crate::ser_impls::{ read_as_tlv, read_i32, read_schnorr_pubkey, read_schnorrsig, read_strings_u16, write_as_tlv, write_i32, write_schnorr_pubkey, write_schnorrsig, write_strings_u16, }; +use bitcoin::hashes::Hash; use dlc::{Error, OracleInfo as DlcOracleInfo}; use lightning::ln::msgs::DecodeError; use lightning::ln::wire::Type; @@ -173,7 +174,8 @@ impl OracleAnnouncement { .write(&mut event_hex) .expect("Error writing oracle event"); - let msg = Message::from_hashed_data::(&event_hex); + let hash = secp256k1_zkp::hashes::sha256::Hash::hash(&event_hex); + let msg = Message::from_digest(hash.to_byte_array()); secp.verify_schnorr(&self.announcement_signature, &msg, &self.oracle_public_key)?; self.oracle_event.validate() } @@ -346,7 +348,7 @@ impl_dlc_writeable!(OracleAttestation, { mod tests { use super::*; use secp256k1_zkp::{rand::thread_rng, Message, SECP256K1}; - use secp256k1_zkp::{schnorr::Signature as SchnorrSignature, KeyPair, XOnlyPublicKey}; + use secp256k1_zkp::{schnorr::Signature as SchnorrSignature, Keypair, XOnlyPublicKey}; fn enum_descriptor() -> EnumEventDescriptor { EnumEventDescriptor { @@ -365,7 +367,7 @@ mod tests { } fn some_schnorr_pubkey() -> XOnlyPublicKey { - let key_pair = KeyPair::new(SECP256K1, &mut thread_rng()); + let key_pair = Keypair::new(SECP256K1, &mut thread_rng()); XOnlyPublicKey::from_keypair(&key_pair).0 } @@ -389,7 +391,7 @@ mod tests { #[test] fn valid_oracle_announcement_passes_validation_test() { - let key_pair = KeyPair::new(SECP256K1, &mut thread_rng()); + let key_pair = Keypair::new(SECP256K1, &mut thread_rng()); let oracle_pubkey = XOnlyPublicKey::from_keypair(&key_pair).0; let events = [digit_event(10), enum_event(1)]; for event in events { @@ -397,7 +399,8 @@ mod tests { event .write(&mut event_hex) .expect("Error writing oracle event"); - let msg = Message::from_hashed_data::(&event_hex); + let hash = secp256k1_zkp::hashes::sha256::Hash::hash(&event_hex); + let msg = Message::from_digest(hash.to_byte_array()); let sig = SECP256K1.sign_schnorr(&msg, &key_pair); let valid_announcement = OracleAnnouncement { announcement_signature: sig, @@ -413,7 +416,7 @@ mod tests { #[test] fn invalid_oracle_announcement_fails_validation_test() { - let key_pair = KeyPair::new(SECP256K1, &mut thread_rng()); + let key_pair = Keypair::new(SECP256K1, &mut thread_rng()); let oracle_pubkey = XOnlyPublicKey::from_keypair(&key_pair).0; let events = [digit_event(9), enum_event(2)]; for event in events { @@ -421,7 +424,8 @@ mod tests { event .write(&mut event_hex) .expect("Error writing oracle event"); - let msg = Message::from_hashed_data::(&event_hex); + let hash = secp256k1_zkp::hashes::sha256::Hash::hash(&event_hex); + let msg = Message::from_digest(hash.to_byte_array()); let sig = SECP256K1.sign_schnorr(&msg, &key_pair); let invalid_announcement = OracleAnnouncement { announcement_signature: sig, @@ -437,14 +441,15 @@ mod tests { #[test] fn invalid_oracle_announcement_signature_fails_validation_test() { - let key_pair = KeyPair::new(SECP256K1, &mut thread_rng()); + let key_pair = Keypair::new(SECP256K1, &mut thread_rng()); let oracle_pubkey = XOnlyPublicKey::from_keypair(&key_pair).0; let event = digit_event(10); let mut event_hex = Vec::new(); event .write(&mut event_hex) .expect("Error writing oracle event"); - let msg = Message::from_hashed_data::(&event_hex); + let hash = secp256k1_zkp::hashes::sha256::Hash::hash(&event_hex); + let msg = Message::from_digest(hash.to_byte_array()); let sig = SECP256K1.sign_schnorr(&msg, &key_pair); let mut sig_hex = *sig.as_ref(); sig_hex[10] = sig_hex[10].checked_add(1).unwrap_or(0); diff --git a/dlc-messages/src/ser_impls.rs b/dlc-messages/src/ser_impls.rs index 1376e359..e34bb0d4 100644 --- a/dlc-messages/src/ser_impls.rs +++ b/dlc-messages/src/ser_impls.rs @@ -1,7 +1,7 @@ //! Set of utility functions to help with serialization. -use bitcoin::network::constants::Network; use bitcoin::Address; +use bitcoin::Network; use dlc::{EnumerationPayout, PartyParams, Payout, TxInputInfo}; use lightning::io::Read; use lightning::ln::msgs::DecodeError; @@ -470,18 +470,36 @@ where } /// Writes a [`bitcoin::util::address::Address`] value to the given writer. +/// +/// https://docs.rs/bitcoin/0.30.2/bitcoin/address/struct.Address.html +/// +/// Parsed addresses do not always have one network. The problem is that legacy testnet, regtest and +/// signet addresse use the same prefix instead of multiple different ones. When parsing, +/// such addresses are always assumed to be testnet addresses (the same is true for bech32 signet addresses). +/// +/// Only checks if the address is Mainnet. pub fn write_address( address: &Address, writer: &mut W, ) -> Result<(), ::lightning::io::Error> { address.script_pubkey().write(writer)?; - let net: u8 = match address.network { - Network::Bitcoin => 0, - Network::Testnet => 1, - Network::Signet => 2, - Network::Regtest => 3, - _ => unimplemented!(), - }; + let unchecked_address = address.as_unchecked(); + + const NETWORKS: [Network; 4] = [ + Network::Bitcoin, + Network::Testnet, + Network::Signet, + Network::Regtest, + ]; + + let mut net: u8 = 0; + + for (i, n) in NETWORKS.iter().enumerate() { + if unchecked_address.is_valid_for_network(*n) { + net = i as u8; + break; + } + } net.write(writer) } @@ -639,7 +657,7 @@ impl_dlc_writeable_external!(PartyParams, party_params, { #[cfg(test)] mod tests { - use std::io::Cursor; + use lightning::io::Cursor; use super::{read_f64, write_f64}; @@ -648,7 +666,7 @@ mod tests { let original = 2.3; let mut ser = Vec::new(); write_f64(original, &mut ser).unwrap(); - let deser = read_f64(&mut Cursor::new(&mut ser)).unwrap(); + let deser = read_f64(&mut Cursor::new(&ser)).unwrap(); assert_eq!(original, deser); } diff --git a/dlc-sled-storage-provider/Cargo.toml b/dlc-sled-storage-provider/Cargo.toml index f90fc5b9..a4e3553c 100644 --- a/dlc-sled-storage-provider/Cargo.toml +++ b/dlc-sled-storage-provider/Cargo.toml @@ -9,12 +9,12 @@ repository = "https://github.com/p2pderivatives/rust-dlc/tree/master/dlc-sled-st version = "0.1.0" [features] -wallet = ["bitcoin", "secp256k1-zkp", "simple-wallet", "lightning"] +wallet = ["bitcoin", "secp256k1-zkp", "simple-wallet"] [dependencies] -bitcoin = {version = "0.30", optional = true} +bitcoin = {version = "0.32.2", optional = true} dlc-manager = {path = "../dlc-manager"} -lightning = {version = "0.0.121", optional = true} -secp256k1-zkp = {version = "0.9", optional = true} +lightning = "0.0.124" +secp256k1-zkp = {version = "0.11.0", optional = true} simple-wallet = {path = "../simple-wallet", optional = true} sled = "0.34" diff --git a/dlc-sled-storage-provider/src/lib.rs b/dlc-sled-storage-provider/src/lib.rs index 31850688..470e958f 100644 --- a/dlc-sled-storage-provider/src/lib.rs +++ b/dlc-sled-storage-provider/src/lib.rs @@ -33,6 +33,7 @@ use dlc_manager::contract::{ #[cfg(feature = "wallet")] use dlc_manager::Utxo; use dlc_manager::{error::Error, ContractId, Storage}; +use lightning::io::{Cursor, Read}; #[cfg(feature = "wallet")] use lightning::util::ser::{Readable, Writeable}; #[cfg(feature = "wallet")] @@ -42,7 +43,6 @@ use simple_wallet::WalletStorage; use sled::transaction::{ConflictableTransactionResult, UnabortableTransactionError}; use sled::{Db, Transactional, Tree}; use std::convert::TryInto; -use std::io::{Cursor, Read}; const CONTRACT_TREE: u8 = 1; const CHANNEL_TREE: u8 = 2; @@ -401,7 +401,7 @@ impl Storage for SledStorageProvider { .map_err(|e| Error::StorageError(format!("Error reading chain monitor: {}", e)))?; let deserialized = match serialized { Some(s) => Some( - ChainMonitor::deserialize(&mut ::std::io::Cursor::new(s)) + ChainMonitor::deserialize(&mut lightning::io::Cursor::new(s)) .map_err(to_storage_error)?, ), None => None, @@ -546,7 +546,7 @@ fn insert_contract( db.insert(&contract.get_id(), serialized) } -fn serialize_contract(contract: &Contract) -> Result, ::std::io::Error> { +fn serialize_contract(contract: &Contract) -> Result, lightning::io::Error> { let serialized = match contract { Contract::Offered(o) | Contract::Rejected(o) => o.serialize(), Contract::Accepted(o) => o.serialize(), @@ -564,7 +564,7 @@ fn serialize_contract(contract: &Contract) -> Result, ::std::io::Error> } fn deserialize_contract(buff: &sled::IVec) -> Result { - let mut cursor = ::std::io::Cursor::new(buff); + let mut cursor = lightning::io::Cursor::new(buff); let mut prefix = [0u8; 1]; cursor.read_exact(&mut prefix)?; let contract_prefix: ContractPrefix = prefix[0].try_into()?; @@ -603,7 +603,7 @@ fn deserialize_contract(buff: &sled::IVec) -> Result { Ok(contract) } -fn serialize_channel(channel: &Channel) -> Result, ::std::io::Error> { +fn serialize_channel(channel: &Channel) -> Result, lightning::io::Error> { let serialized = match channel { Channel::Offered(o) => o.serialize(), Channel::Accepted(a) => a.serialize(), @@ -628,7 +628,7 @@ fn serialize_channel(channel: &Channel) -> Result, ::std::io::Error> { } fn deserialize_channel(buff: &sled::IVec) -> Result { - let mut cursor = ::std::io::Cursor::new(buff); + let mut cursor = lightning::io::Cursor::new(buff); let mut prefix = [0u8; 1]; cursor.read_exact(&mut prefix)?; let channel_prefix: ChannelPrefix = prefix[0].try_into()?; @@ -709,7 +709,7 @@ mod tests { where T: Serializable, { - let mut cursor = std::io::Cursor::new(&serialized); + let mut cursor = lightning::io::Cursor::new(serialized); T::deserialize(&mut cursor).unwrap() } diff --git a/dlc-trie/Cargo.toml b/dlc-trie/Cargo.toml index 2b6f4470..deeff96c 100644 --- a/dlc-trie/Cargo.toml +++ b/dlc-trie/Cargo.toml @@ -5,18 +5,18 @@ homepage = "https://github.com/p2pderivatives/rust-dlc" license-file = "../LICENSE" name = "dlc-trie" repository = "https://github.com/p2pderivatives/rust-dlc/tree/master/dlc-trie" -version = "0.5.0" +version = "0.6.0" [features] default = ["std"] std = ["dlc/std", "bitcoin/std"] -no-std = ["bitcoin/no-std", "dlc/no-std"] +no-std = ["dlc/no-std"] parallel = ["rayon"] use-serde = ["serde", "dlc/use-serde"] [dependencies] -bitcoin = { version = "0.30.2", default-features = false } -dlc = {version = "0.5.0", default-features = false, path = "../dlc"} +bitcoin = { version = "0.32.2", default-features = false } +dlc = {version = "0.6.0", default-features = false, path = "../dlc"} rayon = {version = "1.5", optional = true} -secp256k1-zkp = {version = "0.9.2" } -serde = {version = "1.0", optional = true, default_features = false, features = ["derive"]} +secp256k1-zkp = {version = "0.11.0" } +serde = {version = "1.0", optional = true, default-features = false, features = ["derive"]} diff --git a/dlc/Cargo.toml b/dlc/Cargo.toml index 290ceea0..97bfb35b 100644 --- a/dlc/Cargo.toml +++ b/dlc/Cargo.toml @@ -5,14 +5,13 @@ homepage = "https://github.com/p2pderivatives/rust-dlc" license-file = "../LICENSE" name = "dlc" repository = "https://github.com/p2pderivatives/rust-dlc/tree/master/dlc" -version = "0.5.0" +version = "0.6.0" [dependencies] -bitcoin = { version = "0.30.2", default-features = false } -hashbrown = { version = "0.11.2", optional = true } -miniscript = { version = "10", default-features = false } -secp256k1-sys = "0.8.1" -secp256k1-zkp = "0.9.2" +bitcoin = { version = "0.32.2", default-features = false } +miniscript = { version = "12.2", default-features = false } +secp256k1-sys = "0.10.0" +secp256k1-zkp = "0.11.0" serde = { version = "1.0", default-features = false, optional = true } [features] @@ -20,12 +19,12 @@ serde = { version = "1.0", default-features = false, optional = true } unstable = [] default = ["std"] std = ["bitcoin/std", "miniscript/std", "secp256k1-zkp/rand-std"] -no-std = ["dep:hashbrown", "miniscript/no-std", "bitcoin/no-std"] +no-std = ["miniscript/no-std"] use-serde = ["serde", "secp256k1-zkp/serde", "bitcoin/serde"] [dev-dependencies] bitcoin-test-utils = { path = "../bitcoin-test-utils" } -bitcoincore-rpc = { version = "0.17.0" } -bitcoincore-rpc-json = { version = "0.17.0" } +bitcoincore-rpc = { version = "0.19.0" } +bitcoincore-rpc-json = { version = "0.19.0" } rayon = "1.5" -secp256k1-zkp = { version = "0.9.2", features = ["bitcoin_hashes", "rand","serde", "global-context"] } +secp256k1-zkp = { version = "0.11.0", features = ["hashes", "rand","serde", "global-context"] } diff --git a/dlc/src/channel/mod.rs b/dlc/src/channel/mod.rs index 205e6310..6c81aa84 100644 --- a/dlc/src/channel/mod.rs +++ b/dlc/src/channel/mod.rs @@ -1,20 +1,17 @@ //! Module for working with DLC channels -#[cfg(all(feature = "no-std", not(feature = "std")))] -extern crate hashbrown; - #[cfg(any(feature = "std", not(feature = "no-std")))] -use std::collections::HashMap; +use std::collections::BTreeMap; #[cfg(all(feature = "no-std", not(feature = "std")))] -use self::hashbrown::HashMap; +use alloc::collections::BTreeMap; use crate::{signatures_to_secret, util::get_sig_hash_msg, DlcTransactions, PartyParams, Payout}; use super::Error; use bitcoin::{ - absolute::LockTime, ecdsa::Signature, sighash::EcdsaSighashType, Address, OutPoint, PublicKey, - Script, ScriptBuf, Sequence, Transaction, TxIn, TxOut, Witness, + absolute::LockTime, ecdsa::Signature, sighash::EcdsaSighashType, Address, Amount, OutPoint, + PublicKey, Script, ScriptBuf, Sequence, Transaction, TxIn, TxOut, Witness, }; use miniscript::Descriptor; use secp256k1_zkp::{ @@ -125,7 +122,7 @@ pub fn create_buffer_transaction( lock_time: LockTime::from_consensus(lock_time), input: vec![fund_tx_in.clone()], output: vec![TxOut { - value: total_collateral, + value: Amount::from_sat(total_collateral), script_pubkey: descriptor.script_pubkey(), }], } @@ -197,11 +194,11 @@ pub fn create_settle_transaction( let mut output = crate::util::discard_dust( vec![ TxOut { - value: offer_payout, + value: Amount::from_sat(offer_payout), script_pubkey: offer_descriptor.script_pubkey(), }, TxOut { - value: accept_payout, + value: Amount::from_sat(accept_payout), script_pubkey: accept_descriptor.script_pubkey(), }, ], @@ -220,7 +217,7 @@ pub fn create_settle_transaction( / (output.len() as u64); for o in &mut output { - o.value += remaining_fee; + o.value += Amount::from_sat(remaining_fee); } Ok(Transaction { @@ -290,11 +287,11 @@ pub fn create_renewal_channel_transactions( super::util::weight_to_fee(BUFFER_TX_WEIGHT + CET_EXTRA_WEIGHT, fee_rate_per_vb)?; let (fund_vout, fund_output) = - super::util::get_output_for_script_pubkey(fund_tx, &funding_script_pubkey.to_v0_p2wsh()) + super::util::get_output_for_script_pubkey(fund_tx, &funding_script_pubkey.to_p2wsh()) .expect("to find the funding script pubkey"); let outpoint = OutPoint { - txid: fund_tx.txid(), + txid: fund_tx.compute_txid(), vout: fund_vout as u32, }; @@ -310,12 +307,12 @@ pub fn create_renewal_channel_transactions( let buffer_transaction = create_buffer_transaction( &tx_in, &buffer_descriptor, - fund_output.value - extra_fee, + fund_output.value.to_sat() - extra_fee, cet_lock_time, ); let outpoint = OutPoint { - txid: buffer_transaction.txid(), + txid: buffer_transaction.compute_txid(), vout: 0, }; @@ -367,22 +364,22 @@ pub fn sign_cet( )?; let own_pk = SecpPublicKey::from_secret_key(secp, own_sk); - let sigs = HashMap::from_iter([ + let sigs = BTreeMap::from_iter([ ( PublicKey { inner: own_pk, compressed: true, }, bitcoin::ecdsa::Signature { - sig: own_sig, - hash_ty: EcdsaSighashType::All, + signature: own_sig, + sighash_type: EcdsaSighashType::All, }, ), ( *counter_pubkey, bitcoin::ecdsa::Signature { - sig: adapted_sig, - hash_ty: EcdsaSighashType::All, + signature: adapted_sig, + sighash_type: EcdsaSighashType::All, }, ), ]); @@ -412,7 +409,7 @@ pub fn create_and_sign_punish_buffer_transaction( let tx_in = TxIn { previous_output: OutPoint { - txid: prev_tx.txid(), + txid: prev_tx.compute_txid(), vout: 0, }, sequence: Sequence::ZERO, @@ -426,19 +423,19 @@ pub fn create_and_sign_punish_buffer_transaction( let tx_fee = crate::util::weight_to_fee(PUNISH_BUFFER_INPUT_WEIGHT + output_weight, fee_rate_per_vb)?; - let output_value = prev_tx.output[0].value - tx_fee; + let output_value = prev_tx.output[0].value.to_sat() - tx_fee; let mut tx = Transaction { version: super::TX_VERSION, lock_time: LockTime::from_consensus(lock_time), input: vec![tx_in], output: vec![TxOut { - value: output_value, + value: Amount::from_sat(output_value), script_pubkey: dest_address.script_pubkey(), }], }; - let mut sigs = HashMap::new(); + let mut sigs = BTreeMap::new(); for sk in &[&own_sk, &counter_publish_sk, &counter_revoke_sk] { let pk = PublicKey { @@ -452,15 +449,15 @@ pub fn create_and_sign_punish_buffer_transaction( ( pk, bitcoin::ecdsa::Signature { - sig: super::util::get_raw_sig_for_tx_input( + signature: super::util::get_raw_sig_for_tx_input( secp, &tx, 0, &descriptor.script_code()?, - prev_tx.output[0].value, + prev_tx.output[0].value.to_sat(), sk, )?, - hash_ty: EcdsaSighashType::All, + sighash_type: EcdsaSighashType::All, }, ), ); @@ -500,7 +497,7 @@ pub fn create_and_sign_punish_settle_transaction( let tx_in = TxIn { previous_output: OutPoint { - txid: prev_tx.txid(), + txid: prev_tx.compute_txid(), vout, }, sequence: Sequence::ZERO, @@ -508,7 +505,7 @@ pub fn create_and_sign_punish_settle_transaction( witness: Witness::default(), }; - let input_value = prev_tx.output[vout as usize].value; + let input_value = prev_tx.output[vout as usize].value.to_sat(); let dest_script_pk_len = dest_address.script_pubkey().len(); let var_int_prefix_len = crate::util::compute_var_int_prefix_size(dest_script_pk_len); @@ -521,12 +518,12 @@ pub fn create_and_sign_punish_settle_transaction( lock_time: LockTime::from_consensus(lock_time), input: vec![tx_in], output: vec![TxOut { - value: input_value - tx_fee, + value: Amount::from_sat(input_value - tx_fee), script_pubkey: dest_address.script_pubkey(), }], }; - let mut sigs = HashMap::new(); + let mut sigs = BTreeMap::new(); for sk in &[&own_sk, &counter_publish_sk, &counter_revoke_sk] { let pk = PublicKey { @@ -571,12 +568,12 @@ pub fn create_collaborative_close_transaction( //TODO(tibo): add fee re-payment let offer_output = TxOut { - value: offer_payout, + value: Amount::from_sat(offer_payout), script_pubkey: offer_params.payout_script_pubkey.clone(), }; let accept_output = TxOut { - value: accept_payout, + value: Amount::from_sat(accept_payout), script_pubkey: accept_params.payout_script_pubkey.clone(), }; @@ -781,7 +778,7 @@ mod tests { // Use random signature as it doesn't matter. let sig = bitcoin::ecdsa::Signature { - sig: secp256k1_zkp::ecdsa::Signature::from_str( + signature: secp256k1_zkp::ecdsa::Signature::from_str( "3045\ 0221\ 00f7c3648c390d87578cd79c8016940aa8e3511c4104cb78daa8fb8e429375efc1\ @@ -789,10 +786,10 @@ mod tests { 531d75c136272f127a5dc14acc0722301cbddc222262934151f140da345af177", ) .unwrap(), - hash_ty: EcdsaSighashType::All, + sighash_type: EcdsaSighashType::All, }; - let satisfier = HashMap::from_iter(vec![ + let satisfier = BTreeMap::from_iter(vec![ (offer_params.own_pk, sig), (accept_params.own_pk, sig), ]); @@ -911,7 +908,7 @@ mod tests { // Use random signature as it doesn't matter. let sig = bitcoin::ecdsa::Signature { - sig: secp256k1_zkp::ecdsa::Signature::from_str( + signature: secp256k1_zkp::ecdsa::Signature::from_str( "3045\ 0221\ 00f7c3648c390d87578cd79c8016940aa8e3511c4104cb78daa8fb8e429375efc1\ @@ -919,10 +916,10 @@ mod tests { 531d75c136272f127a5dc14acc0722301cbddc222262934151f140da345af177", ) .unwrap(), - hash_ty: EcdsaSighashType::All, + sighash_type: EcdsaSighashType::All, }; - let satisfier = HashMap::from_iter(vec![(offer_params.own_pk, sig)]); + let satisfier = BTreeMap::from_iter(vec![(offer_params.own_pk, sig)]); descriptor .satisfy( diff --git a/dlc/src/lib.rs b/dlc/src/lib.rs index ccf62717..9f8aa1ca 100644 --- a/dlc/src/lib.rs +++ b/dlc/src/lib.rs @@ -12,6 +12,8 @@ #![deny(unused_imports)] #![deny(missing_docs)] +#[cfg(not(feature = "std"))] +extern crate alloc; extern crate bitcoin; extern crate core; extern crate miniscript; @@ -21,6 +23,8 @@ pub extern crate secp256k1_zkp; extern crate serde; use bitcoin::secp256k1::Scalar; +use bitcoin::transaction::Version; +use bitcoin::Amount; use bitcoin::{ absolute::LockTime, blockdata::{ @@ -50,7 +54,7 @@ const DUST_LIMIT: u64 = 1000; /// The transaction version /// See: https://github.com/discreetlogcontracts/dlcspecs/blob/master/Transactions.md#funding-transaction -const TX_VERSION: i32 = 2; +const TX_VERSION: Version = Version::TWO; /// The base weight of a fund transaction /// See: https://github.com/discreetlogcontracts/dlcspecs/blob/master/Transactions.md#fees @@ -132,7 +136,7 @@ pub struct DlcTransactions { impl DlcTransactions { /// Get the fund output in the fund transaction pub fn get_fund_output(&self) -> &TxOut { - let v0_witness_fund_script = self.funding_script_pubkey.to_v0_p2wsh(); + let v0_witness_fund_script = self.funding_script_pubkey.to_p2wsh(); util::get_output_for_script_pubkey(&self.fund, &v0_witness_fund_script) .unwrap() .1 @@ -140,7 +144,7 @@ impl DlcTransactions { /// Get the fund output in the fund transaction pub fn get_fund_output_index(&self) -> usize { - let v0_witness_fund_script = self.funding_script_pubkey.to_v0_p2wsh(); + let v0_witness_fund_script = self.funding_script_pubkey.to_p2wsh(); util::get_output_for_script_pubkey(&self.fund, &v0_witness_fund_script) .unwrap() .0 @@ -149,7 +153,7 @@ impl DlcTransactions { /// Get the outpoint for the fund output in the fund transaction pub fn get_fund_outpoint(&self) -> OutPoint { OutPoint { - txid: self.fund.txid(), + txid: self.fund.compute_txid(), vout: self.get_fund_output_index() as u32, } } @@ -188,12 +192,14 @@ pub struct OracleInfo { pub enum Error { /// Secp256k1 error Secp256k1(secp256k1_zkp::Error), - /// An error while computing a signature hash - Sighash(bitcoin::sighash::Error), + /// An error while computing a p2wpkh signature hash + P2wpkh(bitcoin::sighash::P2wpkhError), /// An invalid argument was provided InvalidArgument, /// An error occurred in miniscript Miniscript(miniscript::Error), + /// Error attempting to do an out of bounds access on the transaction inputs vector. + InputsIndex(bitcoin::transaction::InputsIndexError), } impl From for Error { @@ -208,9 +214,15 @@ impl From for Error { } } -impl From for Error { - fn from(error: bitcoin::sighash::Error) -> Error { - Error::Sighash(error) +impl From for Error { + fn from(error: bitcoin::sighash::P2wpkhError) -> Error { + Error::P2wpkh(error) + } +} + +impl From for Error { + fn from(error: bitcoin::transaction::InputsIndexError) -> Error { + Error::InputsIndex(error) } } @@ -225,7 +237,8 @@ impl fmt::Display for Error { match *self { Error::Secp256k1(ref e) => write!(f, "Secp256k1 error: {}", e), Error::InvalidArgument => write!(f, "Invalid argument"), - Error::Sighash(_) => write!(f, "Error while computing sighash"), + Error::P2wpkh(ref e) => write!(f, "Error while computing p2wpkh sighash: {}", e), + Error::InputsIndex(ref e) => write!(f, "Error ordering inputs: {}", e), Error::Miniscript(_) => write!(f, "Error within miniscript"), } } @@ -236,7 +249,8 @@ impl std::error::Error for Error { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { Error::Secp256k1(e) => Some(e), - Error::Sighash(e) => Some(e), + Error::P2wpkh(e) => Some(e), + Error::InputsIndex(e) => Some(e), Error::InvalidArgument => None, Error::Miniscript(e) => Some(e), } @@ -333,7 +347,7 @@ impl PartyParams { } let change_output = TxOut { - value: self.input_amount - required_input_funds, + value: Amount::from_sat(self.input_amount - required_input_funds), script_pubkey: self.change_script_pubkey.clone(), }; @@ -379,8 +393,8 @@ pub fn create_dlc_transactions( 0, )?; let fund_outpoint = OutPoint { - txid: fund_tx.txid(), - vout: util::get_output_for_script_pubkey(&fund_tx, &funding_script_pubkey.to_v0_p2wsh()) + txid: fund_tx.compute_txid(), + vout: util::get_output_for_script_pubkey(&fund_tx, &funding_script_pubkey.to_p2wsh()) .expect("to find the funding script pubkey") .0 as u32, }; @@ -418,8 +432,8 @@ pub(crate) fn create_fund_transaction_with_fees( accept_params.get_change_output_and_fees(fee_rate_per_vb, extra_fee)?; let fund_output_value = checked_add!(offer_params.input_amount, accept_params.input_amount)? - - offer_change_output.value - - accept_change_output.value + - offer_change_output.value.to_sat() + - accept_change_output.value.to_sat() - offer_fund_fee - accept_fund_fee - extra_fee; @@ -432,8 +446,8 @@ pub(crate) fn create_fund_transaction_with_fees( assert_eq!( offer_params.input_amount + accept_params.input_amount, fund_output_value - + offer_change_output.value - + accept_change_output.value + + offer_change_output.value.to_sat() + + accept_change_output.value.to_sat() + offer_fund_fee + accept_fund_fee + extra_fee @@ -508,12 +522,12 @@ pub(crate) fn create_cets_and_refund_tx( ); let offer_refund_output = TxOut { - value: offer_params.collateral, + value: Amount::from_sat(offer_params.collateral), script_pubkey: offer_params.payout_script_pubkey.clone(), }; let accept_refund_ouput = TxOut { - value: accept_params.collateral, + value: Amount::from_sat(accept_params.collateral), script_pubkey: accept_params.payout_script_pubkey.clone(), }; @@ -572,11 +586,11 @@ pub fn create_cets( let mut txs: Vec = Vec::new(); for payout in payouts { let offer_output = TxOut { - value: payout.offer, + value: Amount::from_sat(payout.offer), script_pubkey: offer_payout_script_pubkey.to_owned(), }; let accept_output = TxOut { - value: payout.accept, + value: Amount::from_sat(payout.accept), script_pubkey: accept_payout_script_pubkey.to_owned(), }; let tx = create_cet( @@ -610,8 +624,8 @@ pub fn create_funding_transaction( lock_time: u32, ) -> Transaction { let fund_tx_out = TxOut { - value: output_amount, - script_pubkey: funding_script_pubkey.to_v0_p2wsh(), + value: Amount::from_sat(output_amount), + script_pubkey: funding_script_pubkey.to_p2wsh(), }; let output: Vec = { @@ -917,11 +931,13 @@ mod tests { use bitcoin::blockdata::script::ScriptBuf; use bitcoin::blockdata::transaction::OutPoint; use bitcoin::consensus::encode::Encodable; + use bitcoin::hashes::sha256; + use bitcoin::hashes::Hash; use bitcoin::sighash::EcdsaSighashType; - use bitcoin::{network::constants::Network, Address, Txid}; + use bitcoin::{Address, CompressedPublicKey, Network, Txid}; use secp256k1_zkp::{ rand::{Rng, RngCore}, - KeyPair, PublicKey, Secp256k1, SecretKey, Signing, + Keypair, PublicKey, Secp256k1, SecretKey, Signing, }; use std::fmt::Write; use std::str::FromStr; @@ -952,12 +968,12 @@ mod tests { fn create_test_tx_io() -> (TxOut, TxOut, TxIn) { let offer = TxOut { - value: DUST_LIMIT + 1, + value: Amount::from_sat(DUST_LIMIT + 1), script_pubkey: ScriptBuf::new(), }; let accept = TxOut { - value: DUST_LIMIT + 2, + value: Amount::from_sat(DUST_LIMIT + 2), script_pubkey: ScriptBuf::new(), }; @@ -976,10 +992,10 @@ mod tests { let (offer, accept, funding) = create_test_tx_io(); let refund_transaction = create_refund_transaction(offer, accept, funding, 0); - assert_eq!(2, refund_transaction.version); + assert_eq!(Version::TWO, refund_transaction.version); assert_eq!(0, refund_transaction.lock_time.to_consensus_u32()); - assert_eq!(DUST_LIMIT + 1, refund_transaction.output[0].value); - assert_eq!(DUST_LIMIT + 2, refund_transaction.output[1].value); + assert_eq!(DUST_LIMIT + 1, refund_transaction.output[0].value.to_sat()); + assert_eq!(DUST_LIMIT + 2, refund_transaction.output[1].value.to_sat()); assert_eq!(3, refund_transaction.input[0].sequence.0); } @@ -990,7 +1006,7 @@ mod tests { let offer_inputs = create_txin_vec(Sequence::ZERO); let accept_inputs = create_txin_vec(Sequence(1)); - let change = 1000; + let change = Amount::from_sat(1000); let total_collateral = 31415; @@ -1022,7 +1038,7 @@ mod tests { assert_eq!(transaction.input[0].sequence.0, 0); assert_eq!(transaction.input[1].sequence.0, 1); - assert_eq!(transaction.output[0].value, total_collateral); + assert_eq!(transaction.output[0].value.to_sat(), total_collateral); assert_eq!(transaction.output[1].value, change); assert_eq!(transaction.output[2].value, change); assert_eq!(transaction.output.len(), 3); @@ -1036,7 +1052,7 @@ mod tests { let accept_inputs = create_txin_vec(Sequence(1)); let total_collateral = 31415; - let change = 999; + let change = Amount::from_sat(999); let offer_change_output = TxOut { value: change, @@ -1064,7 +1080,7 @@ mod tests { 0, ); - assert_eq!(transaction.output[0].value, total_collateral); + assert_eq!(transaction.output[0].value.to_sat(), total_collateral); assert_eq!(transaction.output.len(), 1); } @@ -1072,7 +1088,7 @@ mod tests { fn create_funding_transaction_serialized_test() { let secp = Secp256k1::new(); let input_amount = 5000000000; - let change = 4899999719; + let change = Amount::from_sat(4899999719); let total_collateral = 200000312; let offer_change_address = Address::from_str("bcrt1qlgmznucxpdkp5k3ktsct7eh6qrc4tju7ktjukn") @@ -1189,13 +1205,11 @@ mod tests { ) -> ScriptBuf { let sk = bitcoin::PrivateKey { inner: SecretKey::new(rng), - network: Network::Testnet, + network: Network::Testnet.into(), compressed: true, }; - let pk = bitcoin::PublicKey::from_private_key(secp, &sk); - Address::p2wpkh(&pk, Network::Testnet) - .unwrap() - .script_pubkey() + let pk = CompressedPublicKey::from_private_key(secp, &sk).unwrap(); + Address::p2wpkh(&pk, Network::Testnet).script_pubkey() } fn get_party_params( @@ -1257,7 +1271,7 @@ mod tests { party_params.get_change_output_and_fees(4, 0).unwrap(); // Assert - assert!(change_out.value > 0 && fund_fee > 0 && cet_fee > 0); + assert!(change_out.value > Amount::ZERO && fund_fee > 0 && cet_fee > 0); } #[test] @@ -1325,7 +1339,7 @@ mod tests { const NB_OUTCOMES: usize = 2; const NB_DIGITS: usize = 20; let mut oracle_infos: Vec = Vec::with_capacity(NB_ORACLES); - let mut oracle_sks: Vec = Vec::with_capacity(NB_ORACLES); + let mut oracle_sks: Vec = Vec::with_capacity(NB_ORACLES); let mut oracle_sk_nonce: Vec> = Vec::with_capacity(NB_ORACLES); let mut oracle_sigs: Vec> = Vec::with_capacity(NB_ORACLES); let messages: Vec>> = (0..NB_OUTCOMES) @@ -1334,9 +1348,9 @@ mod tests { .map(|y| { (0..NB_DIGITS) .map(|z| { - Message::from_hashed_data::(&[ - ((y + x + z) as u8), - ]) + let message = &[(x + y + z) as u8]; + let hash = sha256::Hash::hash(message).to_byte_array(); + Message::from_digest(hash) }) .collect() }) @@ -1345,7 +1359,7 @@ mod tests { .collect(); for i in 0..NB_ORACLES { - let oracle_kp = KeyPair::new(&secp, &mut rng); + let oracle_kp = Keypair::new(&secp, &mut rng); let oracle_pubkey = oracle_kp.x_only_public_key().0; let mut nonces: Vec = Vec::with_capacity(NB_DIGITS); let mut sk_nonces: Vec<[u8; 32]> = Vec::with_capacity(NB_DIGITS); @@ -1353,7 +1367,7 @@ mod tests { for j in 0..NB_DIGITS { let mut sk_nonce = [0u8; 32]; rng.fill_bytes(&mut sk_nonce); - let oracle_r_kp = KeyPair::from_seckey_slice(&secp, &sk_nonce).unwrap(); + let oracle_r_kp = Keypair::from_seckey_slice(&secp, &sk_nonce).unwrap(); let nonce = XOnlyPublicKey::from_keypair(&oracle_r_kp).0; let sig = secp_utils::schnorrsig_sign_with_nonce( &secp, @@ -1377,7 +1391,7 @@ mod tests { &offer_party_params.fund_pubkey, &accept_party_params.fund_pubkey, ); - let fund_output_value = dlc_txs.fund.output[0].value; + let fund_output_value = dlc_txs.fund.output[0].value.to_sat(); // Act let cet_sigs = create_cet_adaptor_sigs_from_oracle_info( @@ -1503,7 +1517,7 @@ mod tests { // Check that fund output are in correct order assert!( dlc_txs.fund.output[case.expected_fund_output_order[0]].script_pubkey - == dlc_txs.funding_script_pubkey.to_v0_p2wsh() + == dlc_txs.funding_script_pubkey.to_p2wsh() ); assert!( dlc_txs.fund.output[case.expected_fund_output_order[1]].script_pubkey @@ -1526,7 +1540,7 @@ mod tests { crate::util::get_output_for_script_pubkey( &dlc_txs.fund, - &dlc_txs.funding_script_pubkey.to_v0_p2wsh(), + &dlc_txs.funding_script_pubkey.to_p2wsh(), ) .expect("Could not find fund output"); } diff --git a/dlc/src/secp_utils.rs b/dlc/src/secp_utils.rs index 606e41d1..4e96d70a 100644 --- a/dlc/src/secp_utils.rs +++ b/dlc/src/secp_utils.rs @@ -2,15 +2,15 @@ //! rust-secp256k1 or rust-secp256k1-zkp. use crate::Error; +use bitcoin::hashes::sha256t_hash_newtype; use core::ptr; use secp256k1_sys::{ types::{c_int, c_uchar, c_void, size_t}, CPtr, SchnorrSigExtraParams, }; use secp256k1_zkp::hashes::Hash; -use secp256k1_zkp::hashes::*; use secp256k1_zkp::{ - schnorr::Signature as SchnorrSignature, KeyPair, Message, PublicKey, Scalar, Secp256k1, + schnorr::Signature as SchnorrSignature, Keypair, Message, PublicKey, Scalar, Secp256k1, Signing, Verification, XOnlyPublicKey, }; @@ -19,20 +19,20 @@ const BIP340_MIDSTATE: [u8; 32] = [ 0x97, 0xc8, 0x75, 0x50, 0x00, 0x3c, 0xc7, 0x65, 0x90, 0xf6, 0x11, 0x64, 0x33, 0xe9, 0xb6, 0x6a, ]; -sha256t_hash_newtype!( - BIP340Hash, - BIP340HashTag, - BIP340_MIDSTATE, - 64, - doc = "bip340 hash", - backward -); +sha256t_hash_newtype! { + /// BIP340 Hash Tag + pub struct BIP340HashTag = raw(BIP340_MIDSTATE, 64); + + /// BIP340 Hash + #[hash_newtype(backward)] + pub struct BIP340Hash(_); +} /// Create a Schnorr signature using the provided nonce instead of generating one. pub fn schnorrsig_sign_with_nonce( secp: &Secp256k1, msg: &Message, - keypair: &KeyPair, + keypair: &Keypair, nonce: &[u8; 32], ) -> SchnorrSignature { unsafe { diff --git a/dlc/src/util.rs b/dlc/src/util.rs index bd910926..c251b764 100644 --- a/dlc/src/util.rs +++ b/dlc/src/util.rs @@ -1,12 +1,9 @@ //! Utility functions not uniquely related to DLC -use bitcoin::address::{WitnessProgram, WitnessVersion}; -use bitcoin::script::PushBytesBuf; use bitcoin::sighash::SighashCache; -use bitcoin::{ - address::Payload, hash_types::PubkeyHash, sighash::EcdsaSighashType, Script, Transaction, TxOut, -}; -use bitcoin::{ScriptBuf, Sequence, Witness}; +use bitcoin::{sighash::EcdsaSighashType, Script, Transaction, TxOut}; +use bitcoin::{Amount, ScriptBuf, Sequence, Witness}; +use bitcoin::{PubkeyHash, WitnessProgram, WitnessVersion}; use secp256k1_zkp::{ecdsa::Signature, Message, PublicKey, Secp256k1, SecretKey, Signing}; use crate::Error; @@ -27,13 +24,14 @@ pub(crate) fn get_sig_hash_msg( script_pubkey: &Script, value: u64, ) -> Result { - let sig_hash = SighashCache::new(tx).segwit_signature_hash( + let sig_hash = SighashCache::new(tx).p2wsh_signature_hash( input_index, script_pubkey, - value, + Amount::from_sat(value), EcdsaSighashType::All, )?; - Ok(Message::from_slice(sig_hash.as_ref()).unwrap()) + + Ok(Message::from_digest_slice(sig_hash.as_ref()).unwrap()) } /// Convert a raw signature to DER encoded and append the sighash type, to use @@ -115,10 +113,12 @@ fn get_pkh_script_pubkey_from_sk(secp: &Secp256k1, sk: &SecretKey inner: PublicKey::from_secret_key(secp, sk), }; let mut hash_engine = PubkeyHash::engine(); + pk.write_into(&mut hash_engine) .expect("Error writing hash."); - let pkh = Payload::PubkeyHash(PubkeyHash::from_engine(hash_engine)); - pkh.script_pubkey() + let pk = PubkeyHash::from_engine(hash_engine); + + ScriptBuf::new_p2pkh(&pk) } /// Create a signature for a p2wpkh transaction input using the provided secret key @@ -204,8 +204,7 @@ pub(crate) fn redeem_script_to_script_sig(redeem: &Script) -> ScriptBuf { match redeem.len() { 0 => ScriptBuf::new(), _ => { - let mut bytes = PushBytesBuf::new(); - bytes.extend_from_slice(redeem.as_bytes()).unwrap(); + let bytes = redeem.as_bytes(); ScriptBuf::new_witness_program(&WitnessProgram::new(WitnessVersion::V0, bytes).unwrap()) } } @@ -233,7 +232,9 @@ pub fn get_output_for_script_pubkey<'a>( /// Filters the outputs that have a value lower than the given `dust_limit`. pub(crate) fn discard_dust(txs: Vec, dust_limit: u64) -> Vec { - txs.into_iter().filter(|x| x.value >= dust_limit).collect() + txs.into_iter() + .filter(|x| x.value.to_sat() >= dust_limit) + .collect() } pub(crate) fn get_sequence(lock_time: u32) -> Sequence { @@ -245,7 +246,7 @@ pub(crate) fn get_sequence(lock_time: u32) -> Sequence { } pub(crate) fn compute_var_int_prefix_size(len: usize) -> usize { - bitcoin::VarInt(len as u64).len() + bitcoin::VarInt(len as u64).size() } /// Validate that the fee rate is not too high diff --git a/electrs-blockchain-provider/Cargo.toml b/electrs-blockchain-provider/Cargo.toml index 5e29da97..021a728c 100644 --- a/electrs-blockchain-provider/Cargo.toml +++ b/electrs-blockchain-provider/Cargo.toml @@ -6,11 +6,11 @@ version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bitcoin = {version = "0.30"} +bitcoin = {version = "0.32.2"} bitcoin-test-utils = {path = "../bitcoin-test-utils"} dlc-manager = {path = "../dlc-manager"} -lightning = {version = "0.0.121"} -lightning-block-sync = {version = "0.0.121"} +lightning = {version = "0.0.124"} +lightning-block-sync = {version = "0.0.124"} reqwest = {version = "0.11", features = ["blocking", "json"]} serde = {version = "*", features = ["derive"]} simple-wallet = {path = "../simple-wallet"} diff --git a/electrs-blockchain-provider/src/lib.rs b/electrs-blockchain-provider/src/lib.rs index e60aefb3..91960966 100644 --- a/electrs-blockchain-provider/src/lib.rs +++ b/electrs-blockchain-provider/src/lib.rs @@ -5,6 +5,7 @@ use std::sync::Arc; use std::time::Duration; use bitcoin::consensus::Decodable; +use bitcoin::Amount; use bitcoin::{ block::Header, Block, BlockHash, Network, OutPoint, ScriptBuf, Transaction, TxOut, Txid, }; @@ -129,9 +130,7 @@ impl Blockchain for ElectrsBlockchainProvider { Ok(()) } - fn get_network( - &self, - ) -> Result { + fn get_network(&self) -> Result { Ok(self.network) } @@ -142,13 +141,14 @@ impl Blockchain for ElectrsBlockchainProvider { fn get_block_at_height(&self, height: u64) -> Result { let hash_at_height = self.get_text(&format!("block-height/{height}"))?; let raw_block = self.get_bytes(&format!("block/{hash_at_height}/raw"))?; - Block::consensus_decode(&mut std::io::Cursor::new(&*raw_block)) + // TODO: Bitcoin IO for all + Block::consensus_decode(&mut bitcoin::io::Cursor::new(&*raw_block)) .map_err(|e| Error::BlockchainError(e.to_string())) } fn get_transaction(&self, tx_id: &Txid) -> Result { let raw_tx = self.get_bytes(&format!("tx/{tx_id}/raw"))?; - Transaction::consensus_decode(&mut std::io::Cursor::new(&*raw_tx)) + Transaction::consensus_decode(&mut lightning::io::Cursor::new(&*raw_tx)) .map_err(|e| Error::BlockchainError(e.to_string())) } @@ -189,7 +189,7 @@ impl simple_wallet::WalletBlockchainProvider for ElectrsBlockchainProvider { redeem_script: ScriptBuf::default(), reserved: false, tx_out: TxOut { - value: x.value, + value: Amount::from_sat(x.value), script_pubkey: address.script_pubkey(), }, }) @@ -228,11 +228,17 @@ impl FeeEstimator for ElectrsBlockchainProvider { .get(&Target::Normal) .unwrap() .load(Ordering::Acquire), - ConfirmationTarget::OnChainSweep => self + ConfirmationTarget::UrgentOnChainSweep => self .fees .get(&Target::HighPriority) .unwrap() .load(Ordering::Acquire), + // TODO: Map all + _ => self + .fees + .get(&Target::Normal) + .unwrap() + .load(Ordering::Acquire), }; u32::max(est, MIN_FEERATE) } @@ -261,14 +267,14 @@ impl BlockSource for ElectrsBlockchainProvider { .await .map_err(BlockSourceError::transient)?; let header_hex = bitcoin_test_utils::str_to_hex(&header_hex_str); - let header = Header::consensus_decode(&mut std::io::Cursor::new(&*header_hex)) + let header = Header::consensus_decode(&mut lightning::io::Cursor::new(&*header_hex)) .expect("to have a valid header"); header.validate_pow(header.target()).unwrap(); Ok(BlockHeaderData { header, height: block_info.height, // Electrs doesn't seem to make this available. - chainwork: bitcoin::pow::Work::MAINNET_MIN, + chainwork: header.work(), }) }) } @@ -285,7 +291,7 @@ impl BlockSource for ElectrsBlockchainProvider { .bytes() .await .map_err(BlockSourceError::transient)?; - let block = Block::consensus_decode(&mut std::io::Cursor::new(&*block_raw)) + let block = Block::consensus_decode(&mut lightning::io::Cursor::new(&*block_raw)) .expect("to have a valid header"); Ok(BlockData::FullBlock(block)) }) diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index aea861b4..c98858ed 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -10,7 +10,7 @@ cargo-fuzz = true [dependencies] dlc-messages = {path = "../dlc-messages"} honggfuzz = "0.5" -lightning = {version = "0.0.121" } +lightning = {version = "0.0.124" } [workspace] members = ["."] diff --git a/mocks/Cargo.toml b/mocks/Cargo.toml index d543e6ba..56b5ac6a 100644 --- a/mocks/Cargo.toml +++ b/mocks/Cargo.toml @@ -5,10 +5,10 @@ name = "mocks" version = "0.1.0" [dependencies] -bitcoin = "0.30" +bitcoin = "0.32.2" dlc = {path = "../dlc"} dlc-manager = {path = "../dlc-manager"} dlc-messages = {path = "../dlc-messages"} -lightning = {version = "0.0.121"} -secp256k1-zkp = {version = "0.9.2", features = ["bitcoin_hashes", "global-context", "rand", "rand-std"]} +lightning = {version = "0.0.124"} +secp256k1-zkp = {version = "0.11.0", features = ["hashes", "global-context", "rand", "rand-std"]} simple-wallet = {path = "../simple-wallet"} diff --git a/mocks/src/mock_blockchain.rs b/mocks/src/mock_blockchain.rs index f1e7d109..cdb6b7ac 100644 --- a/mocks/src/mock_blockchain.rs +++ b/mocks/src/mock_blockchain.rs @@ -28,7 +28,7 @@ impl Blockchain for MockBlockchain { self.transactions.lock().unwrap().push(transaction.clone()); Ok(()) } - fn get_network(&self) -> Result { + fn get_network(&self) -> Result { Ok(bitcoin::Network::Regtest) } fn get_blockchain_height(&self) -> Result { @@ -43,7 +43,7 @@ impl Blockchain for MockBlockchain { .lock() .unwrap() .iter() - .find(|x| &x.txid() == tx_id) + .find(|x| &x.compute_txid() == tx_id) .unwrap() .clone()) } diff --git a/mocks/src/mock_oracle_provider.rs b/mocks/src/mock_oracle_provider.rs index 6610db71..144e3d83 100644 --- a/mocks/src/mock_oracle_provider.rs +++ b/mocks/src/mock_oracle_provider.rs @@ -1,3 +1,4 @@ +use bitcoin::hashes::Hash; use dlc_manager::error::Error as DaemonError; use dlc_manager::Oracle; use dlc_messages::oracle_msgs::{ @@ -7,13 +8,13 @@ use lightning::util::ser::Writeable; use secp256k1_zkp::rand::thread_rng; use secp256k1_zkp::SecretKey; use secp256k1_zkp::{All, Message, Secp256k1}; -use secp256k1_zkp::{KeyPair, XOnlyPublicKey}; +use secp256k1_zkp::{Keypair, XOnlyPublicKey}; use std::collections::HashMap; #[derive(Clone, Debug)] pub struct MockOracle { - key_pair: KeyPair, + key_pair: Keypair, secp: Secp256k1, announcements: HashMap, attestations: HashMap, @@ -23,7 +24,7 @@ pub struct MockOracle { impl MockOracle { pub fn new() -> Self { let secp = Secp256k1::new(); - let key_pair = KeyPair::new(&secp, &mut thread_rng()); + let key_pair = Keypair::new(&secp, &mut thread_rng()); MockOracle { secp, @@ -36,7 +37,7 @@ impl MockOracle { pub fn from_secret_key(sk: &SecretKey) -> Self { let secp = Secp256k1::new(); - let key_pair = KeyPair::from_secret_key(&secp, sk); + let key_pair = Keypair::from_secret_key(&secp, sk); MockOracle { secp, @@ -92,7 +93,7 @@ impl MockOracle { .collect(); let key_pairs: Vec<_> = priv_nonces .iter() - .map(|x| KeyPair::from_seckey_slice(&self.secp, x.as_ref()).unwrap()) + .map(|x| Keypair::from_seckey_slice(&self.secp, x.as_ref()).unwrap()) .collect(); let nonces = key_pairs @@ -117,7 +118,8 @@ impl MockOracle { oracle_event .write(&mut event_hex) .expect("Error writing oracle event"); - let msg = Message::from_hashed_data::(&event_hex); + let hash = bitcoin::hashes::sha256::Hash::hash(&event_hex).to_byte_array(); + let msg = Message::from_digest(hash); let sig = self.secp.sign_schnorr(&msg, &self.key_pair); let announcement = OracleAnnouncement { oracle_event, @@ -134,8 +136,8 @@ impl MockOracle { .iter() .zip(nonces.iter()) .map(|(x, nonce)| { - let msg = - Message::from_hashed_data::(x.as_bytes()); + let hash = bitcoin::hashes::sha256::Hash::hash(x.as_bytes()).to_byte_array(); + let msg = Message::from_digest(hash); dlc::secp_utils::schnorrsig_sign_with_nonce( &self.secp, &msg, diff --git a/mocks/src/mock_wallet.rs b/mocks/src/mock_wallet.rs index 01ac6e63..5bb062fc 100644 --- a/mocks/src/mock_wallet.rs +++ b/mocks/src/mock_wallet.rs @@ -1,7 +1,9 @@ use std::rc::Rc; -use bitcoin::psbt::PartiallySignedTransaction; +use bitcoin::psbt::Psbt; +use bitcoin::transaction::Version; use bitcoin::{absolute::LockTime, Address, OutPoint, ScriptBuf, Transaction, TxOut}; +use bitcoin::{Amount, CompressedPublicKey}; use dlc_manager::{error::Error, Blockchain, ContractSignerProvider, SimpleSigner, Utxo, Wallet}; use secp256k1_zkp::{rand::seq::SliceRandom, PublicKey, SecretKey}; @@ -17,11 +19,11 @@ impl MockWallet { for utxo_value in utxo_values { let tx_out = TxOut { - value: *utxo_value, + value: Amount::from_sat(*utxo_value), script_pubkey: ScriptBuf::default(), }; let tx = Transaction { - version: 2, + version: Version::TWO, lock_time: LockTime::ZERO, input: vec![], output: vec![tx_out.clone()], @@ -30,7 +32,7 @@ impl MockWallet { let utxo = Utxo { tx_out, outpoint: bitcoin::OutPoint { - txid: tx.txid(), + txid: tx.compute_txid(), vout: 0, }, address: get_address(), @@ -94,7 +96,7 @@ impl Wallet for MockWallet { if sum >= amount { return false; } - sum += x.tx_out.value; + sum += x.tx_out.value.to_sat(); true }) .cloned() @@ -111,7 +113,7 @@ impl Wallet for MockWallet { Ok(()) } - fn sign_psbt_input(&self, _: &mut PartiallySignedTransaction, _: usize) -> Result<(), Error> { + fn sign_psbt_input(&self, _: &mut Psbt, _: usize) -> Result<(), Error> { Ok(()) } @@ -121,14 +123,9 @@ impl Wallet for MockWallet { } fn get_address() -> Address { - Address::p2wpkh( - &bitcoin::PublicKey::from_private_key( - secp256k1_zkp::SECP256K1, - &bitcoin::PrivateKey::new(get_secret_key(), bitcoin::Network::Regtest), - ), - bitcoin::Network::Regtest, - ) - .unwrap() + let pk = bitcoin::PrivateKey::new(get_secret_key(), bitcoin::Network::Regtest); + let pubkey = CompressedPublicKey::from_private_key(secp256k1_zkp::SECP256K1, &pk).unwrap(); + Address::p2wpkh(&pubkey, bitcoin::Network::Regtest) } pub fn get_secret_key() -> SecretKey { diff --git a/p2pd-oracle-client/Cargo.toml b/p2pd-oracle-client/Cargo.toml index a28450d5..f8211c6a 100644 --- a/p2pd-oracle-client/Cargo.toml +++ b/p2pd-oracle-client/Cargo.toml @@ -12,7 +12,7 @@ chrono = {version = "0.4.19", features = ["serde"]} dlc-manager = {path = "../dlc-manager"} dlc-messages = {path = "../dlc-messages", features = ["use-serde"]} reqwest = {version = "0.11", features = ["blocking", "json"]} -secp256k1-zkp = {version = "0.9.2" } +secp256k1-zkp = {version = "0.11.0" } serde = {version = "*", features = ["derive"]} [dev-dependencies] diff --git a/p2pd-oracle-client/src/lib.rs b/p2pd-oracle-client/src/lib.rs index 10689cf6..91a7e2dc 100644 --- a/p2pd-oracle-client/src/lib.rs +++ b/p2pd-oracle-client/src/lib.rs @@ -75,7 +75,9 @@ where { reqwest::blocking::get(path) .map_err(|x| { - dlc_manager::error::Error::IOError(std::io::Error::new(std::io::ErrorKind::Other, x)) + dlc_manager::error::Error::IOError( + std::io::Error::new(std::io::ErrorKind::Other, x).into(), + ) })? .json::() .map_err(|e| dlc_manager::error::Error::OracleError(e.to_string())) diff --git a/sample/Cargo.toml b/sample/Cargo.toml index 83f11fcb..e936813c 100644 --- a/sample/Cargo.toml +++ b/sample/Cargo.toml @@ -5,15 +5,15 @@ name = "sample" version = "0.1.0" [dependencies] -bitcoin = {version = "0.30.2"} +bitcoin = {version = "0.32.2"} bitcoin-rpc-provider = {path = "../bitcoin-rpc-provider"} dlc = {path = "../dlc", features = ["use-serde"]} dlc-manager = {path = "../dlc-manager", features = ["use-serde", "parallel"]} dlc-messages = {path = "../dlc-messages"} dlc-sled-storage-provider = {path = "../dlc-sled-storage-provider"} futures = "0.3" -lightning = {version = "0.0.121"} -lightning-net-tokio = {version = "0.0.121" } +lightning = {version = "0.0.124"} +lightning-net-tokio = {version = "0.0.124" } p2pd-oracle-client = {path = "../p2pd-oracle-client"} serde = "1.0" serde_json = "1.0" diff --git a/sample/src/cli.rs b/sample/src/cli.rs index c76b235f..c55b3795 100644 --- a/sample/src/cli.rs +++ b/sample/src/cli.rs @@ -115,7 +115,7 @@ pub(crate) async fn poll_for_user_input( match parse_peer_info(peer_pubkey_and_ip_addr.unwrap().to_string()) { Ok(info) => info, Err(e) => { - println!("{:?}", e.into_inner().unwrap()); + println!("{:?}", e); print!("> "); io::stdout().flush().unwrap(); continue; @@ -146,7 +146,7 @@ pub(crate) async fn poll_for_user_input( match parse_peer_info(peer_pubkey_and_ip_addr.to_string()) { Ok(info) => info, Err(e) => { - println!("{:?}", e.into_inner().unwrap()); + println!("{:?}", e); print!("> "); io::stdout().flush().unwrap(); continue; @@ -507,8 +507,8 @@ fn help() { fn list_peers(peer_manager: Arc) { println!("\t{{"); - for (pubkey, _) in peer_manager.get_peer_node_ids() { - println!("\t\t pubkey: {}", pubkey); + for peer in peer_manager.list_peers() { + println!("\t\t pubkey: {}", peer.counterparty_node_id); } println!("\t}},"); } @@ -518,8 +518,8 @@ pub(crate) async fn connect_peer_if_necessary( peer_addr: SocketAddr, peer_manager: Arc, ) -> Result<(), ()> { - for (node_pubkey, _) in peer_manager.get_peer_node_ids() { - if node_pubkey == pubkey { + for peer in peer_manager.list_peers() { + if peer.counterparty_node_id == pubkey { return Ok(()); } } @@ -537,9 +537,9 @@ pub(crate) async fn connect_peer_if_necessary( } // Avoid blocking the tokio context by sleeping a bit match peer_manager - .get_peer_node_ids() + .list_peers() .iter() - .find(|id| id.0 == pubkey) + .find(|id| id.counterparty_node_id == pubkey) { Some(_) => break, None => tokio::time::sleep(Duration::from_millis(10)).await, diff --git a/sample/src/disk.rs b/sample/src/disk.rs index 02b421e7..54a50d83 100644 --- a/sample/src/disk.rs +++ b/sample/src/disk.rs @@ -1,6 +1,6 @@ use lightning::util::logger::{Logger, Record}; -use lightning::util::ser::Writer; use std::fs; +use std::io::Write; use time::OffsetDateTime; pub(crate) struct FilesystemLogger { @@ -26,6 +26,7 @@ impl Logger for FilesystemLogger { record.line, raw_log ); + let logs_file_path = format!("{}/logs.txt", self.data_dir.clone()); fs::OpenOptions::new() .create(true) diff --git a/simple-wallet/Cargo.toml b/simple-wallet/Cargo.toml index 1d680023..1e3ab5be 100644 --- a/simple-wallet/Cargo.toml +++ b/simple-wallet/Cargo.toml @@ -6,13 +6,13 @@ version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bitcoin = "0.30" +bdk_wallet = "1.0.0-beta.2" +bitcoin = "0.32.2" dlc = {path = "../dlc"} dlc-manager = {path = "../dlc-manager"} -lightning = {version = "0.0.121"} -bdk = {version = "0.29.0"} -secp256k1-zkp = {version = "0.9.2"} +lightning = {version = "0.0.124"} +secp256k1-zkp = {version = "0.11.0"} [dev-dependencies] mocks = {path = "../mocks"} -secp256k1-zkp = {version = "0.9.2", features = ["global-context"]} +secp256k1-zkp = {version = "0.11.0", features = ["global-context"]} diff --git a/simple-wallet/src/lib.rs b/simple-wallet/src/lib.rs index 73761641..a2ed414b 100644 --- a/simple-wallet/src/lib.rs +++ b/simple-wallet/src/lib.rs @@ -1,15 +1,15 @@ use std::ops::Deref; -use bdk::{ - database::{BatchOperations, Database}, - wallet::coin_selection::{BranchAndBoundCoinSelection, CoinSelectionAlgorithm}, - FeeRate, KeychainKind, LocalUtxo, Utxo as BdkUtxo, WeightedUtxo, +use bdk_wallet::{ + chain::ConfirmationTime, + coin_selection::{CoinSelectionAlgorithm, OldestFirstCoinSelection}, + KeychainKind, LocalOutput, Utxo as BdkUtxo, WeightedUtxo, }; use bitcoin::{ - hashes::Hash, Address, Network, OutPoint, Script, Sequence, Transaction, TxIn, TxOut, Txid, - Witness, + hashes::Hash, Address, Amount, CompressedPublicKey, FeeRate, Network, OutPoint, PrivateKey, + Sequence, Transaction, TxIn, TxOut, Txid, Weight, Witness, }; -use bitcoin::{psbt::PartiallySignedTransaction, ScriptBuf}; +use bitcoin::{psbt::Psbt, ScriptBuf}; use dlc_manager::{ error::Error, Blockchain, ContractSignerProvider, KeysId, SimpleSigner, Utxo, Wallet, }; @@ -101,7 +101,7 @@ where .get_utxos() .unwrap() .iter() - .map(|x| x.tx_out.value) + .map(|x| x.tx_out.value.to_sat()) .sum() } @@ -126,7 +126,7 @@ where return Err(Error::InvalidState("No utxo in wallet".to_string())); } - let mut total_value = 0; + let mut total_value = Amount::ZERO; let input = utxos .iter() .map(|x| { @@ -144,7 +144,7 @@ where script_pubkey: address.script_pubkey(), }]; let mut tx = Transaction { - version: 2, + version: bitcoin::transaction::Version(2), lock_time: bitcoin::absolute::LockTime::ZERO, input, output, @@ -155,11 +155,11 @@ where .blockchain .get_est_sat_per_1000_weight(ConfirmationTarget::NonAnchorChannelFee) as u64; - let fee = (weight * fee_rate) / 1000; + let fee = Amount::from_sat((weight * fee_rate) / 1000); tx.output[0].value -= fee; // construct psbt - let mut psbt = PartiallySignedTransaction::from_unsigned_tx(tx.clone()).unwrap(); + let mut psbt = Psbt::from_unsigned_tx(tx.clone()).unwrap(); for (i, utxo) in utxos.iter().enumerate().take(tx.input.len()) { psbt.inputs[i].witness_utxo = Some(utxo.tx_out.clone()); } @@ -168,7 +168,9 @@ where self.sign_psbt_input(&mut psbt, i)?; } - let tx = psbt.extract_tx(); + let tx = psbt + .extract_tx() + .expect("could not extract transaction from psbt"); self.blockchain.send_transaction(&tx) } @@ -222,15 +224,9 @@ where { fn get_new_address(&self) -> Result
{ let seckey = SecretKey::new(&mut thread_rng()); - let pubkey = PublicKey::from_secret_key(&self.secp_ctx, &seckey); - let address = Address::p2wpkh( - &bitcoin::PublicKey { - inner: pubkey, - compressed: true, - }, - self.network, - ) - .map_err(|x| Error::WalletError(Box::new(x)))?; + let privkey = PrivateKey::new(seckey, self.network); + let pubkey = CompressedPublicKey::from_private_key(&self.secp_ctx, &privkey).unwrap(); + let address = Address::p2wpkh(&pubkey, self.network); self.storage.upsert_address(&address, &seckey)?; Ok(address) } @@ -250,25 +246,34 @@ where .iter() .filter(|x| !x.reserved) .map(|x| WeightedUtxo { - utxo: BdkUtxo::Local(LocalUtxo { + utxo: BdkUtxo::Local(LocalOutput { outpoint: x.outpoint, txout: x.tx_out.clone(), keychain: KeychainKind::External, is_spent: false, + confirmation_time: ConfirmationTime::unconfirmed(1), + derivation_index: 1, }), - satisfaction_weight: 107, + satisfaction_weight: Weight::from_wu(107), }) .collect::>(); - let coin_selection = BranchAndBoundCoinSelection::default(); + let coin_selection = OldestFirstCoinSelection; let dummy_pubkey: PublicKey = "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798" .parse() .unwrap(); let dummy_drain = - ScriptBuf::new_v0_p2wpkh(&bitcoin::WPubkeyHash::hash(&dummy_pubkey.serialize())); - let fee_rate = FeeRate::from_sat_per_vb(fee_rate as f32); + ScriptBuf::new_p2wpkh(&bitcoin::WPubkeyHash::hash(&dummy_pubkey.serialize())); + let fee_rate = FeeRate::from_sat_per_vb(fee_rate).unwrap_or(FeeRate::BROADCAST_MIN); let selection = coin_selection - .coin_select(self, Vec::new(), utxos, fee_rate, amount, &dummy_drain) + .coin_select( + Vec::new(), + utxos, + fee_rate, + amount, + &dummy_drain, + &mut bitcoin::key::rand::thread_rng(), + ) .map_err(|e| Error::WalletError(Box::new(e)))?; let mut res = Vec::new(); for utxo in selection.selected { @@ -307,7 +312,7 @@ where fn sign_psbt_input( &self, - psbt: &mut PartiallySignedTransaction, + psbt: &mut Psbt, input_index: usize, ) -> std::result::Result<(), Error> { let tx_out = if let Some(input) = psbt.inputs.get(input_index) { @@ -342,7 +347,7 @@ where &mut tx, input_index, bitcoin::sighash::EcdsaSighashType::All, - tx_out.value, + tx_out.value.to_sat(), )?; let tx_input = tx.input[input_index].clone(); @@ -352,174 +357,6 @@ where } } -impl BatchOperations for SimpleWallet -where - B::Target: WalletBlockchainProvider, - W::Target: WalletStorage, -{ - fn set_script_pubkey( - &mut self, - _: &Script, - _: bdk::KeychainKind, - _: u32, - ) -> std::result::Result<(), bdk::Error> { - Ok(()) - } - - fn set_utxo(&mut self, _: &bdk::LocalUtxo) -> std::result::Result<(), bdk::Error> { - Ok(()) - } - - fn set_raw_tx(&mut self, _: &Transaction) -> std::result::Result<(), bdk::Error> { - Ok(()) - } - - fn set_tx(&mut self, _: &bdk::TransactionDetails) -> std::result::Result<(), bdk::Error> { - Ok(()) - } - - fn set_last_index( - &mut self, - _: bdk::KeychainKind, - _: u32, - ) -> std::result::Result<(), bdk::Error> { - Ok(()) - } - - fn set_sync_time(&mut self, _: bdk::database::SyncTime) -> std::result::Result<(), bdk::Error> { - Ok(()) - } - - fn del_script_pubkey_from_path( - &mut self, - _: bdk::KeychainKind, - _: u32, - ) -> std::result::Result, bdk::Error> { - Ok(None) - } - - fn del_path_from_script_pubkey( - &mut self, - _: &Script, - ) -> std::result::Result, bdk::Error> { - Ok(None) - } - - fn del_utxo( - &mut self, - _: &bitcoin::OutPoint, - ) -> std::result::Result, bdk::Error> { - Ok(None) - } - - fn del_raw_tx(&mut self, _: &Txid) -> std::result::Result, bdk::Error> { - Ok(None) - } - - fn del_tx( - &mut self, - _: &Txid, - _: bool, - ) -> std::result::Result, bdk::Error> { - Ok(None) - } - - fn del_last_index( - &mut self, - _: bdk::KeychainKind, - ) -> std::result::Result, bdk::Error> { - Ok(None) - } - - fn del_sync_time( - &mut self, - ) -> std::result::Result, bdk::Error> { - Ok(None) - } -} - -impl Database for SimpleWallet -where - B::Target: WalletBlockchainProvider, - W::Target: WalletStorage, -{ - fn check_descriptor_checksum>( - &mut self, - _: bdk::KeychainKind, - _: BY, - ) -> std::result::Result<(), bdk::Error> { - Ok(()) - } - - fn iter_script_pubkeys( - &self, - _: Option, - ) -> std::result::Result, bdk::Error> { - Ok(Vec::new()) - } - - fn iter_utxos(&self) -> std::result::Result, bdk::Error> { - Ok(Vec::new()) - } - - fn iter_raw_txs(&self) -> std::result::Result, bdk::Error> { - Ok(Vec::new()) - } - - fn iter_txs(&self, _: bool) -> std::result::Result, bdk::Error> { - Ok(Vec::new()) - } - - fn get_script_pubkey_from_path( - &self, - _: bdk::KeychainKind, - _: u32, - ) -> std::result::Result, bdk::Error> { - Ok(None) - } - - fn get_path_from_script_pubkey( - &self, - _: &Script, - ) -> std::result::Result, bdk::Error> { - Ok(None) - } - - fn get_utxo( - &self, - _: &bitcoin::OutPoint, - ) -> std::result::Result, bdk::Error> { - Ok(None) - } - - fn get_raw_tx(&self, _: &Txid) -> std::result::Result, bdk::Error> { - Ok(None) - } - - fn get_tx( - &self, - _: &Txid, - _: bool, - ) -> std::result::Result, bdk::Error> { - Ok(None) - } - - fn get_last_index(&self, _: bdk::KeychainKind) -> std::result::Result, bdk::Error> { - Ok(None) - } - - fn get_sync_time(&self) -> std::result::Result, bdk::Error> { - Ok(None) - } - - fn increment_last_index( - &mut self, - _: bdk::KeychainKind, - ) -> std::result::Result { - Ok(0) - } -} - #[cfg(test)] mod tests { use std::rc::Rc;