diff --git a/bitcoin-rpc-provider/src/lib.rs b/bitcoin-rpc-provider/src/lib.rs index 7fa1c687..23a3cdcc 100644 --- a/bitcoin-rpc-provider/src/lib.rs +++ b/bitcoin-rpc-provider/src/lib.rs @@ -11,6 +11,7 @@ use bitcoin::hashes::serde; use bitcoin::psbt::Psbt; use bitcoin::secp256k1::rand::thread_rng; use bitcoin::secp256k1::SecretKey; +use bitcoin::Amount; use bitcoin::{consensus::Decodable, Network, PrivateKey, Transaction, Txid}; use bitcoin::{secp256k1::PublicKey, Address, OutPoint, ScriptBuf, TxOut}; use bitcoincore_rpc::jsonrpc::serde_json; @@ -276,7 +277,7 @@ impl Wallet for BitcoinCoreProvider { fn get_utxos_for_amount( &self, - amount: u64, + amount: Amount, _fee_rate: u64, lock_utxos: bool, ) -> Result, ManagerError> { @@ -312,7 +313,8 @@ impl Wallet for BitcoinCoreProvider { }) .collect::, Error>>()?; // TODO(tibo): properly compute the cost of change - let selection = select_coins(amount, 20, &mut utxo_pool).ok_or(Error::NotEnoughCoins)?; + let selection = + select_coins(amount.to_sat(), 20, &mut utxo_pool).ok_or(Error::NotEnoughCoins)?; if lock_utxos { let outputs: Vec<_> = selection.iter().map(|x| x.0.outpoint).collect(); diff --git a/dlc-manager/benches/benchmarks.rs b/dlc-manager/benches/benchmarks.rs index a8062f14..18e12eb0 100644 --- a/dlc-manager/benches/benchmarks.rs +++ b/dlc-manager/benches/benchmarks.rs @@ -1,4 +1,5 @@ use bitcoin::hashes::Hash; +use bitcoin::Amount; use bitcoin::OutPoint; use bitcoin::ScriptBuf; use bitcoin::WPubkeyHash; @@ -49,7 +50,7 @@ const THRESHOLD: usize = 2; /// The ID of the event. const EVENT_ID: &str = "Test"; /// The total collateral value locked in the contract. -const TOTAL_COLLATERAL: u64 = 200000000; +const TOTAL_COLLATERAL: Amount = Amount::from_sat(200000000); fn max_value() -> u32 { BASE.pow(NB_DIGITS as u32) - 1 @@ -71,12 +72,12 @@ fn create_contract_descriptor() -> ContractDescriptor { PolynomialPayoutCurvePiece::new(vec![ PayoutPoint { event_outcome: 0, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: FLOOR, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, ]) @@ -86,7 +87,7 @@ fn create_contract_descriptor() -> ContractDescriptor { PolynomialPayoutCurvePiece::new(vec![ PayoutPoint { event_outcome: FLOOR, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { @@ -189,8 +190,8 @@ fn create_transactions(payouts: &[Payout]) -> DlcTransactions { payout_script_pubkey: get_p2wpkh_script_pubkey(), payout_serial_id: 1, inputs: create_txinputinfo_vec(), - input_amount: 300000000, - collateral: 100000000, + input_amount: Amount::from_sat(300000000), + collateral: Amount::from_sat(100000000), }; let accept_params = PartyParams { @@ -200,8 +201,8 @@ fn create_transactions(payouts: &[Payout]) -> DlcTransactions { payout_script_pubkey: get_p2wpkh_script_pubkey(), payout_serial_id: 1, inputs: create_txinputinfo_vec(), - input_amount: 300000000, - collateral: 100000000, + input_amount: Amount::from_sat(300000000), + collateral: Amount::from_sat(100000000), }; create_dlc_transactions(&offer_params, &accept_params, payouts, 1000, 2, 0, 1000, 3).unwrap() } @@ -221,7 +222,11 @@ fn offer_seckey() -> SecretKey { /// Benchmark to measure the adaptor signature creation time. pub fn sign_bench(c: &mut Criterion) { let contract_info = create_contract_info(); - let dlc_transactions = create_transactions(&contract_info.get_payouts(200000000).unwrap()); + let dlc_transactions = create_transactions( + &contract_info + .get_payouts(Amount::from_sat(200000000)) + .unwrap(), + ); let fund_output_value = dlc_transactions.get_fund_output().value; let seckey = accept_seckey(); @@ -234,7 +239,7 @@ pub fn sign_bench(c: &mut Criterion) { TOTAL_COLLATERAL, &seckey, &dlc_transactions.funding_script_pubkey, - fund_output_value.to_sat(), + fund_output_value, &dlc_transactions.cets, 0, ) @@ -247,7 +252,11 @@ pub fn sign_bench(c: &mut Criterion) { /// Benchmark to measure the adaptor signature verification time. pub fn verify_bench(c: &mut Criterion) { let contract_info = create_contract_info(); - let dlc_transactions = create_transactions(&contract_info.get_payouts(200000000).unwrap()); + let dlc_transactions = create_transactions( + &contract_info + .get_payouts(Amount::from_sat(200000000)) + .unwrap(), + ); let fund_output_value = dlc_transactions.get_fund_output().value; let seckey = accept_seckey(); @@ -258,7 +267,7 @@ pub fn verify_bench(c: &mut Criterion) { TOTAL_COLLATERAL, &seckey, &dlc_transactions.funding_script_pubkey, - fund_output_value.to_sat(), + fund_output_value, &dlc_transactions.cets, 0, ) @@ -272,7 +281,7 @@ pub fn verify_bench(c: &mut Criterion) { SECP256K1, &pubkey, &dlc_transactions.funding_script_pubkey, - fund_output_value.to_sat(), + fund_output_value, &dlc_transactions.cets, adaptor_signatures, 0, diff --git a/dlc-manager/src/channel/signed_channel.rs b/dlc-manager/src/channel/signed_channel.rs index 82f8b271..14e8cd24 100644 --- a/dlc-manager/src/channel/signed_channel.rs +++ b/dlc-manager/src/channel/signed_channel.rs @@ -2,7 +2,7 @@ //! transaction inputs. This module contains the model for a signed channel, //! the possible states in which it can be as well as methods to work with it. -use bitcoin::{ScriptBuf, Transaction}; +use bitcoin::{Amount, ScriptBuf, Transaction}; use dlc::PartyParams; use lightning::ln::chan_utils::CounterpartyCommitmentSecrets; use secp256k1_zkp::{ecdsa::Signature, EcdsaAdaptorSignature, PublicKey}; @@ -108,7 +108,7 @@ typed_enum!( /// state change. is_offer: bool, /// The total amount of collateral in the channel - total_collateral: u64, + total_collateral: Amount, /// Keys Id for generating the signers keys_id: KeysId, }, @@ -116,7 +116,7 @@ typed_enum!( /// has sent a [`dlc_messages::channel::SettleOffer`] message. SettledOffered { /// The payout that was proposed to the counter party. - counter_payout: u64, + counter_payout: Amount, /// The per update point that the local party would use for the next /// channel state. next_per_update_point: PublicKey, @@ -130,9 +130,9 @@ typed_enum!( /// has received a [`dlc_messages::channel::SettleOffer`] message. SettledReceived { /// The payout that was proposed to the local party to settle the channel. - own_payout: u64, + own_payout: Amount, /// The payout that was proposed to the counter party. - counter_payout: u64, + counter_payout: Amount, /// The per update point to be used by the counter party for the setup /// of the next channel state. counter_next_per_update_point: PublicKey, @@ -157,9 +157,9 @@ typed_enum!( /// unresponsive and the channel will be forced closed. timeout: u64, /// The payout to the local party after settling the channel. - own_payout: u64, + own_payout: Amount, /// The payout that was proposed to the counter party. - counter_payout: u64, + counter_payout: Amount, /// Keys Id for generating the signers keys_id: KeysId, }, @@ -184,9 +184,9 @@ typed_enum!( /// unresponsive and the channel will be forced closed. timeout: u64, /// The payout to the local party after settling the channel. - own_payout: u64, + own_payout: Amount, /// The payout that was proposed to the counter party. - counter_payout: u64, + counter_payout: Amount, /// Keys Id for generating the signers keys_id: KeysId, }, @@ -203,9 +203,9 @@ typed_enum!( /// local party. own_settle_adaptor_signature: EcdsaAdaptorSignature, /// The amount the local party holds in the channel. - own_payout: u64, + own_payout: Amount, /// The amount the counter party holds in the channel. - counter_payout: u64, + counter_payout: Amount, /// Keys Id for generating the signers keys_id: KeysId, }, @@ -215,7 +215,7 @@ typed_enum!( /// The temporary [`crate::ContractId`] of the offered contract. offered_contract_id: ContractId, /// The payout offered to settle the previous channel state. - counter_payout: u64, + counter_payout: Amount, /// The per update point to be used by the offer party for the setup /// of the next channel state. offer_next_per_update_point: PublicKey, @@ -246,7 +246,7 @@ typed_enum!( /// unresponsive and the channel will be forced closed. timeout: u64, /// The payout to the local party attributed for closing the previous state. - own_payout: u64, + own_payout: Amount, /// Keys Id for generating the signers keys_id: KeysId, }, @@ -272,9 +272,9 @@ typed_enum!( /// unresponsive and the channel will be forced closed. timeout: u64, /// The payout to the local party attributed for closing the previous state. - own_payout: u64, + own_payout: Amount, /// The total amount of collateral in the channel. - total_collateral: u64, + total_collateral: Amount, /// Keys Id for generating the signers keys_id: KeysId, }, @@ -299,9 +299,9 @@ typed_enum!( /// unresponsive and the channel will be forced closed. timeout: u64, /// The payout to the local party attributed for closing the previous state. - own_payout: u64, + own_payout: Amount, /// The total amount of collateral in the channel. - total_collateral: u64, + total_collateral: Amount, /// Keys Id for generating the signers keys_id: KeysId, }, @@ -323,7 +323,7 @@ typed_enum!( /// has sent a [`dlc_messages::channel::CollaborativeCloseOffer`] message. CollaborativeCloseOffered { /// The payout offered to the counter party to close the channel. - counter_payout: u64, + counter_payout: Amount, /// The signature of the local party for the closing transaction. offer_signature: Signature, /// The closing transaction. diff --git a/dlc-manager/src/channel_updater.rs b/dlc-manager/src/channel_updater.rs index ae026c52..cfc57d65 100644 --- a/dlc-manager/src/channel_updater.rs +++ b/dlc-manager/src/channel_updater.rs @@ -25,7 +25,7 @@ use crate::{ Blockchain, ChannelId, ContractId, ContractSigner, ContractSignerProvider, KeysId, Time, Wallet, }; -use bitcoin::{OutPoint, Script, ScriptBuf, Sequence, Transaction, TxIn, Witness}; +use bitcoin::{Amount, OutPoint, Script, ScriptBuf, Sequence, Transaction, TxIn, Witness}; use dlc::{ channel::{get_tx_adaptor_signature, verify_tx_adaptor_signature, DlcChannelTransactions}, PartyParams, @@ -228,7 +228,7 @@ where let buffer_adaptor_signature = get_tx_adaptor_signature( secp, &buffer_transaction, - dlc_transactions.get_fund_output().value.to_sat(), + dlc_transactions.get_fund_output().value, &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.to_sat(), + buffer_transaction.output[0].value, Some(&buffer_script_pubkey), &dlc_transactions, )?; @@ -363,7 +363,7 @@ where &accept_channel.funding_inputs, &accept_channel.refund_signature, &accept_cet_adaptor_signatures, - buffer_transaction.output[0].value.to_sat(), + buffer_transaction.output[0].value, 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.to_sat(), + dlc_transactions.get_fund_output().value, &dlc_transactions.funding_script_pubkey, &signed_contract.accepted_contract.accept_params.fund_pubkey, &offer_revoke_params.publish_pk.inner, @@ -385,7 +385,7 @@ where let own_buffer_adaptor_signature = get_tx_adaptor_signature( secp, &buffer_transaction, - dlc_transactions.get_fund_output().value.to_sat(), + dlc_transactions.get_fund_output().value, &dlc_transactions.funding_script_pubkey, &offer_fund_sk.get_secret_key()?, &accept_revoke_params.publish_pk.inner, @@ -471,11 +471,7 @@ where verify_tx_adaptor_signature( secp, &accepted_channel.buffer_transaction, - accepted_contract - .dlc_transactions - .get_fund_output() - .value - .to_sat(), + accepted_contract.dlc_transactions.get_fund_output().value, &accepted_contract.dlc_transactions.funding_script_pubkey, &accepted_contract.offered_contract.offer_params.fund_pubkey, &own_publish_pk, @@ -490,7 +486,7 @@ where &sign_channel.refund_signature, &cet_adaptor_signatures, &sign_channel.funding_signatures, - accepted_channel.buffer_transaction.output[0].value.to_sat(), + accepted_channel.buffer_transaction.output[0].value, Some(&accepted_channel.buffer_script_pubkey), Some(counter_own_pk), wallet, @@ -556,7 +552,7 @@ where pub fn settle_channel_offer( secp: &Secp256k1, channel: &mut SignedChannel, - counter_payout: u64, + counter_payout: Amount, peer_timeout: u64, signer_provider: &SP, time: &T, @@ -689,9 +685,9 @@ where let total_collateral = channel.counter_params.collateral + channel.own_params.collateral; //Todo(tibo): compute fee for settle transaction. - let fee_remainder = 0; //channel.fund_tx.output[channel.fund_output_index].value - total_collateral; - let final_offer_payout = total_collateral - own_payout + fee_remainder / 2; - let final_accept_payout = own_payout + fee_remainder / 2; + let fee_remainder = 0_u64; //channel.fund_tx.output[channel.fund_output_index].value - total_collateral; + let final_offer_payout = total_collateral - own_payout + Amount::from_sat(fee_remainder / 2); + let final_accept_payout = own_payout + Amount::from_sat(fee_remainder / 2); let fund_tx = &channel.fund_tx; let fund_vout = channel.fund_output_index; @@ -780,9 +776,10 @@ where let total_collateral = channel.counter_params.collateral + channel.own_params.collateral; //Todo(tibo): compute fee for settle transaction. - let fee_remainder = 0; //channel.fund_tx.output[channel.fund_output_index].value - total_collateral; - let final_offer_payout = total_collateral - counter_payout + fee_remainder / 2; - let final_accept_payout = counter_payout + fee_remainder / 2; + let fee_remainder = 0_u64; //channel.fund_tx.output[channel.fund_output_index].value - total_collateral; + let final_offer_payout = + total_collateral - counter_payout + Amount::from_sat(fee_remainder / 2); + let final_accept_payout = counter_payout + Amount::from_sat(fee_remainder / 2); let fund_tx = &channel.fund_tx; let fund_vout = channel.fund_output_index; @@ -909,9 +906,7 @@ where verify_tx_adaptor_signature( secp, settle_tx, - channel.fund_tx.output[channel.fund_output_index] - .value - .to_sat(), + channel.fund_tx.output[channel.fund_output_index].value, &channel.fund_script_pubkey, &channel.counter_params.fund_pubkey, &accept_revoke_params.publish_pk.inner, @@ -1067,7 +1062,7 @@ pub fn renew_offer( signed_channel: &mut SignedChannel, contract_input: &ContractInput, oracle_announcements: Vec>, - counter_payout: u64, + counter_payout: Amount, refund_delay: u32, peer_timeout: u64, cet_nsequence: u32, @@ -1313,7 +1308,7 @@ where &signed_channel.own_params, &[], &own_secret_key, - buffer_transaction.output[0].value.to_sat(), + buffer_transaction.output[0].value, Some(&buffer_script_pubkey), &dlc_transactions, )?; @@ -1386,8 +1381,8 @@ where let total_collateral = offered_contract.total_collateral; - let own_payout = - total_collateral - get_signed_channel_state!(signed_channel, RenewOffered, counter_payout)?; + let own_payout = total_collateral + - get_signed_channel_state!(signed_channel, RenewOffered, counter_payout)?.to_owned(); let DlcChannelTransactions { buffer_transaction, @@ -1417,7 +1412,7 @@ where &[], &renew_accept.refund_signature, &cet_adaptor_signatures, - buffer_transaction.output[0].value.to_sat(), + buffer_transaction.output[0].value, wallet, &offer_own_sk, Some(&buffer_script_pubkey), @@ -1429,7 +1424,7 @@ where let own_buffer_adaptor_signature = get_tx_adaptor_signature( secp, &buffer_transaction, - dlc_transactions.get_fund_output().value.to_sat(), + dlc_transactions.get_fund_output().value, &dlc_transactions.funding_script_pubkey, &contract_signer.get_secret_key()?, &accept_revoke_params.publish_pk.inner, @@ -1510,9 +1505,7 @@ where verify_tx_adaptor_signature( secp, buffer_transaction, - signed_channel.fund_tx.output[signed_channel.fund_output_index] - .value - .to_sat(), + signed_channel.fund_tx.output[signed_channel.fund_output_index].value, &signed_channel.fund_script_pubkey, counter_buffer_own_pk, &own_publish_pk, @@ -1528,7 +1521,7 @@ where &FundingSignatures { funding_signatures: Vec::new(), }, - buffer_transaction.output[0].value.to_sat(), + buffer_transaction.output[0].value, Some(buffer_script_pubkey), Some(counter_own_pk), wallet, @@ -1559,7 +1552,7 @@ where let buffer_adaptor_signature = get_tx_adaptor_signature( secp, buffer_transaction, - buffer_input_value.to_sat(), + buffer_input_value, &signed_channel.fund_script_pubkey, &own_fund_sk, &offer_revoke_params.publish_pk.inner, @@ -1638,7 +1631,7 @@ where verify_tx_adaptor_signature( secp, buffer_transaction, - buffer_input_value.to_sat(), + buffer_input_value, &signed_channel.fund_script_pubkey, counter_buffer_own_pk, &offer_revoke_params.publish_pk.inner, @@ -1776,7 +1769,7 @@ pub fn reject_renew_offer(signed_channel: &mut SignedChannel) -> Result( secp: &Secp256k1, signed_channel: &mut SignedChannel, - counter_payout: u64, + counter_payout: Amount, signer_provider: &SP, time: &T, ) -> Result<(CollaborativeCloseOffer, Transaction), Error> @@ -1806,7 +1799,7 @@ where txid: signed_channel.fund_tx.compute_txid(), vout: signed_channel.fund_output_index as u32, }, - fund_output_value.to_sat(), + fund_output_value, ); let keys_id = signed_channel @@ -1819,7 +1812,7 @@ where &close_tx, 0, &signed_channel.fund_script_pubkey, - fund_output_value.to_sat(), + fund_output_value, &contract_signer.get_secret_key()?, )?; @@ -1881,7 +1874,7 @@ where txid: signed_channel.fund_tx.compute_txid(), vout: signed_channel.fund_output_index as u32, }, - fund_output_value.to_sat(), + fund_output_value, ); let mut state = SignedChannelState::CollaborativeCloseOffered { @@ -1930,7 +1923,7 @@ where &signed_channel.counter_params.fund_pubkey, &own_fund_sk, &signed_channel.fund_script_pubkey, - fund_out_amount.to_sat(), + fund_out_amount, 0, )?; @@ -1953,8 +1946,8 @@ fn get_settle_tx_and_adaptor_sig( offer_points: &PartyBasePoints, accept_points: &PartyBasePoints, counter_per_update_point: &PublicKey, - offer_payout: u64, - accept_payout: u64, + offer_payout: Amount, + accept_payout: Amount, csv_timelock: u32, lock_time: u32, counter_adaptor_signature: Option<(&EcdsaAdaptorSignature, PublicKey)>, @@ -1997,7 +1990,7 @@ fn get_settle_tx_and_adaptor_sig( accept_payout, csv_timelock, lock_time, - fund_tx.output[fund_vout].value.to_sat(), + fund_tx.output[fund_vout].value, fee_rate_per_vb, )?; @@ -2005,7 +1998,7 @@ fn get_settle_tx_and_adaptor_sig( verify_tx_adaptor_signature( secp, &settle_tx, - fund_tx.output[fund_vout].value.to_sat(), + fund_tx.output[fund_vout].value, funding_script_pubkey, &fund_pk, &offer_revoke_params.publish_pk.inner, @@ -2022,7 +2015,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.to_sat(), + fund_tx.output[fund_vout].value, funding_script_pubkey, own_fund_sk, &counter_pk, @@ -2095,9 +2088,7 @@ 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 - .to_sat(), + signed_channel.fund_tx.output[signed_channel.fund_output_index].value, 0, )?; @@ -2203,7 +2194,7 @@ where dlc::channel::sign_cet( secp, &mut cet, - buffer_transaction.output[0].value.to_sat(), + buffer_transaction.output[0].value, &offer_revoke_params, &accept_revoke_params, &own_sk, @@ -2263,9 +2254,7 @@ 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 - .to_sat(), + signed_channel.fund_tx.output[signed_channel.fund_output_index].value, 0, )?; diff --git a/dlc-manager/src/contract/accepted_contract.rs b/dlc-manager/src/contract/accepted_contract.rs index 6e507170..f071b858 100644 --- a/dlc-manager/src/contract/accepted_contract.rs +++ b/dlc-manager/src/contract/accepted_contract.rs @@ -1,8 +1,9 @@ //! # AcceptedContract +use crate::Error; use super::offered_contract::OfferedContract; use super::AdaptorInfo; -use bitcoin::Transaction; +use bitcoin::{Amount, SignedAmount, Transaction}; use dlc::{DlcTransactions, PartyParams}; use dlc_messages::{AcceptDlc, FundingInput}; use secp256k1_zkp::ecdsa::Signature; @@ -75,27 +76,28 @@ impl AcceptedContract { } /// Compute the profit and loss for this contract and an assciated cet index - pub fn compute_pnl(&self, cet: &Transaction) -> i64 { + pub fn compute_pnl(&self, cet: &Transaction) -> Result { let offer = &self.offered_contract; let party_params = if offer.is_offer_party { &offer.offer_params } else { &self.accept_params }; - let collateral = party_params.collateral as i64; + let collateral = party_params.collateral; let v0_witness_payout_script = &party_params.payout_script_pubkey; let final_payout = cet .output .iter() .find_map(|x| { if &x.script_pubkey == v0_witness_payout_script { - Some(x.value.to_sat()) + Some(x.value) } else { None } }) - .unwrap_or(0) as i64; - final_payout - collateral + .unwrap_or(Amount::ZERO); + Ok(final_payout.to_signed().map_err(|_| Error::OutOfRange)? + - collateral.to_signed().map_err(|_| Error::OutOfRange)?) } } @@ -112,10 +114,15 @@ mod tests { let buf = include_bytes!("../../../dlc-sled-storage-provider/test_files/Accepted"); let accepted_contract: AcceptedContract = Readable::read(&mut Cursor::new(&buf)).unwrap(); let cets = &accepted_contract.dlc_transactions.cets; - assert_eq!(accepted_contract.compute_pnl(&cets[0]), 90000000); assert_eq!( - accepted_contract.compute_pnl(&cets[cets.len() - 1]), - -11000000 + accepted_contract.compute_pnl(&cets[0]).unwrap(), + SignedAmount::from_sat(90000000) + ); + assert_eq!( + accepted_contract + .compute_pnl(&cets[cets.len() - 1]) + .unwrap(), + SignedAmount::from_sat(-11000000) ); } } diff --git a/dlc-manager/src/contract/contract_info.rs b/dlc-manager/src/contract/contract_info.rs index 8c1ece79..943a660e 100644 --- a/dlc-manager/src/contract/contract_info.rs +++ b/dlc-manager/src/contract/contract_info.rs @@ -5,6 +5,7 @@ use super::ContractDescriptor; use crate::error::Error; use crate::ContractSigner; use bitcoin::hashes::Hash; +use bitcoin::Amount; use bitcoin::{Script, Transaction}; use dlc::{OracleInfo, Payout}; use dlc_messages::oracle_msgs::{EventDescriptor, OracleAnnouncement}; @@ -35,7 +36,7 @@ pub struct ContractInfo { impl ContractInfo { /// Get the payouts associated with the contract. - pub fn get_payouts(&self, total_collateral: u64) -> Result, Error> { + pub fn get_payouts(&self, total_collateral: Amount) -> Result, Error> { match &self.contract_descriptor { ContractDescriptor::Enum(e) => Ok(e.get_payouts()), ContractDescriptor::Numerical(n) => n.get_payouts(total_collateral), @@ -69,7 +70,7 @@ impl ContractInfo { adaptor_info: &AdaptorInfo, signer: &S, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, cets: &[Transaction], ) -> Result, Error> where @@ -113,10 +114,10 @@ impl ContractInfo { pub fn verify_and_get_adaptor_info( &self, secp: &Secp256k1, - total_collateral: u64, + total_collateral: Amount, fund_pubkey: &PublicKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, cets: &[Transaction], adaptor_sigs: &[EcdsaAdaptorSignature], adaptor_sig_start: usize, @@ -191,7 +192,7 @@ impl ContractInfo { secp: &Secp256k1, fund_pubkey: &PublicKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, cets: &[Transaction], adaptor_sigs: &[EcdsaAdaptorSignature], adaptor_sig_start: usize, @@ -238,10 +239,10 @@ impl ContractInfo { pub fn get_adaptor_info( &self, secp: &Secp256k1, - total_collateral: u64, + total_collateral: Amount, fund_priv_key: &SecretKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, cets: &[Transaction], adaptor_index_start: usize, ) -> Result<(AdaptorInfo, Vec), Error> { diff --git a/dlc-manager/src/contract/contract_input.rs b/dlc-manager/src/contract/contract_input.rs index ad5ed1af..24f25960 100644 --- a/dlc-manager/src/contract/contract_input.rs +++ b/dlc-manager/src/contract/contract_input.rs @@ -3,6 +3,7 @@ use crate::error::Error; use super::ContractDescriptor; +use bitcoin::Amount; use secp256k1_zkp::XOnlyPublicKey; #[cfg(feature = "use-serde")] use serde::{Deserialize, Serialize}; @@ -73,9 +74,9 @@ pub struct ContractInputInfo { /// Contains all the information necessary for the initialization of a DLC. pub struct ContractInput { /// The collateral for the offering party. - pub offer_collateral: u64, + pub offer_collateral: Amount, /// The collateral for the accepting party. - pub accept_collateral: u64, + pub accept_collateral: Amount, /// The fee rate used to construct the transactions. pub fee_rate: u64, /// The set of contract that make up the DLC (a single DLC can be based @@ -112,8 +113,8 @@ mod tests { fn get_base_input() -> ContractInput { ContractInput { - offer_collateral: 1000000, - accept_collateral: 2000000, + offer_collateral: Amount::from_sat(1000000), + accept_collateral: Amount::from_sat(2000000), fee_rate: 1234, contract_infos: vec![ContractInputInfo { contract_descriptor: ContractDescriptor::Enum(EnumDescriptor { @@ -121,15 +122,15 @@ mod tests { EnumerationPayout { outcome: "A".to_string(), payout: Payout { - offer: 3000000, - accept: 0, + offer: Amount::from_sat(3000000), + accept: Amount::ZERO, }, }, EnumerationPayout { outcome: "B".to_string(), payout: Payout { - offer: 0, - accept: 3000000, + offer: Amount::ZERO, + accept: Amount::from_sat(3000000), }, }, ], diff --git a/dlc-manager/src/contract/enum_descriptor.rs b/dlc-manager/src/contract/enum_descriptor.rs index bb5c4bff..0224f1ba 100644 --- a/dlc-manager/src/contract/enum_descriptor.rs +++ b/dlc-manager/src/contract/enum_descriptor.rs @@ -5,7 +5,7 @@ use super::utils::{get_majority_combination, unordered_equal}; use super::AdaptorInfo; use crate::error::Error; use bitcoin::hashes::Hash; -use bitcoin::{Script, Transaction}; +use bitcoin::{Amount, Script, Transaction}; use dlc::OracleInfo; use dlc::{EnumerationPayout, Payout}; use dlc_messages::oracle_msgs::EnumEventDescriptor; @@ -117,7 +117,7 @@ impl EnumDescriptor { threshold: usize, fund_pubkey: &PublicKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, cets: &[Transaction], adaptor_sigs: &[EcdsaAdaptorSignature], adaptor_sig_start: usize, @@ -152,7 +152,7 @@ impl EnumDescriptor { threshold: usize, fund_pubkey: &PublicKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, cets: &[Transaction], adaptor_sigs: &[EcdsaAdaptorSignature], adaptor_sig_start: usize, @@ -180,7 +180,7 @@ impl EnumDescriptor { threshold: usize, fund_privkey: &SecretKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, cets: &[Transaction], ) -> Result<(AdaptorInfo, Vec), Error> { let adaptor_sigs = self.get_adaptor_signatures( @@ -205,7 +205,7 @@ impl EnumDescriptor { cets: &[Transaction], fund_privkey: &SecretKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, ) -> Result, Error> { let mut adaptor_sigs = Vec::new(); let mut callback = diff --git a/dlc-manager/src/contract/mod.rs b/dlc-manager/src/contract/mod.rs index 155cee03..3365a3d3 100644 --- a/dlc-manager/src/contract/mod.rs +++ b/dlc-manager/src/contract/mod.rs @@ -2,7 +2,7 @@ use crate::error::Error; use crate::ContractId; -use bitcoin::Transaction; +use bitcoin::{SignedAmount, Transaction}; use dlc_messages::{ oracle_msgs::{EventDescriptor, OracleAnnouncement, OracleAttestation}, AcceptDlc, SignDlc, @@ -169,7 +169,7 @@ pub struct ClosedContract { /// The public key of the counter-party's node. pub counter_party_id: PublicKey, /// The profit and loss for the given contract - pub pnl: i64, + pub pnl: SignedAmount, } /// Information about the adaptor signatures and the CET for which they are diff --git a/dlc-manager/src/contract/numerical_descriptor.rs b/dlc-manager/src/contract/numerical_descriptor.rs index 6ae535b7..cd93f074 100644 --- a/dlc-manager/src/contract/numerical_descriptor.rs +++ b/dlc-manager/src/contract/numerical_descriptor.rs @@ -3,7 +3,7 @@ use super::AdaptorInfo; use crate::error::Error; use crate::payout_curve::{PayoutFunction, RoundingIntervals}; -use bitcoin::{Script, Transaction}; +use bitcoin::{Amount, Script, Transaction}; use dlc::{Payout, RangePayout}; use dlc_trie::multi_oracle_trie::MultiOracleTrie; use dlc_trie::multi_oracle_trie_with_diff::MultiOracleTrieWithDiff; @@ -55,7 +55,7 @@ pub struct NumericalDescriptor { impl NumericalDescriptor { /// Returns the set of RangePayout for the descriptor generated from the /// payout function. - pub fn get_range_payouts(&self, total_collateral: u64) -> Result, Error> { + pub fn get_range_payouts(&self, total_collateral: Amount) -> Result, Error> { self.payout_function .to_range_payouts(total_collateral, &self.rounding_intervals) } @@ -69,7 +69,7 @@ impl NumericalDescriptor { /// Returns the set of payouts for the descriptor generated from the payout /// function. - pub fn get_payouts(&self, total_collateral: u64) -> Result, Error> { + pub fn get_payouts(&self, total_collateral: Amount) -> Result, Error> { Ok(self .get_range_payouts(total_collateral)? .iter() @@ -81,10 +81,10 @@ impl NumericalDescriptor { pub fn verify_and_get_adaptor_info( &self, secp: &Secp256k1, - total_collateral: u64, + total_collateral: Amount, fund_pubkey: &PublicKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, threshold: usize, precomputed_points: &[Vec>], cets: &[Transaction], @@ -134,10 +134,10 @@ impl NumericalDescriptor { pub fn get_adaptor_info( &self, secp: &Secp256k1, - total_collateral: u64, + total_collateral: Amount, fund_priv_key: &SecretKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, threshold: usize, precomputed_points: &[Vec>], cets: &[Transaction], diff --git a/dlc-manager/src/contract/offered_contract.rs b/dlc-manager/src/contract/offered_contract.rs index 6f40badb..25102beb 100644 --- a/dlc-manager/src/contract/offered_contract.rs +++ b/dlc-manager/src/contract/offered_contract.rs @@ -9,6 +9,7 @@ use super::contract_info::ContractInfo; use super::contract_input::ContractInput; use super::ContractDescriptor; use crate::{ContractId, KeysId}; +use bitcoin::Amount; use dlc::PartyParams; use dlc_messages::oracle_msgs::OracleAnnouncement; use dlc_messages::{FundingInput, OfferDlc}; @@ -34,7 +35,7 @@ pub struct OfferedContract { /// The parameters of the offering party. pub offer_params: PartyParams, /// The sum of both parties collateral. - pub total_collateral: u64, + pub total_collateral: Amount, /// Information about the offering party's funding inputs. pub funding_inputs: Vec, /// The serial id of the fund output used for output ordering. diff --git a/dlc-manager/src/contract/ser.rs b/dlc-manager/src/contract/ser.rs index d05655ab..d8fee842 100644 --- a/dlc-manager/src/contract/ser.rs +++ b/dlc-manager/src/contract/ser.rs @@ -136,7 +136,7 @@ impl_dlc_writeable!(ClosedContract, { (contract_id, writeable), (temporary_contract_id, writeable), (counter_party_id, writeable), - (pnl, i64) + (pnl, SignedAmount) }); impl_dlc_writeable!(FailedAcceptContract, {(offered_contract, writeable), (accept_message, writeable), (error_message, string)}); impl_dlc_writeable!(FailedSignContract, {(accepted_contract, writeable), (sign_message, writeable), (error_message, string)}); diff --git a/dlc-manager/src/contract_updater.rs b/dlc-manager/src/contract_updater.rs index 939da0c3..dc8054ca 100644 --- a/dlc-manager/src/contract_updater.rs +++ b/dlc-manager/src/contract_updater.rs @@ -3,6 +3,7 @@ use std::ops::Deref; use bitcoin::psbt::Psbt; +use bitcoin::Amount; use bitcoin::{consensus::Decodable, Script, Transaction, Witness}; use dlc::{DlcTransactions, PartyParams}; use dlc_messages::FundingInput; @@ -120,7 +121,7 @@ where &accept_params, &funding_inputs, &signer.get_secret_key()?, - fund_output_value.to_sat(), + fund_output_value, None, &dlc_transactions, )?; @@ -136,7 +137,7 @@ pub(crate) fn accept_contract_internal( accept_params: &PartyParams, funding_inputs: &[FundingInput], adaptor_secret_key: &SecretKey, - input_value: u64, + input_value: Amount, input_script_pubkey: Option<&Script>, dlc_transactions: &DlcTransactions, ) -> Result<(AcceptedContract, Vec), crate::Error> { @@ -282,7 +283,7 @@ where &accept_msg.funding_inputs, &accept_msg.refund_signature, &cet_adaptor_signatures, - fund_output_value.to_sat(), + fund_output_value, wallet, &signer, None, @@ -323,7 +324,7 @@ pub(crate) fn verify_accepted_and_sign_contract_internal, @@ -533,11 +534,7 @@ where &sign_msg.refund_signature, &cet_adaptor_signatures, &sign_msg.funding_signatures, - accepted_contract - .dlc_transactions - .get_fund_output() - .value - .to_sat(), + accepted_contract.dlc_transactions.get_fund_output().value, None, None, wallet, @@ -551,7 +548,7 @@ pub(crate) fn verify_signed_contract_internal( refund_signature: &Signature, cet_adaptor_signatures: &[EcdsaAdaptorSignature], funding_signatures: &FundingSignatures, - input_value: u64, + input_value: Amount, input_script_pubkey: Option<&Script>, counter_adaptor_pk: Option, wallet: &W, @@ -711,8 +708,7 @@ where .accepted_contract .dlc_transactions .get_fund_output() - .value - .to_sat(), + .value, )?; Ok(cet) @@ -752,7 +748,7 @@ where other_fund_pubkey, &fund_priv_key, funding_script_pubkey, - fund_output_value.to_sat(), + fund_output_value, 0, )?; Ok(refund) @@ -762,6 +758,7 @@ where mod tests { use std::rc::Rc; + use bitcoin::Amount; use mocks::dlc_manager::contract::offered_contract::OfferedContract; use secp256k1_zkp::PublicKey; @@ -777,12 +774,12 @@ mod tests { OfferedContract::try_from_offer_dlc(&offer_dlc, dummy_pubkey, [0; 32]).unwrap(); let blockchain = Rc::new(mocks::mock_blockchain::MockBlockchain::new()); let fee_rate: u64 = offered_contract.fee_rate_per_vb; - let utxo_value: u64 = offered_contract.total_collateral + let utxo_value = offered_contract.total_collateral - offered_contract.offer_params.collateral + crate::utils::get_half_common_fee(fee_rate).unwrap(); let wallet = Rc::new(mocks::mock_wallet::MockWallet::new( &blockchain, - &[utxo_value, 10000], + &[utxo_value, Amount::from_sat(10000)], )); mocks::dlc_manager::contract_updater::accept_contract( diff --git a/dlc-manager/src/conversion_utils.rs b/dlc-manager/src/conversion_utils.rs index b7f15202..4520b1aa 100644 --- a/dlc-manager/src/conversion_utils.rs +++ b/dlc-manager/src/conversion_utils.rs @@ -71,7 +71,7 @@ impl From for Error { pub fn get_tx_input_infos( funding_inputs: &[FundingInput], -) -> Result<(Vec, u64), Error> { +) -> Result<(Vec, Amount), Error> { let mut input_amount = Amount::ZERO; let mut inputs = Vec::new(); @@ -94,7 +94,7 @@ pub fn get_tx_input_infos( }); } - Ok((inputs, input_amount.to_sat())) + Ok((inputs, input_amount)) } pub(crate) fn get_contract_info_and_announcements( @@ -542,12 +542,12 @@ mod tests { payout_points: vec![ PayoutPoint { event_outcome: 0, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: 9, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, ], @@ -556,12 +556,12 @@ mod tests { payout_points: vec![ PayoutPoint { event_outcome: 9, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: 10, - outcome_payout: 10, + outcome_payout: Amount::from_sat(10), extra_precision: 0, }, ], @@ -570,12 +570,12 @@ mod tests { payout_points: vec![ PayoutPoint { event_outcome: 10, - outcome_payout: 10, + outcome_payout: Amount::from_sat(10), extra_precision: 0, }, PayoutPoint { event_outcome: 20, - outcome_payout: 10, + outcome_payout: Amount::from_sat(10), extra_precision: 0, }, ], diff --git a/dlc-manager/src/error.rs b/dlc-manager/src/error.rs index 9f0ff5c4..34388a7d 100644 --- a/dlc-manager/src/error.rs +++ b/dlc-manager/src/error.rs @@ -27,6 +27,8 @@ pub enum Error { DlcError(dlc::Error), /// An error occurred in the Secp library. SecpError(secp256k1_zkp::Error), + /// A computation was out of range. + OutOfRange, } impl fmt::Display for Error { @@ -43,6 +45,7 @@ impl fmt::Display for Error { Error::DlcError(ref e) => write!(f, "Dlc error {}", e), Error::OracleError(ref s) => write!(f, "Oracle error {}", s), Error::SecpError(_) => write!(f, "Secp error"), + Error::OutOfRange => write!(f, "Out of range error"), } } } @@ -98,6 +101,7 @@ impl std::error::Error for Error { Error::OracleError(_) => None, Error::DlcError(e) => Some(e), Error::SecpError(e) => Some(e), + Error::OutOfRange => None, } } } diff --git a/dlc-manager/src/lib.rs b/dlc-manager/src/lib.rs index b5250c00..1f93f1af 100644 --- a/dlc-manager/src/lib.rs +++ b/dlc-manager/src/lib.rs @@ -37,7 +37,7 @@ pub mod payout_curve; mod utils; use bitcoin::psbt::Psbt; -use bitcoin::{Address, Block, OutPoint, ScriptBuf, Transaction, TxOut, Txid}; +use bitcoin::{Address, Amount, Block, OutPoint, ScriptBuf, Transaction, TxOut, Txid}; use chain_monitor::ChainMonitor; use channel::offered_channel::OfferedChannel; use channel::signed_channel::{SignedChannel, SignedChannelStateType}; @@ -155,7 +155,7 @@ pub trait Wallet { /// Get a set of UTXOs to fund the given amount. fn get_utxos_for_amount( &self, - amount: u64, + amount: Amount, fee_rate: u64, lock_utxos: bool, ) -> Result, Error>; diff --git a/dlc-manager/src/manager.rs b/dlc-manager/src/manager.rs index 8662d15f..1722c76d 100644 --- a/dlc-manager/src/manager.rs +++ b/dlc-manager/src/manager.rs @@ -22,7 +22,7 @@ use crate::{ChannelId, ContractId, ContractSignerProvider}; use bitcoin::absolute::Height; use bitcoin::consensus::encode::serialize_hex; use bitcoin::consensus::Decodable; -use bitcoin::Address; +use bitcoin::{Address, Amount, SignedAmount}; use bitcoin::{OutPoint, Transaction}; use dlc_messages::channel::{ AcceptChannel, CollaborativeCloseOffer, OfferChannel, Reject, RenewAccept, RenewConfirm, @@ -755,7 +755,7 @@ where pnl: contract .signed_contract .accepted_contract - .compute_pnl(&contract.signed_cet), + .compute_pnl(&contract.signed_cet)?, }; self.store .update_contract(&Contract::Closed(closed_contract))?; @@ -800,7 +800,7 @@ where let closed_contract = ClosedContract { attestations: Some(attestations.to_vec()), - pnl: contract.accepted_contract.compute_pnl(&signed_cet), + pnl: contract.accepted_contract.compute_pnl(&signed_cet)?, signed_cet: Some(signed_cet), contract_id: contract.accepted_contract.get_contract_id(), temporary_contract_id: contract.accepted_contract.offered_contract.id, @@ -883,7 +883,7 @@ where } else { Contract::Closed(ClosedContract { attestations: None, // todo in some cases we can get the attestations from the closing tx - pnl: contract.accepted_contract.compute_pnl(&closing_tx), + pnl: contract.accepted_contract.compute_pnl(&closing_tx)?, signed_cet: Some(closing_tx), contract_id: contract.accepted_contract.get_contract_id(), temporary_contract_id: contract.accepted_contract.offered_contract.id, @@ -1039,7 +1039,7 @@ where pub fn settle_offer( &self, channel_id: &ChannelId, - counter_payout: u64, + counter_payout: Amount, ) -> Result<(SettleOffer, PublicKey), Error> { let mut signed_channel = get_channel_in_state!(self, channel_id, Signed, None as Option)?; @@ -1095,7 +1095,7 @@ where pub fn renew_offer( &self, channel_id: &ChannelId, - counter_payout: u64, + counter_payout: Amount, contract_input: &ContractInput, ) -> Result<(RenewOffer, PublicKey), Error> { let mut signed_channel = @@ -1228,7 +1228,7 @@ where pub fn offer_collaborative_close( &self, channel_id: &ChannelId, - counter_payout: u64, + counter_payout: Amount, ) -> Result { let mut signed_channel = get_channel_in_state!(self, channel_id, Signed, None as Option)?; @@ -2562,7 +2562,7 @@ where fn get_collaboratively_closed_contract( &self, contract_id: &ContractId, - payout: u64, + payout: Amount, is_own_payout: bool, ) -> Result { let contract = get_contract_in_state!(self, contract_id, Confirmed, None::)?; @@ -2580,7 +2580,8 @@ where } else { contract.accepted_contract.offered_contract.total_collateral - payout }; - let pnl = own_payout as i64 - own_collateral as i64; + let pnl = + SignedAmount::from_sat(own_payout.to_sat() as i64 - own_collateral.to_sat() as i64); Ok(ClosedContract { attestations: None, signed_cet: None, @@ -2594,6 +2595,7 @@ where #[cfg(test)] mod test { + use bitcoin::Amount; use dlc_messages::Message; use mocks::{ dlc_manager::{manager::Manager, CachedContractSignerProvider, Oracle, SimpleSigner}, @@ -2622,7 +2624,9 @@ mod test { let store = Rc::new(MemoryStorage::new()); let wallet = Rc::new(MockWallet::new( &blockchain, - &(0..100).map(|x| x as u64 * 1000000).collect::>(), + &(0..100) + .map(|x| Amount::from_sat(x as u64 * 1000000)) + .collect::>(), )); let oracle_list = (0..5).map(|_| MockOracle::new()).collect::>(); diff --git a/dlc-manager/src/payout_curve.rs b/dlc-manager/src/payout_curve.rs index 6d06677c..411042a7 100644 --- a/dlc-manager/src/payout_curve.rs +++ b/dlc-manager/src/payout_curve.rs @@ -3,6 +3,7 @@ use std::ops::Deref; use crate::error::Error; +use bitcoin::Amount; use dlc::{Payout, RangePayout}; #[cfg(feature = "use-serde")] use serde::{Deserialize, Serialize}; @@ -98,7 +99,7 @@ impl PayoutFunction { /// Generate the range payouts from the function. pub fn to_range_payouts( &self, - total_collateral: u64, + total_collateral: Amount, rounding_intervals: &RoundingIntervals, ) -> Result, Error> { let mut range_payouts = Vec::new(); @@ -127,7 +128,7 @@ impl PayoutFunctionPiece { /// Generate the range payouts for the function piece. pub fn to_range_payouts( &self, - total_collateral: u64, + total_collateral: Amount, rounding_intervals: &RoundingIntervals, range_payouts: &mut Vec, ) -> Result<(), Error> { @@ -163,9 +164,10 @@ trait Evaluable { &self, outcome: u64, rounding_intervals: &RoundingIntervals, - total_collateral: u64, - ) -> Result { + total_collateral: Amount, + ) -> Result { let payout_double = self.evaluate(outcome); + let total_collateral_sats = total_collateral.to_sat(); if payout_double.is_sign_negative() || (payout_double != 0.0 && !payout_double.is_normal()) { return Err(Error::InvalidParameters(format!( @@ -174,17 +176,17 @@ trait Evaluable { ))); } - if payout_double.round() > total_collateral as f64 { + if payout_double.round() > total_collateral_sats as f64 { return Err(Error::InvalidParameters( "Computed payout is greater than total collateral".to_string(), )); } // Ensure that we never round over the total collateral. - Ok(u64::min( + Ok(Amount::from_sat(u64::min( rounding_intervals.round(outcome, payout_double), - total_collateral, - )) + total_collateral_sats, + ))) } fn get_first_outcome(&self) -> u64; @@ -194,7 +196,7 @@ trait Evaluable { fn get_cur_range( &self, range_payouts: &mut Vec, - total_collateral: u64, + total_collateral: Amount, rounding_intervals: &RoundingIntervals, ) -> Result { let res = match range_payouts.pop() { @@ -219,7 +221,7 @@ trait Evaluable { fn to_range_payouts( &self, rounding_intervals: &RoundingIntervals, - total_collateral: u64, + total_collateral: Amount, range_payouts: &mut Vec, ) -> Result<(), Error> { compute_range_payouts(self, rounding_intervals, total_collateral, range_payouts) @@ -229,7 +231,7 @@ trait Evaluable { fn compute_range_payouts( function: E, rounding_intervals: &RoundingIntervals, - total_collateral: u64, + total_collateral: Amount, range_payouts: &mut Vec, ) -> Result<(), Error> where @@ -308,13 +310,14 @@ impl Evaluable for PolynomialPayoutCurvePiece { // Optimizations for constant and linear cases. if nb_points == 2 { let (left_point, right_point) = (&self.payout_points[0], &self.payout_points[1]); + let right_point_payout_sats = right_point.outcome_payout.to_sat() as f64; + let left_point_payout_sats = left_point.outcome_payout.to_sat() as f64; return if left_point.outcome_payout == right_point.outcome_payout { - right_point.outcome_payout as f64 + right_point_payout_sats } else { - let slope = (right_point.outcome_payout as f64 - left_point.outcome_payout as f64) + let slope = (right_point_payout_sats - left_point_payout_sats) / (right_point.event_outcome - left_point.event_outcome) as f64; - (outcome - left_point.event_outcome) as f64 * slope - + left_point.outcome_payout as f64 + (outcome - left_point.event_outcome) as f64 * slope + left_point_payout_sats }; } @@ -352,7 +355,7 @@ impl Evaluable for PolynomialPayoutCurvePiece { fn to_range_payouts( &self, rounding_intervals: &RoundingIntervals, - total_collateral: u64, + total_collateral: Amount, range_payouts: &mut Vec, ) -> Result<(), Error> { if self.payout_points.len() == 2 @@ -381,14 +384,14 @@ pub struct PayoutPoint { /// The event outcome. pub event_outcome: u64, /// The payout for the outcome. - pub outcome_payout: u64, + pub outcome_payout: Amount, /// Extra precision to use when computing the payout. pub extra_precision: u16, } impl PayoutPoint { fn get_outcome_payout(&self) -> f64 { - (self.outcome_payout as f64) + ((self.extra_precision as f64) / ((1 << 16) as f64)) + (self.outcome_payout.to_sat() as f64) + ((self.extra_precision as f64) / ((1 << 16) as f64)) } } @@ -578,17 +581,17 @@ mod test { payout_points: vec![ PayoutPoint { event_outcome: 0, - outcome_payout: 1, + outcome_payout: Amount::from_sat(1), extra_precision: 0, }, PayoutPoint { event_outcome: 2, - outcome_payout: 5, + outcome_payout: Amount::from_sat(5), extra_precision: 0, }, PayoutPoint { event_outcome: 4, - outcome_payout: 17, + outcome_payout: Amount::from_sat(17), extra_precision: 0, }, ], @@ -604,71 +607,71 @@ mod test { payout_points: Vec, expected_len: usize, expected_first_start: usize, - expected_first_payout: u64, + expected_first_payout: Amount, expected_last_start: usize, - expected_last_payout: u64, - total_collateral: u64, + expected_last_payout: Amount, + total_collateral: Amount, } let test_cases: Vec = vec![ TestCase { payout_points: vec![ PayoutPoint { event_outcome: 0, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: 20, - outcome_payout: 20, + outcome_payout: Amount::from_sat(20), extra_precision: 0, }, ], expected_len: 21, expected_first_start: 0, - expected_first_payout: 0, + expected_first_payout: Amount::ZERO, expected_last_start: 20, - expected_last_payout: 20, - total_collateral: 20, + expected_last_payout: Amount::from_sat(20), + total_collateral: Amount::from_sat(20), }, TestCase { payout_points: vec![ PayoutPoint { event_outcome: 10, - outcome_payout: 10, + outcome_payout: Amount::from_sat(10), extra_precision: 0, }, PayoutPoint { event_outcome: 20, - outcome_payout: 10, + outcome_payout: Amount::from_sat(10), extra_precision: 0, }, ], expected_len: 1, expected_first_start: 10, - expected_first_payout: 10, + expected_first_payout: Amount::from_sat(10), expected_last_start: 10, - expected_last_payout: 10, - total_collateral: 10, + expected_last_payout: Amount::from_sat(10), + total_collateral: Amount::from_sat(10), }, TestCase { payout_points: vec![ PayoutPoint { event_outcome: 50000, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: 1048575, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, ], expected_len: 1, expected_first_start: 50000, - expected_first_payout: 0, + expected_first_payout: Amount::ZERO, expected_last_start: 50000, - expected_last_payout: 0, - total_collateral: 200000000, + expected_last_payout: Amount::ZERO, + total_collateral: Amount::from_sat(200000000), }, ]; @@ -714,12 +717,12 @@ mod test { let hyperbola = HyperbolaPayoutCurvePiece { left_end_point: PayoutPoint { event_outcome: 1, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, right_end_point: PayoutPoint { event_outcome: u64::MAX, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, use_positive_piece: true, @@ -741,12 +744,12 @@ mod test { let hyperbola = HyperbolaPayoutCurvePiece { left_end_point: PayoutPoint { event_outcome: 1, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, right_end_point: PayoutPoint { event_outcome: 1000, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, use_positive_piece: true, @@ -766,7 +769,7 @@ mod test { rounding_mod: 1, }], }, - 200000000, + Amount::from_sat(200000000), &mut Vec::new(), ) .expect_err("Should not tolerate negative payout"); @@ -777,12 +780,12 @@ mod test { let hyperbola = HyperbolaPayoutCurvePiece { left_end_point: PayoutPoint { event_outcome: 1, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, right_end_point: PayoutPoint { event_outcome: 1000, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, use_positive_piece: true, @@ -802,7 +805,7 @@ mod test { rounding_mod: 1, }], }, - 200000000, + Amount::from_sat(200000000), &mut Vec::new(), ) .expect("to be able to compute the range payouts"); @@ -813,12 +816,12 @@ mod test { HyperbolaPayoutCurvePiece::new( PayoutPoint { event_outcome: 1, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: 1000, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, true, @@ -839,12 +842,12 @@ mod test { PolynomialPayoutCurvePiece::new(vec![ PayoutPoint { event_outcome: 0, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: 9, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, ]) @@ -854,12 +857,12 @@ mod test { PolynomialPayoutCurvePiece::new(vec![ PayoutPoint { event_outcome: 9, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: 10, - outcome_payout: 9, + outcome_payout: Amount::from_sat(9), extra_precision: 0, }, ]) @@ -869,12 +872,12 @@ mod test { PolynomialPayoutCurvePiece::new(vec![ PayoutPoint { event_outcome: 10, - outcome_payout: 9, + outcome_payout: Amount::from_sat(9), extra_precision: 0, }, PayoutPoint { event_outcome: 19, - outcome_payout: 9, + outcome_payout: Amount::from_sat(9), extra_precision: 0, }, ]) @@ -884,12 +887,12 @@ mod test { PolynomialPayoutCurvePiece::new(vec![ PayoutPoint { event_outcome: 19, - outcome_payout: 9, + outcome_payout: Amount::from_sat(9), extra_precision: 0, }, PayoutPoint { event_outcome: 20, - outcome_payout: 10, + outcome_payout: Amount::from_sat(10), extra_precision: 0, }, ]) @@ -899,12 +902,12 @@ mod test { PolynomialPayoutCurvePiece::new(vec![ PayoutPoint { event_outcome: 20, - outcome_payout: 10, + outcome_payout: Amount::from_sat(10), extra_precision: 0, }, PayoutPoint { event_outcome: u64::MAX, - outcome_payout: 10, + outcome_payout: Amount::from_sat(10), extra_precision: 0, }, ]) @@ -917,24 +920,24 @@ mod test { start: 0, count: 10, payout: Payout { - offer: 0, - accept: 10, + offer: Amount::ZERO, + accept: Amount::from_sat(10), }, }, RangePayout { start: 10, count: 10, payout: Payout { - offer: 9, - accept: 1, + offer: Amount::from_sat(9), + accept: Amount::from_sat(1), }, }, RangePayout { start: 20, count: (u64::MAX - 19) as usize, payout: Payout { - offer: 10, - accept: 0, + offer: Amount::from_sat(10), + accept: Amount::ZERO, }, }, ]; @@ -942,7 +945,7 @@ mod test { expected_ranges, payout_function .to_range_payouts( - 10, + Amount::from_sat(10), &RoundingIntervals { intervals: vec![RoundingInterval { begin_interval: 0, @@ -960,19 +963,19 @@ mod test { // Polynomial curve piece requires more than one vec![PayoutPoint { event_outcome: 0, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }], // Payout point outcomes should be increasing vec![ PayoutPoint { event_outcome: 10, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: 9, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, ], @@ -988,12 +991,12 @@ mod test { HyperbolaPayoutCurvePiece::new( PayoutPoint { event_outcome: 0, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: 0, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, true, @@ -1008,12 +1011,12 @@ mod test { HyperbolaPayoutCurvePiece::new( PayoutPoint { event_outcome: 0, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: 1, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, true, @@ -1036,12 +1039,12 @@ mod test { payout_points: vec![ PayoutPoint { event_outcome: 0, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: 9, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, ], @@ -1050,12 +1053,12 @@ mod test { payout_points: vec![ PayoutPoint { event_outcome: 11, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: 19, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, ], @@ -1066,12 +1069,12 @@ mod test { payout_points: vec![ PayoutPoint { event_outcome: 0, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: 9, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, ], @@ -1080,12 +1083,12 @@ mod test { payout_points: vec![ PayoutPoint { event_outcome: 10, - outcome_payout: 1, + outcome_payout: Amount::from_sat(1), extra_precision: 0, }, PayoutPoint { event_outcome: 19, - outcome_payout: 1, + outcome_payout: Amount::from_sat(1), extra_precision: 0, }, ], @@ -1184,12 +1187,12 @@ mod test { payout_points: vec![ PayoutPoint { event_outcome: 0, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: 500, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, ], @@ -1198,12 +1201,12 @@ mod test { payout_points: vec![ PayoutPoint { event_outcome: 500, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: 1048575, - outcome_payout: 7513, + outcome_payout: Amount::from_sat(7513), extra_precision: 0, }, ], @@ -1212,7 +1215,7 @@ mod test { }; payout_function - .to_range_payouts(7513, &rounding_intervals) + .to_range_payouts(Amount::from_sat(75130), &rounding_intervals) .expect("To be able to compute the range payouts"); } @@ -1222,12 +1225,12 @@ mod test { PolynomialPayoutCurvePiece::new(vec![ PayoutPoint { event_outcome: 22352, - outcome_payout: 0, + outcome_payout: Amount::ZERO, extra_precision: 0, }, PayoutPoint { event_outcome: 55881, - outcome_payout: 87455, + outcome_payout: Amount::from_sat(87455), extra_precision: 0, }, ]) @@ -1245,7 +1248,7 @@ mod test { }; function - .to_range_payouts(87455, &rounding_intervals) + .to_range_payouts(Amount::from_sat(87455), &rounding_intervals) .expect("Not to fail"); } @@ -1255,12 +1258,12 @@ mod test { payout_points: vec![ PayoutPoint { event_outcome: 0, - outcome_payout: 1, + outcome_payout: Amount::from_sat(1), extra_precision: 0, }, PayoutPoint { event_outcome: 2, - outcome_payout: 5, + outcome_payout: Amount::from_sat(5), extra_precision: 0, }, ], @@ -1276,12 +1279,12 @@ mod test { payout_points: vec![ PayoutPoint { event_outcome: 0, - outcome_payout: 10, + outcome_payout: Amount::from_sat(10), extra_precision: 0, }, PayoutPoint { event_outcome: 1, - outcome_payout: 8, + outcome_payout: Amount::from_sat(8), extra_precision: 0, }, ], diff --git a/dlc-manager/src/utils.rs b/dlc-manager/src/utils.rs index f206b4fa..c854ab42 100644 --- a/dlc-manager/src/utils.rs +++ b/dlc-manager/src/utils.rs @@ -91,7 +91,7 @@ pub(crate) fn compute_id( pub(crate) fn get_party_params( secp: &Secp256k1, - own_collateral: u64, + own_collateral: Amount, fee_rate: u64, wallet: &W, signer: &X, @@ -147,7 +147,7 @@ where payout_serial_id, inputs: funding_tx_info, collateral: own_collateral, - input_amount: total_input.to_sat(), + input_amount: total_input, }; Ok((party_params, funding_inputs)) @@ -170,9 +170,11 @@ where }) } -pub(crate) fn get_half_common_fee(fee_rate: u64) -> Result { +pub(crate) fn get_half_common_fee(fee_rate: u64) -> Result { let common_fee = dlc::util::get_common_fee(fee_rate)?; - Ok((common_fee as f64 / 2_f64).ceil() as u64) + Ok(Amount::from_sat( + (common_fee.to_sat() as f64 / 2_f64).ceil() as u64, + )) } pub(crate) fn get_range_info_and_oracle_sigs( diff --git a/dlc-manager/tests/channel_execution_tests.rs b/dlc-manager/tests/channel_execution_tests.rs index 05da7bb5..76fc594f 100644 --- a/dlc-manager/tests/channel_execution_tests.rs +++ b/dlc-manager/tests/channel_execution_tests.rs @@ -373,8 +373,8 @@ fn channel_execution_test(test_params: TestParams, path: TestPath) { generate_blocks(6); - refresh_wallet(&alice_wallet, 200000000); - refresh_wallet(&bob_wallet, 200000000); + refresh_wallet(&alice_wallet, Amount::from_sat(200000000)); + refresh_wallet(&bob_wallet, Amount::from_sat(200000000)); let alice_manager = Arc::new(Mutex::new( Manager::new( @@ -1196,7 +1196,7 @@ fn collaborative_close( let close_offer = first .lock() .unwrap() - .offer_collaborative_close(&channel_id, 100000000) + .offer_collaborative_close(&channel_id, Amount::from_sat(100000000)) .expect("to be able to propose a collaborative close"); first_send .send(Some(Message::CollaborativeCloseOffer(close_offer))) diff --git a/dlc-manager/tests/manager_execution_tests.rs b/dlc-manager/tests/manager_execution_tests.rs index cc2743e1..d6787b51 100644 --- a/dlc-manager/tests/manager_execution_tests.rs +++ b/dlc-manager/tests/manager_execution_tests.rs @@ -646,8 +646,8 @@ fn manager_execution_test(test_params: TestParams, path: TestPath, manual_close: generate_blocks(6); - refresh_wallet(&alice_wallet, 200000000); - refresh_wallet(&bob_wallet, 200000000); + refresh_wallet(&alice_wallet, Amount::from_sat(200000000)); + refresh_wallet(&bob_wallet, Amount::from_sat(200000000)); let alice_manager = Arc::new(Mutex::new( Manager::new( diff --git a/dlc-manager/tests/test_utils.rs b/dlc-manager/tests/test_utils.rs index bb1a7cf8..b6bf2a48 100644 --- a/dlc-manager/tests/test_utils.rs +++ b/dlc-manager/tests/test_utils.rs @@ -8,6 +8,7 @@ extern crate dlc_manager; use std::ops::Deref; +use bitcoin::Amount; use dlc::{EnumerationPayout, Payout}; use dlc_manager::payout_curve::{ PayoutFunction, PayoutFunctionPiece, PayoutPoint, PolynomialPayoutCurvePiece, RoundingInterval, @@ -37,9 +38,9 @@ pub const MAX_ERROR_EXP: usize = 2; pub const BASE: u32 = 2; pub const EVENT_MATURITY: u32 = 1623133104; pub const EVENT_ID: &str = "Test"; -pub const OFFER_COLLATERAL: u64 = 90000000; -pub const ACCEPT_COLLATERAL: u64 = 11000000; -pub const TOTAL_COLLATERAL: u64 = OFFER_COLLATERAL + ACCEPT_COLLATERAL; +pub const OFFER_COLLATERAL: Amount = Amount::from_sat(90000000); +pub const ACCEPT_COLLATERAL: Amount = Amount::from_sat(11000000); +pub const TOTAL_COLLATERAL: Amount = Amount::from_sat(101000000); pub const MID_POINT: u64 = 5; pub const ROUNDING_MOD: u64 = 1; @@ -226,11 +227,11 @@ pub fn get_enum_contract_descriptor() -> ContractDescriptor { let payout = if i % 2 == 0 { Payout { offer: TOTAL_COLLATERAL, - accept: 0, + accept: Amount::ZERO, } } else { Payout { - offer: 0, + offer: Amount::ZERO, accept: TOTAL_COLLATERAL, } }; @@ -305,7 +306,7 @@ pub fn get_polynomial_payout_curve_pieces(min_nb_digits: usize) -> Vec Vec OracleNumericIn pub fn refresh_wallet( wallet: &simple_wallet::SimpleWallet, - expected_funds: u64, + expected_funds: Amount, ) where B::Target: Blockchain + WalletBlockchainProvider, W::Target: WalletStorage, diff --git a/dlc-messages/src/channel.rs b/dlc-messages/src/channel.rs index c631a154..70a37e6a 100644 --- a/dlc-messages/src/channel.rs +++ b/dlc-messages/src/channel.rs @@ -1,6 +1,6 @@ //! Contains messages used for the establishment and update of DLC channels. -use bitcoin::ScriptBuf; +use bitcoin::{Amount, ScriptBuf}; use dlc::Error; use lightning::ln::msgs::DecodeError; use lightning::util::ser::{Readable, Writeable, Writer}; @@ -63,7 +63,7 @@ pub struct OfferChannel { /// Serial id used to order outputs. pub payout_serial_id: u64, /// The collateral input by the offer party in the channel. - pub offer_collateral: u64, + pub offer_collateral: Amount, /// The inputs that the offer party will use to fund the channel. pub funding_inputs: Vec, /// The script that the offer party to receive their change. @@ -161,7 +161,7 @@ pub struct AcceptChannel { /// The temporary id of the channel. pub temporary_channel_id: [u8; 32], /// The collateral input by the accept party. - pub accept_collateral: u64, + pub accept_collateral: Amount, /// The [`PublicKey`] used for the fund output by the accept party. pub funding_pubkey: PublicKey, /// The [`PublicKey`] used for deriving revocation points by the accept party. @@ -266,7 +266,7 @@ pub struct SettleOffer { /// The id of the channel referred to by the message. pub channel_id: [u8; 32], /// The payout offered to the receiving party. - pub counter_payout: u64, + pub counter_payout: Amount, /// The per update point to be used by the sending party to setup the next /// channel state. pub next_per_update_point: PublicKey, @@ -388,7 +388,7 @@ pub struct RenewOffer { pub temporary_contract_id: [u8; 32], /// The proposed payout for the receiving party for the previous channel /// state. - pub counter_payout: u64, + pub counter_payout: Amount, /// The per update point to be used by the sending party to setup the next /// channel state. pub next_per_update_point: PublicKey, @@ -556,7 +556,7 @@ pub struct CollaborativeCloseOffer { /// The id of the channel referred to by the message. pub channel_id: [u8; 32], /// The proposed payout for the receiving party to close the channel with. - pub counter_payout: u64, + pub counter_payout: Amount, /// The signature of the sending party for the closing transaction. pub close_signature: Signature, } diff --git a/dlc-messages/src/contract_msgs.rs b/dlc-messages/src/contract_msgs.rs index 8287e70c..8347444f 100644 --- a/dlc-messages/src/contract_msgs.rs +++ b/dlc-messages/src/contract_msgs.rs @@ -1,5 +1,6 @@ //! Structure containing information about contract details. +use bitcoin::Amount; use lightning::ln::msgs::DecodeError; use lightning::util::ser::{Readable, Writeable, Writer}; use oracle_msgs::OracleInfo; @@ -16,7 +17,7 @@ pub struct ContractOutcome { /// The outcome represented as a string. pub outcome: String, /// The payout of the offer party for the outcome. - pub offer_payout: u64, + pub offer_payout: Amount, } impl_dlc_writeable!(ContractOutcome, {(outcome, string), (offer_payout, writeable)}); @@ -41,7 +42,7 @@ impl_dlc_writeable_enum!(ContractInfo, impl ContractInfo { /// Returns the total collateral locked inside the contract. - pub fn get_total_collateral(&self) -> u64 { + pub fn get_total_collateral(&self) -> Amount { match self { ContractInfo::SingleContractInfo(v0) => v0.total_collateral, ContractInfo::DisjointContractInfo(v1) => v1.total_collateral, @@ -74,7 +75,7 @@ impl ContractInfo { /// Information for a contract based on a single event. pub struct SingleContractInfo { /// The total collateral locked in the contract. - pub total_collateral: u64, + pub total_collateral: Amount, /// Information about the contract outcomes, payout and oracles. pub contract_info: ContractInfoInner, } @@ -90,7 +91,7 @@ impl_dlc_writeable!(SingleContractInfo, { (total_collateral, writeable), (contra /// Information for a contract based on a multiple events. pub struct DisjointContractInfo { /// The total collateral locked in the contract. - pub total_collateral: u64, + pub total_collateral: Amount, /// Information about the contract outcomes, payout and oracles. pub contract_infos: Vec, } @@ -241,7 +242,7 @@ pub struct PayoutPoint { /// The event outcome for this point (X coordinate). pub event_outcome: u64, /// The payout for this point (Y coordinate). - pub outcome_payout: u64, + pub outcome_payout: Amount, /// Extra precision to be applied when computing the payout. pub extra_precision: u16, } diff --git a/dlc-messages/src/lib.rs b/dlc-messages/src/lib.rs index 719350af..c8d47859 100644 --- a/dlc-messages/src/lib.rs +++ b/dlc-messages/src/lib.rs @@ -36,8 +36,8 @@ pub mod serde_utils; use std::fmt::Display; use crate::ser_impls::{read_ecdsa_adaptor_signature, write_ecdsa_adaptor_signature}; -use bitcoin::ScriptBuf; use bitcoin::{consensus::Decodable, OutPoint, Transaction}; +use bitcoin::{Amount, ScriptBuf}; use channel::{ AcceptChannel, CollaborativeCloseOffer, OfferChannel, Reject, RenewAccept, RenewConfirm, RenewFinalize, RenewOffer, RenewRevoke, SettleAccept, SettleConfirm, SettleFinalize, @@ -328,7 +328,7 @@ pub struct OfferDlc { /// Serial id to order CET outputs. pub payout_serial_id: u64, /// Collateral of the offer party. - pub offer_collateral: u64, + pub offer_collateral: Amount, /// Inputs used by the offer party to fund the contract. pub funding_inputs: Vec, /// The SPK where the offer party will receive their change. @@ -347,7 +347,7 @@ pub struct OfferDlc { impl OfferDlc { /// Returns the total collateral locked in the contract. - pub fn get_total_collateral(&self) -> u64 { + pub fn get_total_collateral(&self) -> Amount { match &self.contract_info { ContractInfo::SingleContractInfo(single) => single.total_collateral, ContractInfo::DisjointContractInfo(disjoint) => disjoint.total_collateral, @@ -428,7 +428,7 @@ pub struct AcceptDlc { /// The temporary contract id for the contract. pub temporary_contract_id: [u8; 32], /// The collateral input by the accept party. - pub accept_collateral: u64, + pub accept_collateral: Amount, /// The public key of the accept party to be used to lock the collateral. pub funding_pubkey: PublicKey, /// The SPK where the accept party will receive their payout. @@ -664,7 +664,7 @@ mod tests { let mut no_contract_input = offer.clone(); no_contract_input.contract_info = ContractInfo::DisjointContractInfo(contract_msgs::DisjointContractInfo { - total_collateral: 100000000, + total_collateral: Amount::ONE_BTC, contract_infos: vec![], }); diff --git a/dlc-messages/src/ser_impls.rs b/dlc-messages/src/ser_impls.rs index e34bb0d4..1ba425d7 100644 --- a/dlc-messages/src/ser_impls.rs +++ b/dlc-messages/src/ser_impls.rs @@ -2,6 +2,7 @@ use bitcoin::Address; use bitcoin::Network; +use bitcoin::SignedAmount; use dlc::{EnumerationPayout, PartyParams, Payout, TxInputInfo}; use lightning::io::Read; use lightning::ln::msgs::DecodeError; @@ -567,22 +568,28 @@ pub fn read_i32(reader: &mut R) -> Result { let v: [u8; 4] = Readable::read(reader)?; Ok(i32::from_be_bytes(v)) } -/// Writes an `i64` value to the given writer. -pub fn write_i64(i: &i64, writer: &mut W) -> Result<(), ::lightning::io::Error> { - let i = i.to_be_bytes(); +/// Writes a `SignedAmount` value to the given writer. +pub fn write_signed_amount( + i: &SignedAmount, + writer: &mut W, +) -> Result<(), ::lightning::io::Error> { + let i = i.to_sat().to_be_bytes(); for b in i { b.write(writer)?; } Ok(()) } -/// Reads an `i64` value from the given reader. -pub fn read_i64(reader: &mut R) -> Result { +/// Reads a `SignedAmount` value from the given reader. +pub fn read_signed_amount( + reader: &mut R, +) -> Result { let mut v = [0u8; 8]; for x in &mut v { *x = Readable::read(reader)?; } - Ok(i64::from_be_bytes(v)) + let signed_amount = i64::from_be_bytes(v); + Ok(SignedAmount::from_sat(signed_amount)) } /// Writes a [`lightning::util::ser::Writeable`] value to the given writer as a TLV. diff --git a/dlc-messages/src/ser_macros.rs b/dlc-messages/src/ser_macros.rs index ca62a7f1..2c883c61 100644 --- a/dlc-messages/src/ser_macros.rs +++ b/dlc-messages/src/ser_macros.rs @@ -27,8 +27,8 @@ macro_rules! field_write { ($stream: expr, $field: expr, usize) => { $crate::ser_impls::write_usize(&$field, $stream)?; }; - ($stream: expr, $field: expr, i64) => { - $crate::ser_impls::write_i64(&$field, $stream)?; + ($stream: expr, $field: expr, SignedAmount) => { + $crate::ser_impls::write_signed_amount(&$field, $stream)?; }; ($stream: expr, $field: expr, {option_cb, $w_cb: expr, $r_cb: expr}) => { $crate::ser_impls::write_option_cb(&$field, $stream, &$w_cb)?; @@ -65,8 +65,8 @@ macro_rules! field_read { ($stream: expr, usize) => { $crate::ser_impls::read_usize($stream)? }; - ($stream: expr, i64) => { - $crate::ser_impls::read_i64($stream)? + ($stream: expr, SignedAmount) => { + $crate::ser_impls::read_signed_amount($stream)? }; ($stream: expr, {option_cb, $w_cb: expr, $r_cb: expr}) => { $crate::ser_impls::read_option_cb($stream, &$r_cb)? diff --git a/dlc-trie/src/digit_decomposition.rs b/dlc-trie/src/digit_decomposition.rs index b40f50e6..136d0b89 100644 --- a/dlc-trie/src/digit_decomposition.rs +++ b/dlc-trie/src/digit_decomposition.rs @@ -195,6 +195,7 @@ pub fn group_by_ignoring_digits( #[cfg(test)] mod tests { + use bitcoin::Amount; use dlc::{Payout, RangePayout}; struct DecompositionTestCase { composed: usize, @@ -456,16 +457,16 @@ mod tests { start: 10, count: 10, payout: Payout { - offer: 0, - accept: 10, + offer: Amount::ZERO, + accept: Amount::from_sat(10), }, }, RangePayout { start: 20, count: 10, payout: Payout { - offer: 10, - accept: 0, + offer: Amount::from_sat(10), + accept: Amount::ZERO, }, }, ], @@ -474,16 +475,16 @@ mod tests { start: 0, count: 20, payout: Payout { - offer: 0, - accept: 10, + offer: Amount::ZERO, + accept: Amount::from_sat(10), }, }, RangePayout { start: 20, count: 80, payout: Payout { - offer: 10, - accept: 0, + offer: Amount::from_sat(10), + accept: Amount::ZERO, }, }, ], @@ -495,16 +496,16 @@ mod tests { start: 10, count: 50, payout: Payout { - offer: 0, - accept: 10, + offer: Amount::ZERO, + accept: Amount::from_sat(10), }, }], expected: vec![RangePayout { start: 0, count: 100, payout: Payout { - offer: 0, - accept: 10, + offer: Amount::ZERO, + accept: Amount::from_sat(10), }, }], base: 10, @@ -516,16 +517,16 @@ mod tests { start: 10, count: 10, payout: Payout { - offer: 0, - accept: 10, + offer: Amount::ZERO, + accept: Amount::from_sat(10), }, }, RangePayout { start: 20, count: 10, payout: Payout { - offer: 10, - accept: 0, + offer: Amount::from_sat(10), + accept: Amount::ZERO, }, }, ], @@ -534,16 +535,16 @@ mod tests { start: 0, count: 20, payout: Payout { - offer: 0, - accept: 10, + offer: Amount::ZERO, + accept: Amount::from_sat(10), }, }, RangePayout { start: 20, count: 12, payout: Payout { - offer: 10, - accept: 0, + offer: Amount::from_sat(10), + accept: Amount::ZERO, }, }, ], @@ -556,16 +557,16 @@ mod tests { start: 0, count: 20, payout: Payout { - offer: 0, - accept: 10, + offer: Amount::ZERO, + accept: Amount::from_sat(10), }, }, RangePayout { start: 20, count: 10, payout: Payout { - offer: 10, - accept: 0, + offer: Amount::from_sat(10), + accept: Amount::ZERO, }, }, ], @@ -574,16 +575,16 @@ mod tests { start: 0, count: 20, payout: Payout { - offer: 0, - accept: 10, + offer: Amount::ZERO, + accept: Amount::from_sat(10), }, }, RangePayout { start: 20, count: 12, payout: Payout { - offer: 10, - accept: 0, + offer: Amount::from_sat(10), + accept: Amount::ZERO, }, }, ], diff --git a/dlc-trie/src/lib.rs b/dlc-trie/src/lib.rs index 1522a922..41e86048 100644 --- a/dlc-trie/src/lib.rs +++ b/dlc-trie/src/lib.rs @@ -20,7 +20,7 @@ extern crate secp256k1_zkp; #[cfg(feature = "use-serde")] extern crate serde; -use bitcoin::{Script, Transaction}; +use bitcoin::{Amount, Script, Transaction}; use dlc::{Error, RangePayout}; #[cfg(feature = "parallel")] use rayon::prelude::*; @@ -124,7 +124,7 @@ pub trait DlcTrie<'a, TrieIterator: Iterator> { secp: &Secp256k1, fund_pubkey: &PublicKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, outcomes: &[RangePayout], cets: &[Transaction], precomputed_points: &[Vec>], @@ -150,7 +150,7 @@ pub trait DlcTrie<'a, TrieIterator: Iterator> { secp: &Secp256k1, fund_privkey: &SecretKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, outcomes: &[RangePayout], cets: &[Transaction], precomputed_points: &[Vec>], @@ -175,7 +175,7 @@ pub trait DlcTrie<'a, TrieIterator: Iterator> { secp: &Secp256k1, fund_pubkey: &PublicKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, adaptor_sigs: &[EcdsaAdaptorSignature], cets: &[Transaction], precomputed_points: &[Vec>], @@ -198,7 +198,7 @@ pub trait DlcTrie<'a, TrieIterator: Iterator> { secp: &Secp256k1, fund_privkey: &SecretKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, cets: &[Transaction], precomputed_points: &[Vec>], ) -> Result, Error> { @@ -229,7 +229,7 @@ fn sign_helper>( cets: &[Transaction], fund_privkey: &SecretKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, precomputed_points: &[Vec>], trie_info: T, ) -> Result, Error> { @@ -261,7 +261,7 @@ fn sign_helper>( cets: &[Transaction], fund_privkey: &SecretKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, precomputed_points: &[Vec>], trie_info: T, ) -> Result, Error> { @@ -296,7 +296,7 @@ fn verify_helper>( adaptor_sigs: &[EcdsaAdaptorSignature], fund_pubkey: &PublicKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, precomputed_points: &[Vec>], trie_info: T, ) -> Result { @@ -329,7 +329,7 @@ fn verify_helper>( adaptor_sigs: &[EcdsaAdaptorSignature], fund_pubkey: &PublicKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, precomputed_points: &[Vec>], trie_info: T, ) -> Result { diff --git a/dlc-trie/src/multi_oracle_trie.rs b/dlc-trie/src/multi_oracle_trie.rs index 0274abe5..c66e8513 100644 --- a/dlc-trie/src/multi_oracle_trie.rs +++ b/dlc-trie/src/multi_oracle_trie.rs @@ -358,6 +358,7 @@ impl Iterator for MultiOracleTrieIter<'_> { #[cfg(test)] mod tests { + use bitcoin::Amount; use dlc::{Payout, RangePayout}; use crate::{test_utils::get_variable_oracle_numeric_infos, DlcTrie}; @@ -369,8 +370,8 @@ mod tests { start: 0, count: 1023, payout: Payout { - offer: 200000000, - accept: 0, + offer: Amount::from_sat(200000000), + accept: Amount::ZERO, }, }]; let oracle_numeric_infos = get_variable_oracle_numeric_infos(&[10, 15, 15, 15, 12], 2); @@ -390,8 +391,8 @@ mod tests { start: 0, count: 1023, payout: Payout { - offer: 200000000, - accept: 0, + offer: Amount::from_sat(200000000), + accept: Amount::ZERO, }, }]; let oracle_numeric_infos = get_variable_oracle_numeric_infos(&[10, 15, 15, 15, 12], 2); diff --git a/dlc-trie/src/multi_oracle_trie_with_diff.rs b/dlc-trie/src/multi_oracle_trie_with_diff.rs index 5f86dce6..da12be13 100644 --- a/dlc-trie/src/multi_oracle_trie_with_diff.rs +++ b/dlc-trie/src/multi_oracle_trie_with_diff.rs @@ -167,6 +167,7 @@ impl Iterator for MultiOracleTrieWithDiffIter<'_> { #[cfg(test)] mod tests { + use bitcoin::Amount; use dlc::{Payout, RangePayout}; use crate::{test_utils::get_variable_oracle_numeric_infos, DlcTrie}; @@ -179,48 +180,48 @@ mod tests { start: 0, count: 1, payout: Payout { - offer: 0, - accept: 200000000, + offer: Amount::ZERO, + accept: Amount::from_sat(200000000), }, }, RangePayout { start: 1, count: 1, payout: Payout { - offer: 40000000, - accept: 160000000, + offer: Amount::from_sat(40000000), + accept: Amount::from_sat(160000000), }, }, RangePayout { start: 2, count: 1, payout: Payout { - offer: 80000000, - accept: 120000000, + offer: Amount::from_sat(80000000), + accept: Amount::from_sat(120000000), }, }, RangePayout { start: 3, count: 1, payout: Payout { - offer: 120000000, - accept: 80000000, + offer: Amount::from_sat(120000000), + accept: Amount::from_sat(80000000), }, }, RangePayout { start: 4, count: 1, payout: Payout { - offer: 160000000, - accept: 40000000, + offer: Amount::from_sat(160000000), + accept: Amount::from_sat(40000000), }, }, RangePayout { start: 5, count: 1019, payout: Payout { - offer: 200000000, - accept: 0, + offer: Amount::from_sat(200000000), + accept: Amount::ZERO, }, }, ]; diff --git a/dlc/benches/benchmarks.rs b/dlc/benches/benchmarks.rs index f0f69adc..6437ef1e 100644 --- a/dlc/benches/benchmarks.rs +++ b/dlc/benches/benchmarks.rs @@ -141,7 +141,7 @@ mod benches { &oracle_infos, &seckey, &funding_script_pubkey(), - cet.output[0].value.to_sat(), + cet.output[0].value, &generate_single_outcome_messages(SINGLE_NB_ORACLES, SINGLE_NB_NONCES), ) .unwrap(), @@ -164,7 +164,7 @@ mod benches { adaptor_point, &seckey, &funding_script_pubkey(), - cet.output[0].value.to_sat(), + cet.output[0].value, ) .unwrap(), ) diff --git a/dlc/src/channel/mod.rs b/dlc/src/channel/mod.rs index 6c81aa84..8eb3bd16 100644 --- a/dlc/src/channel/mod.rs +++ b/dlc/src/channel/mod.rs @@ -114,7 +114,7 @@ pub struct DlcChannelTransactions { pub fn create_buffer_transaction( fund_tx_in: &TxIn, descriptor: &Descriptor, - total_collateral: u64, + total_collateral: Amount, lock_time: u32, ) -> Transaction { Transaction { @@ -122,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: Amount::from_sat(total_collateral), + value: total_collateral, script_pubkey: descriptor.script_pubkey(), }], } @@ -133,7 +133,7 @@ pub fn create_buffer_transaction( pub fn get_tx_adaptor_signature( secp: &Secp256k1, tx: &Transaction, - input_value: u64, + input_value: Amount, script_pubkey: &Script, own_fund_sk: &SecretKey, other_publish_key: &SecpPublicKey, @@ -155,7 +155,7 @@ pub fn get_tx_adaptor_signature( pub fn verify_tx_adaptor_signature( secp: &Secp256k1, tx: &Transaction, - input_value: u64, + input_value: Amount, script_pubkey: &Script, other_fund_pk: &SecpPublicKey, own_publish_key: &SecpPublicKey, @@ -173,11 +173,11 @@ pub fn create_settle_transaction( fund_tx_in: &TxIn, offer_revoke_params: &RevokeParams, accept_revoke_params: &RevokeParams, - offer_payout: u64, - accept_payout: u64, + offer_payout: Amount, + accept_payout: Amount, csv_timelock: u32, lock_time: u32, - fund_output_value: u64, + fund_output_value: Amount, fee_rate_per_vb: u64, ) -> Result { let offer_descriptor = settle_descriptor( @@ -194,11 +194,11 @@ pub fn create_settle_transaction( let mut output = crate::util::discard_dust( vec![ TxOut { - value: Amount::from_sat(offer_payout), + value: offer_payout, script_pubkey: offer_descriptor.script_pubkey(), }, TxOut { - value: Amount::from_sat(accept_payout), + value: accept_payout, script_pubkey: accept_descriptor.script_pubkey(), }, ], @@ -217,7 +217,7 @@ pub fn create_settle_transaction( / (output.len() as u64); for o in &mut output { - o.value += Amount::from_sat(remaining_fee); + o.value += remaining_fee; } Ok(Transaction { @@ -307,7 +307,7 @@ pub fn create_renewal_channel_transactions( let buffer_transaction = create_buffer_transaction( &tx_in, &buffer_descriptor, - fund_output.value.to_sat() - extra_fee, + fund_output.value - extra_fee, cet_lock_time, ); @@ -342,7 +342,7 @@ pub fn create_renewal_channel_transactions( pub fn sign_cet( secp: &Secp256k1, cet: &mut Transaction, - input_amount: u64, + input_amount: Amount, offer_params: &RevokeParams, accept_params: &RevokeParams, own_sk: &SecretKey, @@ -423,14 +423,14 @@ 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.to_sat() - tx_fee; + let output_value = prev_tx.output[0].value - 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: Amount::from_sat(output_value), + value: output_value, script_pubkey: dest_address.script_pubkey(), }], }; @@ -454,7 +454,7 @@ pub fn create_and_sign_punish_buffer_transaction( &tx, 0, &descriptor.script_code()?, - prev_tx.output[0].value.to_sat(), + prev_tx.output[0].value, sk, )?, sighash_type: EcdsaSighashType::All, @@ -505,7 +505,7 @@ pub fn create_and_sign_punish_settle_transaction( witness: Witness::default(), }; - let input_value = prev_tx.output[vout as usize].value.to_sat(); + let input_value = prev_tx.output[vout as usize].value; 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); @@ -518,7 +518,7 @@ pub fn create_and_sign_punish_settle_transaction( lock_time: LockTime::from_consensus(lock_time), input: vec![tx_in], output: vec![TxOut { - value: Amount::from_sat(input_value - tx_fee), + value: input_value - tx_fee, script_pubkey: dest_address.script_pubkey(), }], }; @@ -553,11 +553,11 @@ pub fn create_and_sign_punish_settle_transaction( /// Create a transaction for collaboratively closing a channel. pub fn create_collaborative_close_transaction( offer_params: &PartyParams, - offer_payout: u64, + offer_payout: Amount, accept_params: &PartyParams, - accept_payout: u64, + accept_payout: Amount, fund_outpoint: OutPoint, - _fund_output_amount: u64, + _fund_output_amount: Amount, ) -> Transaction { let input = TxIn { previous_output: fund_outpoint, @@ -568,12 +568,12 @@ pub fn create_collaborative_close_transaction( //TODO(tibo): add fee re-payment let offer_output = TxOut { - value: Amount::from_sat(offer_payout), + value: offer_payout, script_pubkey: offer_params.payout_script_pubkey.clone(), }; let accept_output = TxOut { - value: Amount::from_sat(accept_payout), + value: accept_payout, script_pubkey: accept_params.payout_script_pubkey.clone(), }; @@ -699,7 +699,7 @@ mod tests { ), Network::Regtest, ); - let total_collateral = 100000000; + let total_collateral = Amount::ONE_BTC; let descriptor = buffer_descriptor(&offer_params, &accept_params); @@ -812,7 +812,7 @@ mod tests { ), Network::Regtest, ); - let payout = 100000000; + let payout = Amount::ONE_BTC; let csv_timelock = 100; let settle_tx = create_settle_transaction( &TxIn::default(), @@ -822,7 +822,7 @@ mod tests { payout, csv_timelock, 0, - 200020000, + Amount::from_sat(200020000), FEE_RATE_PER_VB, ) .unwrap(); @@ -938,14 +938,14 @@ mod tests { let accept_priv_params = RevokePrivateParams::new(Network::Regtest); let offer_params = offer_priv_params.public_params(SECP256K1); let accept_params = accept_priv_params.public_params(SECP256K1); - let total_collateral = 100000000; + let total_collateral = Amount::ONE_BTC; let descriptor = buffer_descriptor(&offer_params, &accept_params); let buffer_tx = create_buffer_transaction(&TxIn::default(), &descriptor, total_collateral, 0); - let input_value = total_collateral + 10000; + let input_value = total_collateral + Amount::from_sat(10000); let adaptor_sec_key = SecretKey::new(&mut thread_rng()); diff --git a/dlc/src/lib.rs b/dlc/src/lib.rs index 9f8aa1ca..733182d3 100644 --- a/dlc/src/lib.rs +++ b/dlc/src/lib.rs @@ -50,7 +50,7 @@ pub mod util; /// Minimum value that can be included in a transaction output. Under this value, /// outputs are discarded /// See: https://github.com/discreetlogcontracts/dlcspecs/blob/master/Transactions.md#change-outputs -const DUST_LIMIT: u64 = 1000; +const DUST_LIMIT: Amount = Amount::from_sat(1000); /// The transaction version /// See: https://github.com/discreetlogcontracts/dlcspecs/blob/master/Transactions.md#funding-transaction @@ -91,9 +91,9 @@ macro_rules! checked_add { #[cfg_attr(feature = "use-serde", derive(Serialize, Deserialize))] pub struct Payout { /// Payout for the offering party - pub offer: u64, + pub offer: Amount, /// Payout for the accepting party - pub accept: u64, + pub accept: Amount, } #[derive(Eq, PartialEq, Debug, Clone)] @@ -280,9 +280,9 @@ pub struct PartyParams { /// A list of inputs to fund the contract pub inputs: Vec, /// The sum of the inputs values. - pub input_amount: u64, + pub input_amount: Amount, /// The collateral put in the contract by the party - pub collateral: u64, + pub collateral: Amount, } impl PartyParams { @@ -294,8 +294,8 @@ impl PartyParams { pub(crate) fn get_change_output_and_fees( &self, fee_rate_per_vb: u64, - extra_fee: u64, - ) -> Result<(TxOut, u64, u64), Error> { + extra_fee: Amount, + ) -> Result<(TxOut, Amount, Amount), Error> { let mut inputs_weight: usize = 0; for w in &self.inputs { @@ -347,7 +347,7 @@ impl PartyParams { } let change_output = TxOut { - value: Amount::from_sat(self.input_amount - required_input_funds), + value: self.input_amount - required_input_funds, script_pubkey: self.change_script_pubkey.clone(), }; @@ -390,7 +390,7 @@ pub fn create_dlc_transactions( fee_rate_per_vb, fund_lock_time, fund_output_serial_id, - 0, + Amount::ZERO, )?; let fund_outpoint = OutPoint { txid: fund_tx.compute_txid(), @@ -422,7 +422,7 @@ pub(crate) fn create_fund_transaction_with_fees( fee_rate_per_vb: u64, fund_lock_time: u32, fund_output_serial_id: u64, - extra_fee: u64, + extra_fee: Amount, ) -> Result<(Transaction, ScriptBuf), Error> { let total_collateral = checked_add!(offer_params.collateral, accept_params.collateral)?; @@ -432,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.to_sat() - - accept_change_output.value.to_sat() + - offer_change_output.value + - accept_change_output.value - offer_fund_fee - accept_fund_fee - extra_fee; @@ -446,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.to_sat() - + accept_change_output.value.to_sat() + + offer_change_output.value + + accept_change_output.value + offer_fund_fee + accept_fund_fee + extra_fee @@ -522,12 +522,12 @@ pub(crate) fn create_cets_and_refund_tx( ); let offer_refund_output = TxOut { - value: Amount::from_sat(offer_params.collateral), + value: offer_params.collateral, script_pubkey: offer_params.payout_script_pubkey.clone(), }; let accept_refund_ouput = TxOut { - value: Amount::from_sat(accept_params.collateral), + value: accept_params.collateral, script_pubkey: accept_params.payout_script_pubkey.clone(), }; @@ -586,11 +586,11 @@ pub fn create_cets( let mut txs: Vec = Vec::new(); for payout in payouts { let offer_output = TxOut { - value: Amount::from_sat(payout.offer), + value: payout.offer, script_pubkey: offer_payout_script_pubkey.to_owned(), }; let accept_output = TxOut { - value: Amount::from_sat(payout.accept), + value: payout.accept, script_pubkey: accept_payout_script_pubkey.to_owned(), }; let tx = create_cet( @@ -611,7 +611,7 @@ pub fn create_cets( /// Create a funding transaction pub fn create_funding_transaction( funding_script_pubkey: &Script, - output_amount: u64, + output_amount: Amount, offer_inputs: &[TxIn], offer_inputs_serial_ids: &[u64], accept_inputs: &[TxIn], @@ -624,7 +624,7 @@ pub fn create_funding_transaction( lock_time: u32, ) -> Transaction { let fund_tx_out = TxOut { - value: Amount::from_sat(output_amount), + value: output_amount, script_pubkey: funding_script_pubkey.to_p2wsh(), }; @@ -733,7 +733,7 @@ pub fn create_cet_adaptor_sig_from_point( adaptor_point: &PublicKey, funding_sk: &SecretKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, ) -> Result { let sig_hash = util::get_sig_hash_msg(cet, 0, funding_script_pubkey, fund_output_value)?; @@ -754,7 +754,7 @@ pub fn create_cet_adaptor_sig_from_oracle_info( oracle_infos: &[OracleInfo], funding_sk: &SecretKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, msgs: &[Vec], ) -> Result { let adaptor_point = get_adaptor_point_from_oracle_info(secp, oracle_infos, msgs)?; @@ -774,7 +774,7 @@ pub fn create_cet_adaptor_sigs_from_points( inputs: &[(&Transaction, &PublicKey)], funding_sk: &SecretKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, ) -> Result, Error> { inputs .iter() @@ -798,7 +798,7 @@ pub fn create_cet_adaptor_sigs_from_oracle_info( oracle_infos: &[OracleInfo], funding_sk: &SecretKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, msgs: &[Vec>], ) -> Result, Error> { if msgs.len() != cets.len() { @@ -851,7 +851,7 @@ pub fn sign_cet( funding_sk: &SecretKey, other_pk: &PublicKey, funding_script_pubkey: &Script, - fund_output_value: u64, + fund_output_value: Amount, ) -> Result<(), Error> { let adaptor_secret = signatures_to_secret(oracle_signatures)?; let adapted_sig = adaptor_signature.decrypt(&adaptor_secret)?; @@ -879,7 +879,7 @@ pub fn verify_cet_adaptor_sig_from_point( adaptor_point: &PublicKey, pubkey: &PublicKey, funding_script_pubkey: &Script, - total_collateral: u64, + total_collateral: Amount, ) -> Result<(), Error> { let sig_hash = util::get_sig_hash_msg(cet, 0, funding_script_pubkey, total_collateral)?; adaptor_sig.verify(secp, &sig_hash, pubkey, adaptor_point)?; @@ -895,7 +895,7 @@ pub fn verify_cet_adaptor_sig_from_oracle_info( oracle_infos: &[OracleInfo], pubkey: &PublicKey, funding_script_pubkey: &Script, - total_collateral: u64, + total_collateral: Amount, msgs: &[Vec], ) -> Result<(), Error> { let adaptor_point = get_adaptor_point_from_oracle_info(secp, oracle_infos, msgs)?; @@ -917,7 +917,7 @@ pub fn verify_tx_input_sig( tx: &Transaction, input_index: usize, script_pubkey: &Script, - value: u64, + value: Amount, pk: &PublicKey, ) -> Result<(), Error> { let sig_hash_msg = util::get_sig_hash_msg(tx, input_index, script_pubkey, value)?; @@ -968,12 +968,12 @@ mod tests { fn create_test_tx_io() -> (TxOut, TxOut, TxIn) { let offer = TxOut { - value: Amount::from_sat(DUST_LIMIT + 1), + value: DUST_LIMIT + Amount::from_sat(1), script_pubkey: ScriptBuf::new(), }; let accept = TxOut { - value: Amount::from_sat(DUST_LIMIT + 2), + value: DUST_LIMIT + Amount::from_sat(2), script_pubkey: ScriptBuf::new(), }; @@ -994,8 +994,14 @@ mod tests { let refund_transaction = create_refund_transaction(offer, accept, funding, 0); 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.to_sat()); - assert_eq!(DUST_LIMIT + 2, refund_transaction.output[1].value.to_sat()); + assert_eq!( + DUST_LIMIT + Amount::from_sat(1), + refund_transaction.output[0].value + ); + assert_eq!( + DUST_LIMIT + Amount::from_sat(2), + refund_transaction.output[1].value + ); assert_eq!(3, refund_transaction.input[0].sequence.0); } @@ -1008,7 +1014,7 @@ mod tests { let change = Amount::from_sat(1000); - let total_collateral = 31415; + let total_collateral = Amount::from_sat(31415); let offer_change_output = TxOut { value: change, @@ -1038,7 +1044,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.to_sat(), total_collateral); + assert_eq!(transaction.output[0].value, total_collateral); assert_eq!(transaction.output[1].value, change); assert_eq!(transaction.output[2].value, change); assert_eq!(transaction.output.len(), 3); @@ -1051,7 +1057,7 @@ mod tests { let offer_inputs = create_txin_vec(Sequence::ZERO); let accept_inputs = create_txin_vec(Sequence(1)); - let total_collateral = 31415; + let total_collateral = Amount::from_sat(31415); let change = Amount::from_sat(999); let offer_change_output = TxOut { @@ -1080,16 +1086,16 @@ mod tests { 0, ); - assert_eq!(transaction.output[0].value.to_sat(), total_collateral); + assert_eq!(transaction.output[0].value, total_collateral); assert_eq!(transaction.output.len(), 1); } #[test] fn create_funding_transaction_serialized_test() { let secp = Secp256k1::new(); - let input_amount = 5000000000; + let input_amount = Amount::from_sat(5000000000); let change = Amount::from_sat(4899999719); - let total_collateral = 200000312; + let total_collateral = Amount::from_sat(200000312); let offer_change_address = Address::from_str("bcrt1qlgmznucxpdkp5k3ktsct7eh6qrc4tju7ktjukn") .unwrap() @@ -1213,8 +1219,8 @@ mod tests { } fn get_party_params( - input_amount: u64, - collateral: u64, + input_amount: Amount, + collateral: Amount, serial_id: Option, ) -> (PartyParams, SecretKey) { let secp = Secp256k1::new(); @@ -1250,12 +1256,12 @@ mod tests { fn payouts() -> Vec { vec![ Payout { - offer: 200000000, - accept: 0, + offer: Amount::from_sat(200_000_000), + accept: Amount::ZERO, }, Payout { - offer: 0, - accept: 200000000, + offer: Amount::ZERO, + accept: Amount::from_sat(200_000_000), }, ] } @@ -1263,24 +1269,29 @@ mod tests { #[test] fn get_change_output_and_fees_enough_funds() { // Arrange - let (party_params, _) = get_party_params(100000, 10000, None); + let (party_params, _) = + get_party_params(Amount::from_sat(100000), Amount::from_sat(10000), None); // Act - let (change_out, fund_fee, cet_fee) = - party_params.get_change_output_and_fees(4, 0).unwrap(); + let (change_out, fund_fee, cet_fee) = party_params + .get_change_output_and_fees(4, Amount::ZERO) + .unwrap(); // Assert - assert!(change_out.value > Amount::ZERO && fund_fee > 0 && cet_fee > 0); + assert!( + change_out.value > Amount::ZERO && fund_fee > Amount::ZERO && cet_fee > Amount::ZERO + ); } #[test] fn get_change_output_and_fees_not_enough_funds() { // Arrange - let (party_params, _) = get_party_params(100000, 100000, None); + let (party_params, _) = + get_party_params(Amount::from_sat(100000), Amount::from_sat(100000), None); // Act - let res = party_params.get_change_output_and_fees(4, 0); + let res = party_params.get_change_output_and_fees(4, Amount::ZERO); // Assert assert!(res.is_err()); @@ -1289,8 +1300,16 @@ mod tests { #[test] fn create_dlc_transactions_no_error() { // Arrange - let (offer_party_params, _) = get_party_params(1000000000, 100000000, None); - let (accept_party_params, _) = get_party_params(1000000000, 100000000, None); + let (offer_party_params, _) = get_party_params( + Amount::from_sat(1000000000), + Amount::from_sat(100000000), + None, + ); + let (accept_party_params, _) = get_party_params( + Amount::from_sat(1000000000), + Amount::from_sat(100000000), + None, + ); // Act let dlc_txs = create_dlc_transactions( @@ -1319,8 +1338,16 @@ mod tests { // Arrange let secp = Secp256k1::new(); let mut rng = secp256k1_zkp::rand::thread_rng(); - let (offer_party_params, offer_fund_sk) = get_party_params(1000000000, 100000000, None); - let (accept_party_params, accept_fund_sk) = get_party_params(1000000000, 100000000, None); + let (offer_party_params, offer_fund_sk) = get_party_params( + Amount::from_sat(1000000000), + Amount::from_sat(100000000), + None, + ); + let (accept_party_params, accept_fund_sk) = get_party_params( + Amount::from_sat(1000000000), + Amount::from_sat(100000000), + None, + ); let dlc_txs = create_dlc_transactions( &offer_party_params, @@ -1391,7 +1418,7 @@ mod tests { &offer_party_params.fund_pubkey, &accept_party_params.fund_pubkey, ); - let fund_output_value = dlc_txs.fund.output[0].value.to_sat(); + let fund_output_value = dlc_txs.fund.output[0].value; // Act let cet_sigs = create_cet_adaptor_sigs_from_oracle_info( @@ -1484,17 +1511,23 @@ mod tests { ]; for case in cases { - let (offer_party_params, _) = - get_party_params(1000000000, 100000000, Some(case.serials[1])); - let (accept_party_params, _) = - get_party_params(1000000000, 100000000, Some(case.serials[2])); + let (offer_party_params, _) = get_party_params( + Amount::from_sat(1000000000), + Amount::from_sat(100000000), + Some(case.serials[1]), + ); + let (accept_party_params, _) = get_party_params( + Amount::from_sat(1000000000), + Amount::from_sat(100000000), + Some(case.serials[2]), + ); let dlc_txs = create_dlc_transactions( &offer_party_params, &accept_party_params, &[Payout { - offer: 100000000, - accept: 100000000, + offer: Amount::from_sat(100000000), + accept: Amount::from_sat(100000000), }], 100, 4, diff --git a/dlc/src/util.rs b/dlc/src/util.rs index c251b764..48e07548 100644 --- a/dlc/src/util.rs +++ b/dlc/src/util.rs @@ -22,12 +22,12 @@ pub(crate) fn get_sig_hash_msg( tx: &Transaction, input_index: usize, script_pubkey: &Script, - value: u64, + value: Amount, ) -> Result { let sig_hash = SighashCache::new(tx).p2wsh_signature_hash( input_index, script_pubkey, - Amount::from_sat(value), + value, EcdsaSighashType::All, )?; @@ -50,7 +50,7 @@ pub fn get_raw_sig_for_tx_input( tx: &Transaction, input_index: usize, script_pubkey: &Script, - value: u64, + value: Amount, sk: &SecretKey, ) -> Result { let sig_hash_msg = get_sig_hash_msg(tx, input_index, script_pubkey, value)?; @@ -64,7 +64,7 @@ pub fn get_sig_for_tx_input( tx: &Transaction, input_index: usize, script_pubkey: &Script, - value: u64, + value: Amount, sig_hash_type: EcdsaSighashType, sk: &SecretKey, ) -> Result, Error> { @@ -78,7 +78,7 @@ pub fn get_sig_for_p2wpkh_input( sk: &SecretKey, tx: &Transaction, input_index: usize, - value: u64, + value: Amount, sig_hash_type: EcdsaSighashType, ) -> Result, Error> { let script_pubkey = get_pkh_script_pubkey_from_sk(secp, sk); @@ -94,14 +94,15 @@ pub fn get_sig_for_p2wpkh_input( } /// Returns the fee for the given weight at given fee rate. -pub fn weight_to_fee(weight: usize, fee_rate: u64) -> Result { - (f64::ceil((weight as f64) / 4.0) as u64) +pub fn weight_to_fee(weight: usize, fee_rate: u64) -> Result { + let amount = (f64::ceil((weight as f64) / 4.0) as u64) .checked_mul(fee_rate) - .ok_or(Error::InvalidArgument) + .ok_or(Error::InvalidArgument)?; + Ok(Amount::from_sat(amount)) } /// Return the common base fee for a DLC for the given fee rate. -pub fn get_common_fee(fee_rate: u64) -> Result { +pub fn get_common_fee(fee_rate: u64) -> Result { let base_weight = crate::FUND_TX_BASE_WEIGHT + crate::CET_BASE_WEIGHT; weight_to_fee(base_weight, fee_rate) } @@ -129,7 +130,7 @@ pub fn sign_p2wpkh_input( tx: &mut Transaction, input_index: usize, sig_hash_type: EcdsaSighashType, - value: u64, + value: Amount, ) -> Result<(), Error> { tx.input[input_index].witness = get_witness_for_p2wpkh_input(secp, sk, tx, input_index, sig_hash_type, value)?; @@ -143,7 +144,7 @@ pub fn get_witness_for_p2wpkh_input( tx: &Transaction, input_index: usize, sig_hash_type: EcdsaSighashType, - value: u64, + value: Amount, ) -> Result { let full_sig = get_sig_for_p2wpkh_input(secp, sk, tx, input_index, value, sig_hash_type)?; Ok(Witness::from_slice(&[ @@ -163,7 +164,7 @@ pub fn sign_multi_sig_input( other_pk: &PublicKey, sk: &SecretKey, script_pubkey: &Script, - input_value: u64, + input_value: Amount, input_index: usize, ) -> Result<(), Error> { let own_sig = get_sig_for_tx_input( @@ -231,10 +232,8 @@ 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.to_sat() >= dust_limit) - .collect() +pub(crate) fn discard_dust(txs: Vec, dust_limit: Amount) -> Vec { + txs.into_iter().filter(|x| x.value >= dust_limit).collect() } pub(crate) fn get_sequence(lock_time: u32) -> Sequence { diff --git a/mocks/src/mock_wallet.rs b/mocks/src/mock_wallet.rs index 5bb062fc..8386ab42 100644 --- a/mocks/src/mock_wallet.rs +++ b/mocks/src/mock_wallet.rs @@ -14,12 +14,12 @@ pub struct MockWallet { } impl MockWallet { - pub fn new(blockchain: &Rc, utxo_values: &[u64]) -> Self { + pub fn new(blockchain: &Rc, utxo_values: &[Amount]) -> Self { let mut utxos = Vec::with_capacity(utxo_values.len()); for utxo_value in utxo_values { let tx_out = TxOut { - value: Amount::from_sat(*utxo_value), + value: *utxo_value, script_pubkey: ScriptBuf::default(), }; let tx = Transaction { @@ -78,7 +78,7 @@ impl Wallet for MockWallet { fn get_utxos_for_amount( &self, - amount: u64, + amount: Amount, _fee_rate: u64, _lock_utxos: bool, ) -> Result, Error> { @@ -88,7 +88,7 @@ impl Wallet for MockWallet { seed, seed, )); - let mut sum = 0; + let mut sum = Amount::ZERO; let res = utxo_pool .iter() @@ -96,7 +96,7 @@ impl Wallet for MockWallet { if sum >= amount { return false; } - sum += x.tx_out.value.to_sat(); + sum += x.tx_out.value; true }) .cloned() diff --git a/sample/src/cli.rs b/sample/src/cli.rs index c55b3795..1924cf89 100644 --- a/sample/src/cli.rs +++ b/sample/src/cli.rs @@ -4,6 +4,7 @@ use crate::DlcManager; use crate::DlcMessageHandler; use crate::PeerManager; use bitcoin::secp256k1::PublicKey; +use bitcoin::Amount; use dlc_manager::channel::signed_channel::SignedChannelState; use dlc_manager::channel::signed_channel::SignedChannelStateType; use dlc_manager::contract::contract_input::ContractInput; @@ -313,7 +314,7 @@ pub(crate) async fn poll_for_user_input( } s @ "offersettlechannel" => { let channel_id = read_id_or_continue!(words, s, "channel id"); - let counter_payout: u64 = match words.next().map(|w| w.parse().ok()) { + let counter_payout: Amount = match words.next().map(|w| w.parse().ok()) { Some(Some(p)) => p, _ => { println!("Missing or invalid counter payout parameter"); diff --git a/simple-wallet/src/lib.rs b/simple-wallet/src/lib.rs index a2ed414b..cf2ef025 100644 --- a/simple-wallet/src/lib.rs +++ b/simple-wallet/src/lib.rs @@ -96,12 +96,12 @@ where } /// Returns the sum of all UTXOs value. - pub fn get_balance(&self) -> u64 { + pub fn get_balance(&self) -> Amount { self.storage .get_utxos() .unwrap() .iter() - .map(|x| x.tx_out.value.to_sat()) + .map(|x| x.tx_out.value) .sum() } @@ -237,7 +237,7 @@ where fn get_utxos_for_amount( &self, - amount: u64, + amount: Amount, fee_rate: u64, lock_utxos: bool, ) -> Result> { @@ -270,7 +270,7 @@ where Vec::new(), utxos, fee_rate, - amount, + amount.to_sat(), &dummy_drain, &mut bitcoin::key::rand::thread_rng(), ) @@ -347,7 +347,7 @@ where &mut tx, input_index, bitcoin::sighash::EcdsaSighashType::All, - tx_out.value.to_sat(), + tx_out.value, )?; let tx_input = tx.input[input_index].clone();