From 6a38ba97e9cebf19dbd8ed63846eda1cd38ad825 Mon Sep 17 00:00:00 2001 From: bennyhodl Date: Fri, 1 Nov 2024 13:38:49 -0400 Subject: [PATCH] Only run integration tests in sync --- dlc-manager/tests/channel_execution_tests.rs | 2373 +++++++++--------- dlc-manager/tests/manager_execution_tests.rs | 1605 ++++++------ p2pd-oracle-client/src/lib.rs | 1 + 3 files changed, 2000 insertions(+), 1979 deletions(-) diff --git a/dlc-manager/tests/channel_execution_tests.rs b/dlc-manager/tests/channel_execution_tests.rs index 05da7bb5..1aa3d602 100644 --- a/dlc-manager/tests/channel_execution_tests.rs +++ b/dlc-manager/tests/channel_execution_tests.rs @@ -1,747 +1,673 @@ #[macro_use] mod test_utils; -use bitcoin::Amount; -use bitcoin_test_utils::rpc_helpers::init_clients; -use bitcoincore_rpc::RpcApi; -use dlc_manager::contract::contract_input::ContractInput; -use dlc_manager::manager::Manager; -use dlc_manager::{ - channel::Channel, contract::Contract, Blockchain, CachedContractSignerProvider, Oracle, - SimpleSigner, Storage, Wallet, -}; -use dlc_manager::{ChannelId, ContractId}; -use dlc_messages::Message; -use electrs_blockchain_provider::ElectrsBlockchainProvider; -use lightning::util::ser::Writeable; -use mocks::memory_storage_provider::MemoryStorage; -use mocks::mock_oracle_provider::MockOracle; -use mocks::mock_time::MockTime; -use secp256k1_zkp::rand::{thread_rng, RngCore}; -use secp256k1_zkp::EcdsaAdaptorSignature; -use simple_wallet::SimpleWallet; -use test_utils::{get_enum_test_params, TestParams}; - -use std::sync::mpsc::{sync_channel, Receiver, Sender}; -use std::thread; - -use std::time::Duration; -use std::{ - collections::HashMap, - sync::{ - atomic::{AtomicBool, Ordering}, - mpsc::channel, - Arc, Mutex, - }, -}; - -use crate::test_utils::{refresh_wallet, EVENT_MATURITY}; - -type DlcParty = Arc< - Mutex< - Manager< - Arc, Arc>>, - Arc< - CachedContractSignerProvider< - Arc, Arc>>, - SimpleSigner, +#[cfg(not(feature = "async"))] +mod sync_tests { + use crate::test_utils::{get_enum_test_params, TestParams}; + use bitcoin::Amount; + use bitcoin_test_utils::rpc_helpers::init_clients; + use bitcoincore_rpc::RpcApi; + use dlc_manager::contract::contract_input::ContractInput; + use dlc_manager::manager::Manager; + use dlc_manager::{ + channel::Channel, contract::Contract, Blockchain, CachedContractSignerProvider, Oracle, + SimpleSigner, Storage, Wallet, + }; + use dlc_manager::{ChannelId, ContractId}; + use dlc_messages::Message; + use electrs_blockchain_provider::ElectrsBlockchainProvider; + use lightning::util::ser::Writeable; + use mocks::memory_storage_provider::MemoryStorage; + use mocks::mock_oracle_provider::MockOracle; + use mocks::mock_time::MockTime; + use secp256k1_zkp::rand::{thread_rng, RngCore}; + use secp256k1_zkp::EcdsaAdaptorSignature; + use simple_wallet::SimpleWallet; + + use std::sync::mpsc::{sync_channel, Receiver, Sender}; + use std::thread; + + use std::time::Duration; + use std::{ + collections::HashMap, + sync::{ + atomic::{AtomicBool, Ordering}, + mpsc::channel, + Arc, Mutex, + }, + }; + + use crate::test_utils::{refresh_wallet, EVENT_MATURITY}; + + type DlcParty = Arc< + Mutex< + Manager< + Arc, Arc>>, + Arc< + CachedContractSignerProvider< + Arc, Arc>>, + SimpleSigner, + >, >, + Arc, + Arc, + Arc, + Arc, + Arc, + SimpleSigner, >, - Arc, - Arc, - Arc, - Arc, - Arc, - SimpleSigner, >, - >, ->; - -fn get_established_channel_contract_id(dlc_party: &DlcParty, channel_id: &ChannelId) -> ContractId { - let channel = dlc_party - .lock() - .unwrap() - .get_store() - .get_channel(channel_id) - .unwrap() - .unwrap(); - if let Channel::Signed(s) = channel { - return s.get_contract_id().expect("to have a contract id"); + >; + + fn get_established_channel_contract_id( + dlc_party: &DlcParty, + channel_id: &ChannelId, + ) -> ContractId { + let channel = dlc_party + .lock() + .unwrap() + .get_store() + .get_channel(channel_id) + .unwrap() + .unwrap(); + if let Channel::Signed(s) = channel { + return s.get_contract_id().expect("to have a contract id"); + } + + panic!("Invalid channel state {:?}.", channel); } - panic!("Invalid channel state {:?}.", channel); -} + fn alter_adaptor_sig(input: &EcdsaAdaptorSignature) -> EcdsaAdaptorSignature { + let mut copy = input.as_ref().to_vec(); + let i = + thread_rng().next_u32() as usize % secp256k1_zkp::ffi::ECDSA_ADAPTOR_SIGNATURE_LENGTH; + copy[i] = copy[i].checked_add(1).unwrap_or(0); + EcdsaAdaptorSignature::from_slice(©).expect("to be able to create an adaptor signature") + } -fn alter_adaptor_sig(input: &EcdsaAdaptorSignature) -> EcdsaAdaptorSignature { - let mut copy = input.as_ref().to_vec(); - let i = thread_rng().next_u32() as usize % secp256k1_zkp::ffi::ECDSA_ADAPTOR_SIGNATURE_LENGTH; - copy[i] = copy[i].checked_add(1).unwrap_or(0); - EcdsaAdaptorSignature::from_slice(©).expect("to be able to create an adaptor signature") -} + /// We wrap updating the state of the chain monitor and calling the + /// `Manager::periodic_check` because the latter will only be aware of + /// newly confirmed transactions if the former processes new blocks. + fn periodic_check(dlc_party: DlcParty) { + let dlc_manager = dlc_party.lock().unwrap(); -/// We wrap updating the state of the chain monitor and calling the -/// `Manager::periodic_check` because the latter will only be aware of -/// newly confirmed transactions if the former processes new blocks. -fn periodic_check(dlc_party: DlcParty) { - let dlc_manager = dlc_party.lock().unwrap(); + dlc_manager.periodic_chain_monitor().unwrap(); + dlc_manager.periodic_check(true).unwrap(); + } - dlc_manager.periodic_chain_monitor().unwrap(); - dlc_manager.periodic_check(true).unwrap(); -} + #[derive(Eq, PartialEq, Clone)] + enum TestPath { + Close, + BadAcceptBufferAdaptorSignature, + BadSignBufferAdaptorSignature, + SettleClose, + BufferCheat, + RenewedClose, + SettleCheat, + CollaborativeClose, + SettleRenewSettle, + SettleOfferTimeout, + SettleAcceptTimeout, + SettleConfirmTimeout, + SettleReject, + SettleRace, + RenewOfferTimeout, + RenewAcceptTimeout, + RenewConfirmTimeout, + RenewFinalizeTimeout, + RenewReject, + RenewRace, + RenewEstablishedClose, + CancelOffer, + } -#[derive(Eq, PartialEq, Clone)] -enum TestPath { - Close, - BadAcceptBufferAdaptorSignature, - BadSignBufferAdaptorSignature, - SettleClose, - BufferCheat, - RenewedClose, - SettleCheat, - CollaborativeClose, - SettleRenewSettle, - SettleOfferTimeout, - SettleAcceptTimeout, - SettleConfirmTimeout, - SettleReject, - SettleRace, - RenewOfferTimeout, - RenewAcceptTimeout, - RenewConfirmTimeout, - RenewFinalizeTimeout, - RenewReject, - RenewRace, - RenewEstablishedClose, - CancelOffer, -} + #[test] + #[ignore] + fn channel_established_close_test() { + channel_execution_test(get_enum_test_params(1, 1, None), TestPath::Close); + } -#[test] -#[ignore] -fn channel_established_close_test() { - channel_execution_test(get_enum_test_params(1, 1, None), TestPath::Close); -} + #[test] + #[ignore] + fn channel_bad_accept_buffer_adaptor_test() { + channel_execution_test( + get_enum_test_params(1, 1, None), + TestPath::BadAcceptBufferAdaptorSignature, + ); + } -#[test] -#[ignore] -fn channel_bad_accept_buffer_adaptor_test() { - channel_execution_test( - get_enum_test_params(1, 1, None), - TestPath::BadAcceptBufferAdaptorSignature, - ); -} + #[test] + #[ignore] + fn channel_bad_sign_buffer_adaptor_test() { + channel_execution_test( + get_enum_test_params(1, 1, None), + TestPath::BadSignBufferAdaptorSignature, + ); + } -#[test] -#[ignore] -fn channel_bad_sign_buffer_adaptor_test() { - channel_execution_test( - get_enum_test_params(1, 1, None), - TestPath::BadSignBufferAdaptorSignature, - ); -} + #[test] + #[ignore] + fn channel_settled_close_test() { + channel_execution_test(get_enum_test_params(1, 1, None), TestPath::SettleClose); + } -#[test] -#[ignore] -fn channel_settled_close_test() { - channel_execution_test(get_enum_test_params(1, 1, None), TestPath::SettleClose); -} + #[test] + #[ignore] + fn channel_punish_buffer_test() { + channel_execution_test(get_enum_test_params(1, 1, None), TestPath::BufferCheat); + } -#[test] -#[ignore] -fn channel_punish_buffer_test() { - channel_execution_test(get_enum_test_params(1, 1, None), TestPath::BufferCheat); -} + #[test] + #[ignore] + fn channel_renew_close_test() { + channel_execution_test(get_enum_test_params(1, 1, None), TestPath::RenewedClose); + } -#[test] -#[ignore] -fn channel_renew_close_test() { - channel_execution_test(get_enum_test_params(1, 1, None), TestPath::RenewedClose); -} + #[test] + #[ignore] + fn channel_renew_established_close_test() { + channel_execution_test( + get_enum_test_params(1, 1, None), + TestPath::RenewEstablishedClose, + ); + } -#[test] -#[ignore] -fn channel_renew_established_close_test() { - channel_execution_test( - get_enum_test_params(1, 1, None), - TestPath::RenewEstablishedClose, - ); -} + #[test] + #[ignore] + fn channel_settle_cheat_test() { + channel_execution_test(get_enum_test_params(1, 1, None), TestPath::SettleCheat); + } -#[test] -#[ignore] -fn channel_settle_cheat_test() { - channel_execution_test(get_enum_test_params(1, 1, None), TestPath::SettleCheat); -} + #[test] + #[ignore] + fn channel_collaborative_close_test() { + channel_execution_test( + get_enum_test_params(1, 1, None), + TestPath::CollaborativeClose, + ); + } -#[test] -#[ignore] -fn channel_collaborative_close_test() { - channel_execution_test( - get_enum_test_params(1, 1, None), - TestPath::CollaborativeClose, - ); -} + #[test] + #[ignore] + fn channel_settle_renew_settle_test() { + channel_execution_test( + get_enum_test_params(1, 1, None), + TestPath::SettleRenewSettle, + ); + } -#[test] -#[ignore] -fn channel_settle_renew_settle_test() { - channel_execution_test( - get_enum_test_params(1, 1, None), - TestPath::SettleRenewSettle, - ); -} + #[test] + #[ignore] + fn channel_settle_offer_timeout_test() { + channel_execution_test( + get_enum_test_params(1, 1, None), + TestPath::SettleOfferTimeout, + ); + } -#[test] -#[ignore] -fn channel_settle_offer_timeout_test() { - channel_execution_test( - get_enum_test_params(1, 1, None), - TestPath::SettleOfferTimeout, - ); -} + #[test] + #[ignore] + fn channel_settle_accept_timeout_test() { + channel_execution_test( + get_enum_test_params(1, 1, None), + TestPath::SettleAcceptTimeout, + ); + } -#[test] -#[ignore] -fn channel_settle_accept_timeout_test() { - channel_execution_test( - get_enum_test_params(1, 1, None), - TestPath::SettleAcceptTimeout, - ); -} + #[test] + #[ignore] + fn channel_settle_confirm_timeout_test() { + channel_execution_test( + get_enum_test_params(1, 1, None), + TestPath::SettleConfirmTimeout, + ); + } -#[test] -#[ignore] -fn channel_settle_confirm_timeout_test() { - channel_execution_test( - get_enum_test_params(1, 1, None), - TestPath::SettleConfirmTimeout, - ); -} + #[test] + #[ignore] + fn channel_settle_reject_test() { + channel_execution_test(get_enum_test_params(1, 1, None), TestPath::SettleReject); + } -#[test] -#[ignore] -fn channel_settle_reject_test() { - channel_execution_test(get_enum_test_params(1, 1, None), TestPath::SettleReject); -} + #[test] + #[ignore] + fn channel_settle_race_test() { + channel_execution_test(get_enum_test_params(1, 1, None), TestPath::SettleRace); + } -#[test] -#[ignore] -fn channel_settle_race_test() { - channel_execution_test(get_enum_test_params(1, 1, None), TestPath::SettleRace); -} + #[test] + #[ignore] + fn channel_renew_offer_timeout_test() { + channel_execution_test( + get_enum_test_params(1, 1, None), + TestPath::RenewOfferTimeout, + ); + } -#[test] -#[ignore] -fn channel_renew_offer_timeout_test() { - channel_execution_test( - get_enum_test_params(1, 1, None), - TestPath::RenewOfferTimeout, - ); -} + #[test] + #[ignore] + fn channel_renew_accept_timeout_test() { + channel_execution_test( + get_enum_test_params(1, 1, None), + TestPath::RenewAcceptTimeout, + ); + } -#[test] -#[ignore] -fn channel_renew_accept_timeout_test() { - channel_execution_test( - get_enum_test_params(1, 1, None), - TestPath::RenewAcceptTimeout, - ); -} + #[test] + #[ignore] + fn channel_renew_confirm_timeout_test() { + channel_execution_test( + get_enum_test_params(1, 1, None), + TestPath::RenewConfirmTimeout, + ); + } -#[test] -#[ignore] -fn channel_renew_confirm_timeout_test() { - channel_execution_test( - get_enum_test_params(1, 1, None), - TestPath::RenewConfirmTimeout, - ); -} + #[test] + #[ignore] + fn channel_renew_finalize_timeout_test() { + channel_execution_test( + get_enum_test_params(1, 1, None), + TestPath::RenewFinalizeTimeout, + ); + } -#[test] -#[ignore] -fn channel_renew_finalize_timeout_test() { - channel_execution_test( - get_enum_test_params(1, 1, None), - TestPath::RenewFinalizeTimeout, - ); -} + #[test] + #[ignore] + fn channel_renew_reject_test() { + channel_execution_test(get_enum_test_params(1, 1, None), TestPath::RenewReject); + } -#[test] -#[ignore] -fn channel_renew_reject_test() { - channel_execution_test(get_enum_test_params(1, 1, None), TestPath::RenewReject); -} + #[test] + #[ignore] + fn channel_renew_race_test() { + channel_execution_test(get_enum_test_params(1, 1, None), TestPath::RenewRace); + } -#[test] -#[ignore] -fn channel_renew_race_test() { - channel_execution_test(get_enum_test_params(1, 1, None), TestPath::RenewRace); -} + #[test] + #[ignore] + fn channel_offer_reject_test() { + channel_execution_test(get_enum_test_params(1, 1, None), TestPath::CancelOffer); + } -#[test] -#[ignore] -fn channel_offer_reject_test() { - channel_execution_test(get_enum_test_params(1, 1, None), TestPath::CancelOffer); -} + fn channel_execution_test(test_params: TestParams, path: TestPath) { + env_logger::init(); + let (alice_send, bob_receive) = channel::>(); + let (bob_send, alice_receive) = channel::>(); + let (alice_sync_send, alice_sync_receive) = sync_channel::<()>(0); + let (bob_sync_send, bob_sync_receive) = sync_channel::<()>(0); -fn channel_execution_test(test_params: TestParams, path: TestPath) { - env_logger::init(); - let (alice_send, bob_receive) = channel::>(); - let (bob_send, alice_receive) = channel::>(); - let (alice_sync_send, alice_sync_receive) = sync_channel::<()>(0); - let (bob_sync_send, bob_sync_receive) = sync_channel::<()>(0); + let (_, _, sink_rpc) = init_clients(); - let (_, _, sink_rpc) = init_clients(); + let mut alice_oracles = HashMap::with_capacity(1); + let mut bob_oracles = HashMap::with_capacity(1); - let mut alice_oracles = HashMap::with_capacity(1); - let mut bob_oracles = HashMap::with_capacity(1); + for oracle in test_params.oracles { + let oracle = Arc::new(oracle); + alice_oracles.insert(oracle.get_public_key(), Arc::clone(&oracle)); + bob_oracles.insert(oracle.get_public_key(), Arc::clone(&oracle)); + } - for oracle in test_params.oracles { - let oracle = Arc::new(oracle); - alice_oracles.insert(oracle.get_public_key(), Arc::clone(&oracle)); - bob_oracles.insert(oracle.get_public_key(), Arc::clone(&oracle)); - } + let alice_store = Arc::new(mocks::memory_storage_provider::MemoryStorage::new()); + let bob_store = Arc::new(mocks::memory_storage_provider::MemoryStorage::new()); + let mock_time = Arc::new(mocks::mock_time::MockTime {}); + mocks::mock_time::set_time((EVENT_MATURITY as u64) - 1); + + let electrs = Arc::new(ElectrsBlockchainProvider::new( + "http://localhost:3004/".to_string(), + bitcoin::Network::Regtest, + )); + + let alice_wallet = Arc::new(SimpleWallet::new( + electrs.clone(), + alice_store.clone(), + bitcoin::Network::Regtest, + )); + + let bob_wallet = Arc::new(SimpleWallet::new( + electrs.clone(), + bob_store.clone(), + bitcoin::Network::Regtest, + )); + + let alice_fund_address = alice_wallet.get_new_address().unwrap(); + let bob_fund_address = bob_wallet.get_new_address().unwrap(); - let alice_store = Arc::new(mocks::memory_storage_provider::MemoryStorage::new()); - let bob_store = Arc::new(mocks::memory_storage_provider::MemoryStorage::new()); - let mock_time = Arc::new(mocks::mock_time::MockTime {}); - mocks::mock_time::set_time((EVENT_MATURITY as u64) - 1); - - let electrs = Arc::new(ElectrsBlockchainProvider::new( - "http://localhost:3004/".to_string(), - bitcoin::Network::Regtest, - )); - - let alice_wallet = Arc::new(SimpleWallet::new( - electrs.clone(), - alice_store.clone(), - bitcoin::Network::Regtest, - )); - - let bob_wallet = Arc::new(SimpleWallet::new( - electrs.clone(), - bob_store.clone(), - bitcoin::Network::Regtest, - )); - - let alice_fund_address = alice_wallet.get_new_address().unwrap(); - let bob_fund_address = bob_wallet.get_new_address().unwrap(); - - sink_rpc - .send_to_address( - &alice_fund_address, - Amount::from_btc(2.0).unwrap(), - None, - None, - None, - None, - None, - None, - ) - .unwrap(); - - sink_rpc - .send_to_address( - &bob_fund_address, - Amount::from_btc(2.0).unwrap(), - None, - None, - None, - None, - None, - None, - ) - .unwrap(); - - let generate_blocks = |nb_blocks: u64| { - let prev_blockchain_height = electrs.get_blockchain_height().unwrap(); - - let sink_address = sink_rpc - .get_new_address(None, None) - .expect("RPC Error") - .assume_checked(); sink_rpc - .generate_to_address(nb_blocks, &sink_address) - .expect("RPC Error"); - - // Wait for electrs to have processed the new blocks - let mut cur_blockchain_height = prev_blockchain_height; - while cur_blockchain_height < prev_blockchain_height + nb_blocks { - std::thread::sleep(std::time::Duration::from_millis(200)); - cur_blockchain_height = electrs.get_blockchain_height().unwrap(); - } - }; + .send_to_address( + &alice_fund_address, + Amount::from_btc(2.0).unwrap(), + None, + None, + None, + None, + None, + None, + ) + .unwrap(); + + sink_rpc + .send_to_address( + &bob_fund_address, + Amount::from_btc(2.0).unwrap(), + None, + None, + None, + None, + None, + None, + ) + .unwrap(); - generate_blocks(6); - - refresh_wallet(&alice_wallet, 200000000); - refresh_wallet(&bob_wallet, 200000000); - - let alice_manager = Arc::new(Mutex::new( - Manager::new( - Arc::clone(&alice_wallet), - Arc::clone(&alice_wallet), - Arc::clone(&electrs), - alice_store, - alice_oracles, - Arc::clone(&mock_time), - Arc::clone(&electrs), - ) - .unwrap(), - )); - - let alice_manager_loop = Arc::clone(&alice_manager); - let alice_manager_send = Arc::clone(&alice_manager); - - let bob_manager = Arc::new(Mutex::new( - Manager::new( - Arc::clone(&bob_wallet), - Arc::clone(&bob_wallet), - Arc::clone(&electrs), - Arc::clone(&bob_store), - bob_oracles, - Arc::clone(&mock_time), - Arc::clone(&electrs), - ) - .unwrap(), - )); - - let bob_manager_loop = Arc::clone(&bob_manager); - let bob_manager_send = Arc::clone(&bob_manager); - let alice_send_loop = alice_send.clone(); - let bob_send_loop = bob_send.clone(); - - let alice_expect_error = Arc::new(AtomicBool::new(false)); - let bob_expect_error = Arc::new(AtomicBool::new(false)); - - let alice_expect_error_loop = alice_expect_error.clone(); - let bob_expect_error_loop = bob_expect_error.clone(); - - let path_copy = path.clone(); - let msg_filter = move |msg| { - if let TestPath::SettleAcceptTimeout = path_copy { - if let Message::SettleConfirm(_) = msg { - return None; + let generate_blocks = |nb_blocks: u64| { + let prev_blockchain_height = electrs.get_blockchain_height().unwrap(); + + let sink_address = sink_rpc + .get_new_address(None, None) + .expect("RPC Error") + .assume_checked(); + sink_rpc + .generate_to_address(nb_blocks, &sink_address) + .expect("RPC Error"); + + // Wait for electrs to have processed the new blocks + let mut cur_blockchain_height = prev_blockchain_height; + while cur_blockchain_height < prev_blockchain_height + nb_blocks { + std::thread::sleep(std::time::Duration::from_millis(200)); + cur_blockchain_height = electrs.get_blockchain_height().unwrap(); } - } - if let TestPath::SettleConfirmTimeout = path_copy { - if let Message::SettleFinalize(_) = msg { - return None; + }; + + generate_blocks(6); + + refresh_wallet(&alice_wallet, 200000000); + refresh_wallet(&bob_wallet, 200000000); + + let alice_manager = Arc::new(Mutex::new( + Manager::new( + Arc::clone(&alice_wallet), + Arc::clone(&alice_wallet), + Arc::clone(&electrs), + alice_store, + alice_oracles, + Arc::clone(&mock_time), + Arc::clone(&electrs), + ) + .unwrap(), + )); + + let alice_manager_loop = Arc::clone(&alice_manager); + let alice_manager_send = Arc::clone(&alice_manager); + + let bob_manager = Arc::new(Mutex::new( + Manager::new( + Arc::clone(&bob_wallet), + Arc::clone(&bob_wallet), + Arc::clone(&electrs), + Arc::clone(&bob_store), + bob_oracles, + Arc::clone(&mock_time), + Arc::clone(&electrs), + ) + .unwrap(), + )); + + let bob_manager_loop = Arc::clone(&bob_manager); + let bob_manager_send = Arc::clone(&bob_manager); + let alice_send_loop = alice_send.clone(); + let bob_send_loop = bob_send.clone(); + + let alice_expect_error = Arc::new(AtomicBool::new(false)); + let bob_expect_error = Arc::new(AtomicBool::new(false)); + + let alice_expect_error_loop = alice_expect_error.clone(); + let bob_expect_error_loop = bob_expect_error.clone(); + + let path_copy = path.clone(); + let msg_filter = move |msg| { + if let TestPath::SettleAcceptTimeout = path_copy { + if let Message::SettleConfirm(_) = msg { + return None; + } } - } - if let TestPath::RenewAcceptTimeout = path_copy { - if let Message::RenewConfirm(_) = msg { - return None; + if let TestPath::SettleConfirmTimeout = path_copy { + if let Message::SettleFinalize(_) = msg { + return None; + } } - } - if let TestPath::RenewConfirmTimeout = path_copy { - if let Message::RenewFinalize(_) = msg { - return None; + if let TestPath::RenewAcceptTimeout = path_copy { + if let Message::RenewConfirm(_) = msg { + return None; + } } - } - Some(msg) - }; - - let msg_filter_copy = msg_filter.clone(); - let path_copy = path.clone(); - let alter_sign = move |msg| match msg { - Message::SignChannel(mut sign_channel) => { - if path_copy == TestPath::BadSignBufferAdaptorSignature { - sign_channel.buffer_adaptor_signature = - alter_adaptor_sig(&sign_channel.buffer_adaptor_signature); + if let TestPath::RenewConfirmTimeout = path_copy { + if let Message::RenewFinalize(_) = msg { + return None; + } } - Some(Message::SignChannel(sign_channel)) - } - _ => msg_filter_copy(msg), - }; + Some(msg) + }; + + let msg_filter_copy = msg_filter.clone(); + let path_copy = path.clone(); + let alter_sign = move |msg| match msg { + Message::SignChannel(mut sign_channel) => { + if path_copy == TestPath::BadSignBufferAdaptorSignature { + sign_channel.buffer_adaptor_signature = + alter_adaptor_sig(&sign_channel.buffer_adaptor_signature); + } + Some(Message::SignChannel(sign_channel)) + } + _ => msg_filter_copy(msg), + }; + + let alice_handle = receive_loop!( + alice_receive, + alice_manager_loop, + alice_send_loop, + alice_expect_error_loop, + alice_sync_send, + msg_filter, + |msg| msg + ); + + let bob_handle = receive_loop!( + bob_receive, + bob_manager_loop, + bob_send_loop, + bob_expect_error_loop, + bob_sync_send, + alter_sign, + |msg| msg + ); - let alice_handle = receive_loop!( - alice_receive, - alice_manager_loop, - alice_send_loop, - alice_expect_error_loop, - alice_sync_send, - msg_filter, - |msg| msg - ); - - let bob_handle = receive_loop!( - bob_receive, - bob_manager_loop, - bob_send_loop, - bob_expect_error_loop, - bob_sync_send, - alter_sign, - |msg| msg - ); - - let offer_msg = bob_manager_send - .lock() - .unwrap() - .offer_channel( - &test_params.contract_input, - "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166" - .parse() - .unwrap(), - ) - .expect("Send offer error"); - - let temporary_channel_id = offer_msg.temporary_channel_id; - bob_send - .send(Some(Message::OfferChannel(offer_msg))) - .unwrap(); - - assert_channel_state!(bob_manager_send, temporary_channel_id, Offered); - - alice_sync_receive.recv().expect("Error synchronizing"); - - assert_channel_state!(alice_manager_send, temporary_channel_id, Offered); - - if let TestPath::CancelOffer = path { - let (reject_msg, _) = alice_manager_send + let offer_msg = bob_manager_send .lock() .unwrap() - .reject_channel(&temporary_channel_id) - .expect("Error rejecting contract offer"); - assert_channel_state!(alice_manager_send, temporary_channel_id, Cancelled); - alice_send.send(Some(Message::Reject(reject_msg))).unwrap(); - - bob_sync_receive.recv().expect("Error synchronizing"); - assert_channel_state!(bob_manager_send, temporary_channel_id, Cancelled); - return; - } + .offer_channel( + &test_params.contract_input, + "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166" + .parse() + .unwrap(), + ) + .expect("Send offer error"); + + let temporary_channel_id = offer_msg.temporary_channel_id; + bob_send + .send(Some(Message::OfferChannel(offer_msg))) + .unwrap(); - let (mut accept_msg, channel_id, contract_id, _) = alice_manager_send - .lock() - .unwrap() - .accept_channel(&temporary_channel_id) - .expect("Error accepting contract offer"); - assert_channel_state!(alice_manager_send, channel_id, Accepted); - - match path { - TestPath::BadAcceptBufferAdaptorSignature => { - accept_msg.buffer_adaptor_signature = - alter_adaptor_sig(&accept_msg.buffer_adaptor_signature); - bob_expect_error.store(true, Ordering::Relaxed); - alice_send - .send(Some(Message::AcceptChannel(accept_msg))) - .unwrap(); - bob_sync_receive.recv().expect("Error synchronizing"); - assert_channel_state!(bob_manager_send, temporary_channel_id, FailedAccept); - } - TestPath::BadSignBufferAdaptorSignature => { - alice_expect_error.store(true, Ordering::Relaxed); - alice_send - .send(Some(Message::AcceptChannel(accept_msg))) - .unwrap(); - // Bob receives accept message - bob_sync_receive.recv().expect("Error synchronizing"); - // Alice receives sign message - alice_sync_receive.recv().expect("Error synchronizing"); - assert_channel_state!(alice_manager_send, channel_id, FailedSign); - } - _ => { - alice_send - .send(Some(Message::AcceptChannel(accept_msg))) - .unwrap(); - bob_sync_receive.recv().expect("Error synchronizing"); + assert_channel_state!(bob_manager_send, temporary_channel_id, Offered); - assert_channel_state!(bob_manager_send, channel_id, Signed, Established); + alice_sync_receive.recv().expect("Error synchronizing"); - alice_sync_receive.recv().expect("Error synchronizing"); + assert_channel_state!(alice_manager_send, temporary_channel_id, Offered); - assert_channel_state!(alice_manager_send, channel_id, Signed, Established); + if let TestPath::CancelOffer = path { + let (reject_msg, _) = alice_manager_send + .lock() + .unwrap() + .reject_channel(&temporary_channel_id) + .expect("Error rejecting contract offer"); + assert_channel_state!(alice_manager_send, temporary_channel_id, Cancelled); + alice_send.send(Some(Message::Reject(reject_msg))).unwrap(); - generate_blocks(6); + bob_sync_receive.recv().expect("Error synchronizing"); + assert_channel_state!(bob_manager_send, temporary_channel_id, Cancelled); + return; + } - mocks::mock_time::set_time((EVENT_MATURITY as u64) + 1); + let (mut accept_msg, channel_id, contract_id, _) = alice_manager_send + .lock() + .unwrap() + .accept_channel(&temporary_channel_id) + .expect("Error accepting contract offer"); + assert_channel_state!(alice_manager_send, channel_id, Accepted); + + match path { + TestPath::BadAcceptBufferAdaptorSignature => { + accept_msg.buffer_adaptor_signature = + alter_adaptor_sig(&accept_msg.buffer_adaptor_signature); + bob_expect_error.store(true, Ordering::Relaxed); + alice_send + .send(Some(Message::AcceptChannel(accept_msg))) + .unwrap(); + bob_sync_receive.recv().expect("Error synchronizing"); + assert_channel_state!(bob_manager_send, temporary_channel_id, FailedAccept); + } + TestPath::BadSignBufferAdaptorSignature => { + alice_expect_error.store(true, Ordering::Relaxed); + alice_send + .send(Some(Message::AcceptChannel(accept_msg))) + .unwrap(); + // Bob receives accept message + bob_sync_receive.recv().expect("Error synchronizing"); + // Alice receives sign message + alice_sync_receive.recv().expect("Error synchronizing"); + assert_channel_state!(alice_manager_send, channel_id, FailedSign); + } + _ => { + alice_send + .send(Some(Message::AcceptChannel(accept_msg))) + .unwrap(); + bob_sync_receive.recv().expect("Error synchronizing"); - periodic_check(alice_manager_send.clone()); + assert_channel_state!(bob_manager_send, channel_id, Signed, Established); - periodic_check(bob_manager_send.clone()); + alice_sync_receive.recv().expect("Error synchronizing"); - assert_contract_state!(alice_manager_send, contract_id, Confirmed); - assert_contract_state!(bob_manager_send, contract_id, Confirmed); + assert_channel_state!(alice_manager_send, channel_id, Signed, Established); - // Select the first one to close or refund randomly - let (first, first_send, first_receive, second, second_send, second_receive) = - if thread_rng().next_u32() % 2 == 0 { - ( - alice_manager_send, - &alice_send, - &alice_sync_receive, - bob_manager_send, - &bob_send, - &bob_sync_receive, - ) - } else { - ( - bob_manager_send, - &bob_send, - &bob_sync_receive, - alice_manager_send, - &alice_send, - &alice_sync_receive, - ) - }; + generate_blocks(6); - match path { - TestPath::Close => { - close_established_channel(first, second, channel_id, &generate_blocks); - } - TestPath::CollaborativeClose => { - collaborative_close( - first, - first_send, - second, - channel_id, - second_receive, - &generate_blocks, - ); - } - TestPath::SettleOfferTimeout - | TestPath::SettleAcceptTimeout - | TestPath::SettleConfirmTimeout => { - settle_timeout( - first, - first_send, - first_receive, - second, - second_send, - second_receive, - channel_id, - path, - ); - } - TestPath::SettleReject => { - settle_reject( - first, - first_send, - first_receive, - second, - second_send, - second_receive, - channel_id, - ); - } - TestPath::SettleRace => { - settle_race( - first, - first_send, - first_receive, - second, - second_send, - second_receive, - channel_id, - ); - } - _ => { - // Shuffle positions - let (first, first_send, first_receive, second, second_send, second_receive) = - if thread_rng().next_u32() % 2 == 0 { - ( - first, - first_send, - first_receive, - second, - second_send, - second_receive, - ) - } else { - ( - second, - second_send, - second_receive, - first, - first_send, - first_receive, - ) - }; + mocks::mock_time::set_time((EVENT_MATURITY as u64) + 1); - first.lock().unwrap().get_store().save(); + periodic_check(alice_manager_send.clone()); - if let TestPath::RenewEstablishedClose = path { + periodic_check(bob_manager_send.clone()); + + assert_contract_state!(alice_manager_send, contract_id, Confirmed); + assert_contract_state!(bob_manager_send, contract_id, Confirmed); + + // Select the first one to close or refund randomly + let (first, first_send, first_receive, second, second_send, second_receive) = + if thread_rng().next_u32() % 2 == 0 { + ( + alice_manager_send, + &alice_send, + &alice_sync_receive, + bob_manager_send, + &bob_send, + &bob_sync_receive, + ) } else { - settle_channel( - first.clone(), + ( + bob_manager_send, + &bob_send, + &bob_sync_receive, + alice_manager_send, + &alice_send, + &alice_sync_receive, + ) + }; + + match path { + TestPath::Close => { + close_established_channel(first, second, channel_id, &generate_blocks); + } + TestPath::CollaborativeClose => { + collaborative_close( + first, + first_send, + second, + channel_id, + second_receive, + &generate_blocks, + ); + } + TestPath::SettleOfferTimeout + | TestPath::SettleAcceptTimeout + | TestPath::SettleConfirmTimeout => { + settle_timeout( + first, first_send, first_receive, - second.clone(), + second, second_send, second_receive, channel_id, + path, ); } - - match path { - TestPath::SettleClose => { - let closer = if thread_rng().next_u32() % 2 == 0 { - first + TestPath::SettleReject => { + settle_reject( + first, + first_send, + first_receive, + second, + second_send, + second_receive, + channel_id, + ); + } + TestPath::SettleRace => { + settle_race( + first, + first_send, + first_receive, + second, + second_send, + second_receive, + channel_id, + ); + } + _ => { + // Shuffle positions + let (first, first_send, first_receive, second, second_send, second_receive) = + if thread_rng().next_u32() % 2 == 0 { + ( + first, + first_send, + first_receive, + second, + second_send, + second_receive, + ) } else { - second + ( + second, + second_send, + second_receive, + first, + first_send, + first_receive, + ) }; - closer - .lock() - .unwrap() - .force_close_channel(&channel_id) - .expect("to be able to unilaterally close the channel."); - } - TestPath::BufferCheat => { - cheat_punish(first, second, channel_id, &generate_blocks, true); - } - TestPath::RenewOfferTimeout - | TestPath::RenewAcceptTimeout - | TestPath::RenewConfirmTimeout => { - renew_timeout( - first, - first_send, - first_receive, - second, - second_send, - second_receive, - channel_id, - &test_params.contract_input, - path, - &generate_blocks, - ); - } - TestPath::RenewReject => { - renew_reject( - first, - first_send, - first_receive, - second, - second_send, - second_receive, - channel_id, - &test_params.contract_input, - ); - } - TestPath::RenewRace => { - renew_race( - first, - first_send, - first_receive, - second, - second_send, - second_receive, - channel_id, - &test_params.contract_input, - ); - } - TestPath::RenewedClose - | TestPath::SettleCheat - | TestPath::RenewEstablishedClose => { - first.lock().unwrap().get_store().save(); - - let check_prev_contract_close = - if let TestPath::RenewEstablishedClose = path { - true - } else { - false - }; + first.lock().unwrap().get_store().save(); - renew_channel( + if let TestPath::RenewEstablishedClose = path { + } else { + settle_channel( first.clone(), first_send, first_receive, @@ -749,625 +675,712 @@ fn channel_execution_test(test_params: TestParams, path: TestPath) { second_send, second_receive, channel_id, - &test_params.contract_input, - check_prev_contract_close, ); + } - if let TestPath::RenewedClose = path { - close_established_channel( + match path { + TestPath::SettleClose => { + let closer = if thread_rng().next_u32() % 2 == 0 { + first + } else { + second + }; + + closer + .lock() + .unwrap() + .force_close_channel(&channel_id) + .expect("to be able to unilaterally close the channel."); + } + TestPath::BufferCheat => { + cheat_punish(first, second, channel_id, &generate_blocks, true); + } + TestPath::RenewOfferTimeout + | TestPath::RenewAcceptTimeout + | TestPath::RenewConfirmTimeout => { + renew_timeout( first, + first_send, + first_receive, second, + second_send, + second_receive, channel_id, + &test_params.contract_input, + path, &generate_blocks, ); - } else if let TestPath::SettleCheat = path { - cheat_punish(first, second, channel_id, &generate_blocks, false); } - } - TestPath::SettleRenewSettle => { - renew_channel( - first.clone(), - first_send, - first_receive, - second.clone(), - second_send, - second_receive, - channel_id, - &test_params.contract_input, - false, - ); + TestPath::RenewReject => { + renew_reject( + first, + first_send, + first_receive, + second, + second_send, + second_receive, + channel_id, + &test_params.contract_input, + ); + } + TestPath::RenewRace => { + renew_race( + first, + first_send, + first_receive, + second, + second_send, + second_receive, + channel_id, + &test_params.contract_input, + ); + } + TestPath::RenewedClose + | TestPath::SettleCheat + | TestPath::RenewEstablishedClose => { + first.lock().unwrap().get_store().save(); + + let check_prev_contract_close = + if let TestPath::RenewEstablishedClose = path { + true + } else { + false + }; + + renew_channel( + first.clone(), + first_send, + first_receive, + second.clone(), + second_send, + second_receive, + channel_id, + &test_params.contract_input, + check_prev_contract_close, + ); - settle_channel( - first, - first_send, - first_receive, - second, - second_send, - second_receive, - channel_id, - ); + if let TestPath::RenewedClose = path { + close_established_channel( + first, + second, + channel_id, + &generate_blocks, + ); + } else if let TestPath::SettleCheat = path { + cheat_punish( + first, + second, + channel_id, + &generate_blocks, + false, + ); + } + } + TestPath::SettleRenewSettle => { + renew_channel( + first.clone(), + first_send, + first_receive, + second.clone(), + second_send, + second_receive, + channel_id, + &test_params.contract_input, + false, + ); + + settle_channel( + first, + first_send, + first_receive, + second, + second_send, + second_receive, + channel_id, + ); + } + _ => (), } - _ => (), } } } } + + alice_send.send(None).unwrap(); + bob_send.send(None).unwrap(); + + alice_handle.join().unwrap(); + bob_handle.join().unwrap(); } - alice_send.send(None).unwrap(); - bob_send.send(None).unwrap(); + fn close_established_channel( + first: DlcParty, + second: DlcParty, + channel_id: ChannelId, + generate_blocks: &F, + ) where + F: Fn(u64), + { + first + .lock() + .unwrap() + .force_close_channel(&channel_id) + .expect("to be able to unilaterally close."); + assert_channel_state!(first, channel_id, Signed, Closing); + + let contract_id = get_established_channel_contract_id(&first, &channel_id); - alice_handle.join().unwrap(); - bob_handle.join().unwrap(); -} + periodic_check(first.clone()); -fn close_established_channel( - first: DlcParty, - second: DlcParty, - channel_id: ChannelId, - generate_blocks: &F, -) where - F: Fn(u64), -{ - first - .lock() - .unwrap() - .force_close_channel(&channel_id) - .expect("to be able to unilaterally close."); - assert_channel_state!(first, channel_id, Signed, Closing); + let wait = dlc_manager::manager::CET_NSEQUENCE; - let contract_id = get_established_channel_contract_id(&first, &channel_id); + generate_blocks(10); - periodic_check(first.clone()); + periodic_check(second.clone()); - let wait = dlc_manager::manager::CET_NSEQUENCE; + assert_channel_state!(second, channel_id, Signed, Closing); - generate_blocks(10); + periodic_check(first.clone()); - periodic_check(second.clone()); + // Should not have changed state before the CET is spendable. + assert_channel_state!(first, channel_id, Signed, Closing); - assert_channel_state!(second, channel_id, Signed, Closing); + generate_blocks(wait as u64 - 9); - periodic_check(first.clone()); + periodic_check(first.clone()); - // Should not have changed state before the CET is spendable. - assert_channel_state!(first, channel_id, Signed, Closing); + assert_channel_state!(first, channel_id, Closed); - generate_blocks(wait as u64 - 9); + assert_contract_state!(first, contract_id, PreClosed); - periodic_check(first.clone()); + generate_blocks(1); - assert_channel_state!(first, channel_id, Closed); + periodic_check(second.clone()); - assert_contract_state!(first, contract_id, PreClosed); + assert_channel_state!(second, channel_id, CounterClosed); + assert_contract_state!(second, contract_id, PreClosed); - generate_blocks(1); + generate_blocks(5); - periodic_check(second.clone()); + periodic_check(first.clone()); + periodic_check(second.clone()); - assert_channel_state!(second, channel_id, CounterClosed); - assert_contract_state!(second, contract_id, PreClosed); + assert_contract_state!(first, contract_id, Closed); + assert_contract_state!(second, contract_id, Closed); + } - generate_blocks(5); + fn cheat_punish( + first: DlcParty, + second: DlcParty, + channel_id: ChannelId, + generate_blocks: &F, + established: bool, + ) { + first.lock().unwrap().get_store().rollback(); + + if established { + first + .lock() + .unwrap() + .force_close_channel(&channel_id) + .expect("the cheater to be able to close on established"); + } else { + first + .lock() + .unwrap() + .force_close_channel(&channel_id) + .expect("the cheater to be able to close on settled"); + } - periodic_check(first.clone()); - periodic_check(second.clone()); + generate_blocks(2); - assert_contract_state!(first, contract_id, Closed); - assert_contract_state!(second, contract_id, Closed); -} + periodic_check(second.clone()); -fn cheat_punish( - first: DlcParty, - second: DlcParty, - channel_id: ChannelId, - generate_blocks: &F, - established: bool, -) { - first.lock().unwrap().get_store().rollback(); + assert_channel_state!(second, channel_id, ClosedPunished); + } - if established { - first + fn settle_channel( + first: DlcParty, + first_send: &Sender>, + first_receive: &Receiver<()>, + second: DlcParty, + second_send: &Sender>, + second_receive: &Receiver<()>, + channel_id: ChannelId, + ) { + let (settle_offer, _) = first .lock() .unwrap() - .force_close_channel(&channel_id) - .expect("the cheater to be able to close on established"); - } else { - first + .settle_offer(&channel_id, test_utils::ACCEPT_COLLATERAL) + .expect("to be able to offer a settlement of the contract."); + + first_send + .send(Some(Message::SettleOffer(settle_offer))) + .unwrap(); + + second_receive.recv().expect("Error synchronizing"); + + assert_channel_state!(first, channel_id, Signed, SettledOffered); + + assert_channel_state!(second, channel_id, Signed, SettledReceived); + + let (settle_accept, _) = second .lock() .unwrap() - .force_close_channel(&channel_id) - .expect("the cheater to be able to close on settled"); - } + .accept_settle_offer(&channel_id) + .expect("to be able to accept a settlement offer"); + + second_send + .send(Some(Message::SettleAccept(settle_accept))) + .unwrap(); + + // Process Accept + first_receive.recv().expect("Error synchronizing"); + // Process Confirm + second_receive.recv().expect("Error synchronizing"); + // Process Finalize + first_receive.recv().expect("Error synchronizing"); - generate_blocks(2); + assert_channel_state!(first, channel_id, Signed, Settled); - periodic_check(second.clone()); + assert_channel_state!(second, channel_id, Signed, Settled); + } - assert_channel_state!(second, channel_id, ClosedPunished); -} + fn settle_reject( + first: DlcParty, + first_send: &Sender>, + first_receive: &Receiver<()>, + second: DlcParty, + second_send: &Sender>, + second_receive: &Receiver<()>, + channel_id: ChannelId, + ) { + let (settle_offer, _) = first + .lock() + .unwrap() + .settle_offer(&channel_id, test_utils::ACCEPT_COLLATERAL) + .expect("to be able to reject a settlement of the contract."); -fn settle_channel( - first: DlcParty, - first_send: &Sender>, - first_receive: &Receiver<()>, - second: DlcParty, - second_send: &Sender>, - second_receive: &Receiver<()>, - channel_id: ChannelId, -) { - let (settle_offer, _) = first - .lock() - .unwrap() - .settle_offer(&channel_id, test_utils::ACCEPT_COLLATERAL) - .expect("to be able to offer a settlement of the contract."); - - first_send - .send(Some(Message::SettleOffer(settle_offer))) - .unwrap(); - - second_receive.recv().expect("Error synchronizing"); - - assert_channel_state!(first, channel_id, Signed, SettledOffered); - - assert_channel_state!(second, channel_id, Signed, SettledReceived); - - let (settle_accept, _) = second - .lock() - .unwrap() - .accept_settle_offer(&channel_id) - .expect("to be able to accept a settlement offer"); - - second_send - .send(Some(Message::SettleAccept(settle_accept))) - .unwrap(); - - // Process Accept - first_receive.recv().expect("Error synchronizing"); - // Process Confirm - second_receive.recv().expect("Error synchronizing"); - // Process Finalize - first_receive.recv().expect("Error synchronizing"); - - assert_channel_state!(first, channel_id, Signed, Settled); - - assert_channel_state!(second, channel_id, Signed, Settled); -} + first_send + .send(Some(Message::SettleOffer(settle_offer))) + .unwrap(); -fn settle_reject( - first: DlcParty, - first_send: &Sender>, - first_receive: &Receiver<()>, - second: DlcParty, - second_send: &Sender>, - second_receive: &Receiver<()>, - channel_id: ChannelId, -) { - let (settle_offer, _) = first - .lock() - .unwrap() - .settle_offer(&channel_id, test_utils::ACCEPT_COLLATERAL) - .expect("to be able to reject a settlement of the contract."); + second_receive.recv().expect("Error synchronizing"); - first_send - .send(Some(Message::SettleOffer(settle_offer))) - .unwrap(); + assert_channel_state!(first, channel_id, Signed, SettledOffered); - second_receive.recv().expect("Error synchronizing"); + assert_channel_state!(second, channel_id, Signed, SettledReceived); - assert_channel_state!(first, channel_id, Signed, SettledOffered); + let (settle_reject, _) = second + .lock() + .unwrap() + .reject_settle_offer(&channel_id) + .expect("to be able to reject a settlement offer"); - assert_channel_state!(second, channel_id, Signed, SettledReceived); + second_send + .send(Some(Message::Reject(settle_reject))) + .unwrap(); - let (settle_reject, _) = second - .lock() - .unwrap() - .reject_settle_offer(&channel_id) - .expect("to be able to reject a settlement offer"); + first_receive.recv().expect("Error synchronizing"); - second_send - .send(Some(Message::Reject(settle_reject))) - .unwrap(); + assert_channel_state!(first, channel_id, Signed, Established); - first_receive.recv().expect("Error synchronizing"); + assert_channel_state!(second, channel_id, Signed, Established); + } - assert_channel_state!(first, channel_id, Signed, Established); + fn settle_race( + first: DlcParty, + first_send: &Sender>, + first_receive: &Receiver<()>, + second: DlcParty, + second_send: &Sender>, + second_receive: &Receiver<()>, + channel_id: ChannelId, + ) { + let (settle_offer, _) = first + .lock() + .unwrap() + .settle_offer(&channel_id, test_utils::ACCEPT_COLLATERAL) + .expect("to be able to offer a settlement of the contract."); - assert_channel_state!(second, channel_id, Signed, Established); -} + let (settle_offer_2, _) = second + .lock() + .unwrap() + .settle_offer(&channel_id, test_utils::ACCEPT_COLLATERAL) + .expect("to be able to offer a settlement of the contract."); -fn settle_race( - first: DlcParty, - first_send: &Sender>, - first_receive: &Receiver<()>, - second: DlcParty, - second_send: &Sender>, - second_receive: &Receiver<()>, - channel_id: ChannelId, -) { - let (settle_offer, _) = first - .lock() - .unwrap() - .settle_offer(&channel_id, test_utils::ACCEPT_COLLATERAL) - .expect("to be able to offer a settlement of the contract."); - - let (settle_offer_2, _) = second - .lock() - .unwrap() - .settle_offer(&channel_id, test_utils::ACCEPT_COLLATERAL) - .expect("to be able to offer a settlement of the contract."); - - first_send - .send(Some(Message::SettleOffer(settle_offer))) - .unwrap(); - - second_send - .send(Some(Message::SettleOffer(settle_offer_2))) - .unwrap(); - - // Process 2 offers + 2 rejects - first_receive - .recv_timeout(Duration::from_secs(2)) - .expect("Error synchronizing 1"); - second_receive - .recv_timeout(Duration::from_secs(2)) - .expect("Error synchronizing 2"); - first_receive - .recv_timeout(Duration::from_secs(2)) - .expect("Error synchronizing 3"); - second_receive - .recv_timeout(Duration::from_secs(2)) - .expect("Error synchronizing 4"); - - assert_channel_state!(first, channel_id, Signed, Established); - - assert_channel_state!(second, channel_id, Signed, Established); -} + first_send + .send(Some(Message::SettleOffer(settle_offer))) + .unwrap(); -fn renew_channel( - first: DlcParty, - first_send: &Sender>, - first_receive: &Receiver<()>, - second: DlcParty, - second_send: &Sender>, - second_receive: &Receiver<()>, - channel_id: ChannelId, - contract_input: &ContractInput, - check_prev_contract_close: bool, -) { - let prev_contract_id = if check_prev_contract_close { - Some(get_established_channel_contract_id(&first, &channel_id)) - } else { - None - }; + second_send + .send(Some(Message::SettleOffer(settle_offer_2))) + .unwrap(); - let (renew_offer, _) = first - .lock() - .unwrap() - .renew_offer(&channel_id, test_utils::ACCEPT_COLLATERAL, contract_input) - .expect("to be able to renew channel contract"); - - first_send - .send(Some(Message::RenewOffer(renew_offer))) - .expect("to be able to send the renew offer"); - - // Process Renew Offer - second_receive.recv().expect("Error synchronizing"); - - assert_channel_state!(first, channel_id, Signed, RenewOffered); - assert_channel_state!(second, channel_id, Signed, RenewOffered); - - let (accept_renew, _) = second - .lock() - .unwrap() - .accept_renew_offer(&channel_id) - .expect("to be able to accept the renewal"); - - second_send - .send(Some(Message::RenewAccept(accept_renew))) - .expect("to be able to send the accept renew"); - - // Process Renew Accept - first_receive.recv().expect("Error synchronizing"); - assert_channel_state!(first, channel_id, Signed, RenewConfirmed); - // Process Renew Confirm - second_receive.recv().expect("Error synchronizing"); - // Process Renew Finalize - first_receive.recv().expect("Error synchronizing"); - // Process Renew Revoke - second_receive.recv().expect("Error synchronizing"); - - if let Some(prev_contract_id) = prev_contract_id { - assert_contract_state!(first, prev_contract_id, Closed); - assert_contract_state!(second, prev_contract_id, Closed); + // Process 2 offers + 2 rejects + first_receive + .recv_timeout(Duration::from_secs(2)) + .expect("Error synchronizing 1"); + second_receive + .recv_timeout(Duration::from_secs(2)) + .expect("Error synchronizing 2"); + first_receive + .recv_timeout(Duration::from_secs(2)) + .expect("Error synchronizing 3"); + second_receive + .recv_timeout(Duration::from_secs(2)) + .expect("Error synchronizing 4"); + + assert_channel_state!(first, channel_id, Signed, Established); + + assert_channel_state!(second, channel_id, Signed, Established); } - let new_contract_id = get_established_channel_contract_id(&first, &channel_id); + fn renew_channel( + first: DlcParty, + first_send: &Sender>, + first_receive: &Receiver<()>, + second: DlcParty, + second_send: &Sender>, + second_receive: &Receiver<()>, + channel_id: ChannelId, + contract_input: &ContractInput, + check_prev_contract_close: bool, + ) { + let prev_contract_id = if check_prev_contract_close { + Some(get_established_channel_contract_id(&first, &channel_id)) + } else { + None + }; - assert_channel_state!(first, channel_id, Signed, Established); - assert_contract_state!(first, new_contract_id, Confirmed); - assert_channel_state!(second, channel_id, Signed, Established); - assert_contract_state!(second, new_contract_id, Confirmed); -} + let (renew_offer, _) = first + .lock() + .unwrap() + .renew_offer(&channel_id, test_utils::ACCEPT_COLLATERAL, contract_input) + .expect("to be able to renew channel contract"); -fn renew_reject( - first: DlcParty, - first_send: &Sender>, - first_receive: &Receiver<()>, - second: DlcParty, - second_send: &Sender>, - second_receive: &Receiver<()>, - channel_id: ChannelId, - contract_input: &ContractInput, -) { - let (renew_offer, _) = first - .lock() - .unwrap() - .renew_offer(&channel_id, test_utils::ACCEPT_COLLATERAL, contract_input) - .expect("to be able to renew channel contract"); - - first_send - .send(Some(Message::RenewOffer(renew_offer))) - .expect("to be able to send the renew offer"); - - // Process Renew Offer - second_receive.recv().expect("Error synchronizing"); - - assert_channel_state!(first, channel_id, Signed, RenewOffered); - assert_channel_state!(second, channel_id, Signed, RenewOffered); - - let (renew_reject, _) = second - .lock() - .unwrap() - .reject_renew_offer(&channel_id) - .expect("to be able to reject the renewal"); - - second_send - .send(Some(Message::Reject(renew_reject))) - .expect("to be able to send the renew reject"); - - // Process Renew Reject - first_receive.recv().expect("Error synchronizing"); - assert_channel_state!(first, channel_id, Signed, Settled); - assert_channel_state!(second, channel_id, Signed, Settled); -} + first_send + .send(Some(Message::RenewOffer(renew_offer))) + .expect("to be able to send the renew offer"); -fn renew_race( - first: DlcParty, - first_send: &Sender>, - first_receive: &Receiver<()>, - second: DlcParty, - second_send: &Sender>, - second_receive: &Receiver<()>, - channel_id: ChannelId, - contract_input: &ContractInput, -) { - let (renew_offer, _) = first - .lock() - .unwrap() - .renew_offer(&channel_id, test_utils::OFFER_COLLATERAL, contract_input) - .expect("to be able to renew channel contract"); - - let mut contract_input_2 = contract_input.clone(); - contract_input_2.accept_collateral = contract_input.offer_collateral; - contract_input_2.offer_collateral = contract_input.accept_collateral; - - let (renew_offer_2, _) = second - .lock() - .unwrap() - .renew_offer(&channel_id, test_utils::OFFER_COLLATERAL, &contract_input_2) - .expect("to be able to renew channel contract"); - - first_send - .send(Some(Message::RenewOffer(renew_offer))) - .expect("to be able to send the renew offer"); - - second_send - .send(Some(Message::RenewOffer(renew_offer_2))) - .expect("to be able to send the renew offer"); - - // Process 2 offers + 2 rejects - first_receive - .recv_timeout(Duration::from_secs(2)) - .expect("Error synchronizing 1"); - second_receive - .recv_timeout(Duration::from_secs(2)) - .expect("Error synchronizing 2"); - first_receive - .recv_timeout(Duration::from_secs(2)) - .expect("Error synchronizing 3"); - second_receive - .recv_timeout(Duration::from_secs(2)) - .expect("Error synchronizing 4"); - - assert_channel_state!(first, channel_id, Signed, Settled); - assert_channel_state!(second, channel_id, Signed, Settled); -} + // Process Renew Offer + second_receive.recv().expect("Error synchronizing"); -fn collaborative_close( - first: DlcParty, - first_send: &Sender>, - second: DlcParty, - channel_id: ChannelId, - sync_receive: &Receiver<()>, - generate_blocks: &F, -) { - let contract_id = get_established_channel_contract_id(&first, &channel_id); - let close_offer = first - .lock() - .unwrap() - .offer_collaborative_close(&channel_id, 100000000) - .expect("to be able to propose a collaborative close"); - first_send - .send(Some(Message::CollaborativeCloseOffer(close_offer))) - .expect("to be able to send collaborative close"); - sync_receive.recv().expect("Error synchronizing"); - - assert_channel_state!(first, channel_id, Signed, CollaborativeCloseOffered); - assert_channel_state!(second, channel_id, Signed, CollaborativeCloseOffered); - - second - .lock() - .unwrap() - .accept_collaborative_close(&channel_id) - .expect("to be able to accept a collaborative close"); - - assert_channel_state!(second, channel_id, CollaborativelyClosed); - assert_contract_state!(second, contract_id, Closed); - - generate_blocks(2); - - periodic_check(first.clone()); - - assert_channel_state!(first, channel_id, CollaborativelyClosed); - assert_contract_state!(first, contract_id, Closed); -} + assert_channel_state!(first, channel_id, Signed, RenewOffered); + assert_channel_state!(second, channel_id, Signed, RenewOffered); -fn renew_timeout( - first: DlcParty, - first_send: &Sender>, - first_receive: &Receiver<()>, - second: DlcParty, - second_send: &Sender>, - second_receive: &Receiver<()>, - channel_id: ChannelId, - contract_input: &ContractInput, - path: TestPath, - generate_blocks: &F, -) { - { + let (accept_renew, _) = second + .lock() + .unwrap() + .accept_renew_offer(&channel_id) + .expect("to be able to accept the renewal"); + + second_send + .send(Some(Message::RenewAccept(accept_renew))) + .expect("to be able to send the accept renew"); + + // Process Renew Accept + first_receive.recv().expect("Error synchronizing"); + assert_channel_state!(first, channel_id, Signed, RenewConfirmed); + // Process Renew Confirm + second_receive.recv().expect("Error synchronizing"); + // Process Renew Finalize + first_receive.recv().expect("Error synchronizing"); + // Process Renew Revoke + second_receive.recv().expect("Error synchronizing"); + + if let Some(prev_contract_id) = prev_contract_id { + assert_contract_state!(first, prev_contract_id, Closed); + assert_contract_state!(second, prev_contract_id, Closed); + } + + let new_contract_id = get_established_channel_contract_id(&first, &channel_id); + + assert_channel_state!(first, channel_id, Signed, Established); + assert_contract_state!(first, new_contract_id, Confirmed); + assert_channel_state!(second, channel_id, Signed, Established); + assert_contract_state!(second, new_contract_id, Confirmed); + } + + fn renew_reject( + first: DlcParty, + first_send: &Sender>, + first_receive: &Receiver<()>, + second: DlcParty, + second_send: &Sender>, + second_receive: &Receiver<()>, + channel_id: ChannelId, + contract_input: &ContractInput, + ) { let (renew_offer, _) = first .lock() .unwrap() .renew_offer(&channel_id, test_utils::ACCEPT_COLLATERAL, contract_input) - .expect("to be able to offer a settlement of the contract."); + .expect("to be able to renew channel contract"); first_send .send(Some(Message::RenewOffer(renew_offer))) - .unwrap(); + .expect("to be able to send the renew offer"); + // Process Renew Offer second_receive.recv().expect("Error synchronizing"); - if let TestPath::RenewOfferTimeout = path { - mocks::mock_time::set_time( - (EVENT_MATURITY as u64) + dlc_manager::manager::PEER_TIMEOUT + 2, - ); - periodic_check(first.clone()); + assert_channel_state!(first, channel_id, Signed, RenewOffered); + assert_channel_state!(second, channel_id, Signed, RenewOffered); - assert_channel_state!(first, channel_id, Closed); - } else { - let (renew_accept, _) = second + let (renew_reject, _) = second + .lock() + .unwrap() + .reject_renew_offer(&channel_id) + .expect("to be able to reject the renewal"); + + second_send + .send(Some(Message::Reject(renew_reject))) + .expect("to be able to send the renew reject"); + + // Process Renew Reject + first_receive.recv().expect("Error synchronizing"); + assert_channel_state!(first, channel_id, Signed, Settled); + assert_channel_state!(second, channel_id, Signed, Settled); + } + + fn renew_race( + first: DlcParty, + first_send: &Sender>, + first_receive: &Receiver<()>, + second: DlcParty, + second_send: &Sender>, + second_receive: &Receiver<()>, + channel_id: ChannelId, + contract_input: &ContractInput, + ) { + let (renew_offer, _) = first + .lock() + .unwrap() + .renew_offer(&channel_id, test_utils::OFFER_COLLATERAL, contract_input) + .expect("to be able to renew channel contract"); + + let mut contract_input_2 = contract_input.clone(); + contract_input_2.accept_collateral = contract_input.offer_collateral; + contract_input_2.offer_collateral = contract_input.accept_collateral; + + let (renew_offer_2, _) = second + .lock() + .unwrap() + .renew_offer(&channel_id, test_utils::OFFER_COLLATERAL, &contract_input_2) + .expect("to be able to renew channel contract"); + + first_send + .send(Some(Message::RenewOffer(renew_offer))) + .expect("to be able to send the renew offer"); + + second_send + .send(Some(Message::RenewOffer(renew_offer_2))) + .expect("to be able to send the renew offer"); + + // Process 2 offers + 2 rejects + first_receive + .recv_timeout(Duration::from_secs(2)) + .expect("Error synchronizing 1"); + second_receive + .recv_timeout(Duration::from_secs(2)) + .expect("Error synchronizing 2"); + first_receive + .recv_timeout(Duration::from_secs(2)) + .expect("Error synchronizing 3"); + second_receive + .recv_timeout(Duration::from_secs(2)) + .expect("Error synchronizing 4"); + + assert_channel_state!(first, channel_id, Signed, Settled); + assert_channel_state!(second, channel_id, Signed, Settled); + } + + fn collaborative_close( + first: DlcParty, + first_send: &Sender>, + second: DlcParty, + channel_id: ChannelId, + sync_receive: &Receiver<()>, + generate_blocks: &F, + ) { + let contract_id = get_established_channel_contract_id(&first, &channel_id); + let close_offer = first + .lock() + .unwrap() + .offer_collaborative_close(&channel_id, 100000000) + .expect("to be able to propose a collaborative close"); + first_send + .send(Some(Message::CollaborativeCloseOffer(close_offer))) + .expect("to be able to send collaborative close"); + sync_receive.recv().expect("Error synchronizing"); + + assert_channel_state!(first, channel_id, Signed, CollaborativeCloseOffered); + assert_channel_state!(second, channel_id, Signed, CollaborativeCloseOffered); + + second + .lock() + .unwrap() + .accept_collaborative_close(&channel_id) + .expect("to be able to accept a collaborative close"); + + assert_channel_state!(second, channel_id, CollaborativelyClosed); + assert_contract_state!(second, contract_id, Closed); + + generate_blocks(2); + + periodic_check(first.clone()); + + assert_channel_state!(first, channel_id, CollaborativelyClosed); + assert_contract_state!(first, contract_id, Closed); + } + + fn renew_timeout( + first: DlcParty, + first_send: &Sender>, + first_receive: &Receiver<()>, + second: DlcParty, + second_send: &Sender>, + second_receive: &Receiver<()>, + channel_id: ChannelId, + contract_input: &ContractInput, + path: TestPath, + generate_blocks: &F, + ) { + { + let (renew_offer, _) = first .lock() .unwrap() - .accept_renew_offer(&channel_id) - .expect("to be able to accept a settlement offer"); + .renew_offer(&channel_id, test_utils::ACCEPT_COLLATERAL, contract_input) + .expect("to be able to offer a settlement of the contract."); - second_send - .send(Some(Message::RenewAccept(renew_accept))) + first_send + .send(Some(Message::RenewOffer(renew_offer))) .unwrap(); - // Process Accept - first_receive.recv().expect("Error synchronizing"); - - if let TestPath::RenewAcceptTimeout = path { - mocks::mock_time::set_time( - (EVENT_MATURITY as u64) + dlc_manager::manager::PEER_TIMEOUT + 2, - ); - periodic_check(second.clone()); + second_receive.recv().expect("Error synchronizing"); - assert_channel_state!(second, channel_id, Closed); - } else if let TestPath::RenewConfirmTimeout = path { - // Process Confirm - second_receive.recv().expect("Error synchronizing"); + if let TestPath::RenewOfferTimeout = path { mocks::mock_time::set_time( (EVENT_MATURITY as u64) + dlc_manager::manager::PEER_TIMEOUT + 2, ); periodic_check(first.clone()); assert_channel_state!(first, channel_id, Closed); - } else if let TestPath::RenewFinalizeTimeout = path { - //Process confirm - second_receive.recv().expect("Error synchronizing"); - // Process Finalize + } else { + let (renew_accept, _) = second + .lock() + .unwrap() + .accept_renew_offer(&channel_id) + .expect("to be able to accept a settlement offer"); + + second_send + .send(Some(Message::RenewAccept(renew_accept))) + .unwrap(); + + // Process Accept first_receive.recv().expect("Error synchronizing"); - mocks::mock_time::set_time( - (EVENT_MATURITY as u64) + dlc_manager::manager::PEER_TIMEOUT + 2, - ); - periodic_check(second.clone()); - generate_blocks(289); - periodic_check(second.clone()); - assert_channel_state!(second, channel_id, Closed); + if let TestPath::RenewAcceptTimeout = path { + mocks::mock_time::set_time( + (EVENT_MATURITY as u64) + dlc_manager::manager::PEER_TIMEOUT + 2, + ); + periodic_check(second.clone()); + + assert_channel_state!(second, channel_id, Closed); + } else if let TestPath::RenewConfirmTimeout = path { + // Process Confirm + second_receive.recv().expect("Error synchronizing"); + mocks::mock_time::set_time( + (EVENT_MATURITY as u64) + dlc_manager::manager::PEER_TIMEOUT + 2, + ); + periodic_check(first.clone()); + + assert_channel_state!(first, channel_id, Closed); + } else if let TestPath::RenewFinalizeTimeout = path { + //Process confirm + second_receive.recv().expect("Error synchronizing"); + // Process Finalize + first_receive.recv().expect("Error synchronizing"); + mocks::mock_time::set_time( + (EVENT_MATURITY as u64) + dlc_manager::manager::PEER_TIMEOUT + 2, + ); + periodic_check(second.clone()); + generate_blocks(289); + periodic_check(second.clone()); + + assert_channel_state!(second, channel_id, Closed); + } } } } -} -fn settle_timeout( - first: DlcParty, - first_send: &Sender>, - first_receive: &Receiver<()>, - second: DlcParty, - second_send: &Sender>, - second_receive: &Receiver<()>, - channel_id: ChannelId, - path: TestPath, -) { - let (settle_offer, _) = first - .lock() - .unwrap() - .settle_offer(&channel_id, test_utils::ACCEPT_COLLATERAL) - .expect("to be able to offer a settlement of the contract."); - - first_send - .send(Some(Message::SettleOffer(settle_offer))) - .unwrap(); - - second_receive.recv().expect("Error synchronizing"); - - if let TestPath::SettleOfferTimeout = path { - mocks::mock_time::set_time( - (EVENT_MATURITY as u64) + dlc_manager::manager::PEER_TIMEOUT + 2, - ); - periodic_check(first.clone()); - - assert_channel_state!(first, channel_id, Signed, Closing); - } else { - let (settle_accept, _) = second + fn settle_timeout( + first: DlcParty, + first_send: &Sender>, + first_receive: &Receiver<()>, + second: DlcParty, + second_send: &Sender>, + second_receive: &Receiver<()>, + channel_id: ChannelId, + path: TestPath, + ) { + let (settle_offer, _) = first .lock() .unwrap() - .accept_settle_offer(&channel_id) - .expect("to be able to accept a settlement offer"); + .settle_offer(&channel_id, test_utils::ACCEPT_COLLATERAL) + .expect("to be able to offer a settlement of the contract."); - second_send - .send(Some(Message::SettleAccept(settle_accept))) + first_send + .send(Some(Message::SettleOffer(settle_offer))) .unwrap(); - // Process Accept - first_receive.recv().expect("Error synchronizing"); + second_receive.recv().expect("Error synchronizing"); - if let TestPath::SettleAcceptTimeout = path { + if let TestPath::SettleOfferTimeout = path { mocks::mock_time::set_time( (EVENT_MATURITY as u64) + dlc_manager::manager::PEER_TIMEOUT + 2, ); - periodic_check(second.clone()); + periodic_check(first.clone()); - second + assert_channel_state!(first, channel_id, Signed, Closing); + } else { + let (settle_accept, _) = second .lock() .unwrap() - .get_store() - .get_channel(&channel_id) + .accept_settle_offer(&channel_id) + .expect("to be able to accept a settlement offer"); + + second_send + .send(Some(Message::SettleAccept(settle_accept))) .unwrap(); - assert_channel_state!(second, channel_id, Signed, Closing); - } else if let TestPath::SettleConfirmTimeout = path { - // Process Confirm - second_receive.recv().expect("Error synchronizing"); - mocks::mock_time::set_time( - (EVENT_MATURITY as u64) + dlc_manager::manager::PEER_TIMEOUT + 2, - ); - periodic_check(first.clone()); - assert_channel_state!(first, channel_id, Signed, Closing); + // Process Accept + first_receive.recv().expect("Error synchronizing"); + + if let TestPath::SettleAcceptTimeout = path { + mocks::mock_time::set_time( + (EVENT_MATURITY as u64) + dlc_manager::manager::PEER_TIMEOUT + 2, + ); + periodic_check(second.clone()); + + second + .lock() + .unwrap() + .get_store() + .get_channel(&channel_id) + .unwrap(); + assert_channel_state!(second, channel_id, Signed, Closing); + } else if let TestPath::SettleConfirmTimeout = path { + // Process Confirm + second_receive.recv().expect("Error synchronizing"); + mocks::mock_time::set_time( + (EVENT_MATURITY as u64) + dlc_manager::manager::PEER_TIMEOUT + 2, + ); + periodic_check(first.clone()); + + assert_channel_state!(first, channel_id, Signed, Closing); + } } } } diff --git a/dlc-manager/tests/manager_execution_tests.rs b/dlc-manager/tests/manager_execution_tests.rs index cc2743e1..d8e29d69 100644 --- a/dlc-manager/tests/manager_execution_tests.rs +++ b/dlc-manager/tests/manager_execution_tests.rs @@ -8,902 +8,909 @@ extern crate dlc_manager; #[allow(dead_code)] mod test_utils; -use bitcoin::Amount; -use dlc_manager::payout_curve::PayoutFunctionPiece; -use electrs_blockchain_provider::ElectrsBlockchainProvider; -use simple_wallet::SimpleWallet; -use test_utils::*; - -use bitcoin_test_utils::rpc_helpers::init_clients; -use bitcoincore_rpc::RpcApi; -use dlc_manager::contract::{numerical_descriptor::DifferenceParams, Contract}; -use dlc_manager::manager::Manager; -use dlc_manager::{Blockchain, Oracle, Storage, Wallet}; -use dlc_messages::oracle_msgs::OracleAttestation; -use dlc_messages::{AcceptDlc, OfferDlc, SignDlc}; -use dlc_messages::{CetAdaptorSignatures, Message}; -use lightning::ln::wire::Type; -use lightning::util::ser::Writeable; -use secp256k1_zkp::rand::{thread_rng, RngCore}; -use secp256k1_zkp::{ecdsa::Signature, EcdsaAdaptorSignature}; -use serde_json::{from_str, to_writer_pretty}; -use std::collections::HashMap; -use std::sync::{ - atomic::{AtomicBool, Ordering}, - mpsc::channel, - Arc, Mutex, -}; -use std::thread; - -#[derive(serde::Serialize, serde::Deserialize)] -struct TestVectorPart { - message: T, - #[cfg_attr( - feature = "use-serde", - serde( - serialize_with = "dlc_messages::serde_utils::serialize_hex", - deserialize_with = "dlc_messages::serde_utils::deserialize_hex_string" - ) - )] - serialized: Vec, -} - -#[derive(serde::Serialize, serde::Deserialize)] -struct TestVector { - offer_message: TestVectorPart, - accept_message: TestVectorPart, - sign_message: TestVectorPart, -} +#[cfg(not(feature = "async"))] +mod sync_tests { + + use crate::test_utils::*; + use bitcoin::Amount; + use dlc_manager::payout_curve::PayoutFunctionPiece; + use electrs_blockchain_provider::ElectrsBlockchainProvider; + use simple_wallet::SimpleWallet; + + use bitcoin_test_utils::rpc_helpers::init_clients; + use bitcoincore_rpc::RpcApi; + use dlc_manager::contract::{numerical_descriptor::DifferenceParams, Contract}; + use dlc_manager::manager::Manager; + use dlc_manager::{Blockchain, Oracle, Storage, Wallet}; + use dlc_messages::oracle_msgs::OracleAttestation; + use dlc_messages::{AcceptDlc, OfferDlc, SignDlc}; + use dlc_messages::{CetAdaptorSignatures, Message}; + use lightning::ln::wire::Type; + use lightning::util::ser::Writeable; + use secp256k1_zkp::rand::{thread_rng, RngCore}; + use secp256k1_zkp::{ecdsa::Signature, EcdsaAdaptorSignature}; + use serde_json::{from_str, to_writer_pretty}; + use std::collections::HashMap; + use std::sync::{ + atomic::{AtomicBool, Ordering}, + mpsc::channel, + Arc, Mutex, + }; + use std::thread; + + #[derive(serde::Serialize, serde::Deserialize)] + struct TestVectorPart { + message: T, + #[cfg_attr( + feature = "use-serde", + serde( + serialize_with = "dlc_messages::serde_utils::serialize_hex", + deserialize_with = "dlc_messages::serde_utils::deserialize_hex_string" + ) + )] + serialized: Vec, + } -fn write_message(msg_name: &str, s: T) { - if std::env::var("GENERATE_TEST_VECTOR").is_ok() { - let mut buf = Vec::new(); - s.type_id().write(&mut buf).unwrap(); - s.write(&mut buf).unwrap(); - let t = TestVectorPart { - message: s, - serialized: buf, - }; - to_writer_pretty( - &std::fs::File::create(format!("{}.json", msg_name)).unwrap(), - &t, - ) - .unwrap(); + #[derive(serde::Serialize, serde::Deserialize)] + struct TestVector { + offer_message: TestVectorPart, + accept_message: TestVectorPart, + sign_message: TestVectorPart, } -} -fn create_test_vector() { - if std::env::var("GENERATE_TEST_VECTOR").is_ok() { - let test_vector = TestVector { - offer_message: from_str(&std::fs::read_to_string("offer_message.json").unwrap()) - .unwrap(), - accept_message: from_str(&std::fs::read_to_string("accept_message.json").unwrap()) - .unwrap(), - sign_message: from_str(&std::fs::read_to_string("sign_message.json").unwrap()).unwrap(), - }; - let file_name = std::env::var("TEST_VECTOR_OUTPUT_NAME") - .unwrap_or_else(|_| "test_vector.json".to_string()); - to_writer_pretty(std::fs::File::create(file_name).unwrap(), &test_vector).unwrap(); + fn write_message(msg_name: &str, s: T) { + if std::env::var("GENERATE_TEST_VECTOR").is_ok() { + let mut buf = Vec::new(); + s.type_id().write(&mut buf).unwrap(); + s.write(&mut buf).unwrap(); + let t = TestVectorPart { + message: s, + serialized: buf, + }; + to_writer_pretty( + &std::fs::File::create(format!("{}.json", msg_name)).unwrap(), + &t, + ) + .unwrap(); + } } -} -macro_rules! periodic_check { - ($d:expr, $id:expr, $p:ident) => { - $d.lock() - .unwrap() - .periodic_check(true) - .expect("Periodic check error"); + fn create_test_vector() { + if std::env::var("GENERATE_TEST_VECTOR").is_ok() { + let test_vector = TestVector { + offer_message: from_str(&std::fs::read_to_string("offer_message.json").unwrap()) + .unwrap(), + accept_message: from_str(&std::fs::read_to_string("accept_message.json").unwrap()) + .unwrap(), + sign_message: from_str(&std::fs::read_to_string("sign_message.json").unwrap()) + .unwrap(), + }; + let file_name = std::env::var("TEST_VECTOR_OUTPUT_NAME") + .unwrap_or_else(|_| "test_vector.json".to_string()); + to_writer_pretty(std::fs::File::create(file_name).unwrap(), &test_vector).unwrap(); + } + } - assert_contract_state!($d, $id, $p); - }; -} + macro_rules! periodic_check { + ($d:expr, $id:expr, $p:ident) => { + $d.lock() + .unwrap() + .periodic_check(true) + .expect("Periodic check error"); -fn numerical_common( - nb_oracles: usize, - threshold: usize, - payout_function_pieces_cb: F, - difference_params: Option, - manual_close: bool, -) where - F: Fn(usize) -> Vec, -{ - let oracle_numeric_infos = get_same_num_digits_oracle_numeric_infos(nb_oracles); - let with_diff = difference_params.is_some(); - let contract_descriptor = get_numerical_contract_descriptor( - oracle_numeric_infos.clone(), - payout_function_pieces_cb(*oracle_numeric_infos.nb_digits.iter().min().unwrap()), - difference_params, - ); - manager_execution_test( - get_numerical_test_params( - &oracle_numeric_infos, - threshold, - with_diff, - contract_descriptor, - false, - ), - TestPath::Close, - manual_close, - ); -} + assert_contract_state!($d, $id, $p); + }; + } -fn numerical_polynomial_common( - nb_oracles: usize, - threshold: usize, - difference_params: Option, - manual_close: bool, -) { - numerical_common( - nb_oracles, - threshold, - get_polynomial_payout_curve_pieces, - difference_params, - manual_close, - ); -} + fn numerical_common( + nb_oracles: usize, + threshold: usize, + payout_function_pieces_cb: F, + difference_params: Option, + manual_close: bool, + ) where + F: Fn(usize) -> Vec, + { + let oracle_numeric_infos = get_same_num_digits_oracle_numeric_infos(nb_oracles); + let with_diff = difference_params.is_some(); + let contract_descriptor = get_numerical_contract_descriptor( + oracle_numeric_infos.clone(), + payout_function_pieces_cb(*oracle_numeric_infos.nb_digits.iter().min().unwrap()), + difference_params, + ); + manager_execution_test( + get_numerical_test_params( + &oracle_numeric_infos, + threshold, + with_diff, + contract_descriptor, + false, + ), + TestPath::Close, + manual_close, + ); + } -fn numerical_common_diff_nb_digits( - nb_oracles: usize, - threshold: usize, - difference_params: Option, - use_max_value: bool, - manual_close: bool, -) { - let with_diff = difference_params.is_some(); - let oracle_numeric_infos = get_variable_oracle_numeric_infos( - &(0..nb_oracles) - .map(|_| (NB_DIGITS + (thread_rng().next_u32() % 6)) as usize) - .collect::>(), - ); - let contract_descriptor = get_numerical_contract_descriptor( - oracle_numeric_infos.clone(), - get_polynomial_payout_curve_pieces(oracle_numeric_infos.get_min_nb_digits()), - difference_params, - ); - - manager_execution_test( - get_numerical_test_params( - &oracle_numeric_infos, + fn numerical_polynomial_common( + nb_oracles: usize, + threshold: usize, + difference_params: Option, + manual_close: bool, + ) { + numerical_common( + nb_oracles, threshold, - with_diff, - contract_descriptor, - use_max_value, - ), - TestPath::Close, - manual_close, - ); -} + get_polynomial_payout_curve_pieces, + difference_params, + manual_close, + ); + } -#[derive(Eq, PartialEq, Clone)] -enum TestPath { - Close, - Refund, - BadAcceptCetSignature, - BadAcceptRefundSignature, - BadSignCetSignature, - BadSignRefundSignature, -} + fn numerical_common_diff_nb_digits( + nb_oracles: usize, + threshold: usize, + difference_params: Option, + use_max_value: bool, + manual_close: bool, + ) { + let with_diff = difference_params.is_some(); + let oracle_numeric_infos = get_variable_oracle_numeric_infos( + &(0..nb_oracles) + .map(|_| (NB_DIGITS + (thread_rng().next_u32() % 6)) as usize) + .collect::>(), + ); + let contract_descriptor = get_numerical_contract_descriptor( + oracle_numeric_infos.clone(), + get_polynomial_payout_curve_pieces(oracle_numeric_infos.get_min_nb_digits()), + difference_params, + ); + + manager_execution_test( + get_numerical_test_params( + &oracle_numeric_infos, + threshold, + with_diff, + contract_descriptor, + use_max_value, + ), + TestPath::Close, + manual_close, + ); + } -#[test] -#[ignore] -fn single_oracle_numerical_test() { - numerical_polynomial_common(1, 1, None, false); -} + #[derive(Eq, PartialEq, Clone)] + enum TestPath { + Close, + Refund, + BadAcceptCetSignature, + BadAcceptRefundSignature, + BadSignCetSignature, + BadSignRefundSignature, + } -#[test] -#[ignore] -fn single_oracle_numerical_manual_test() { - numerical_polynomial_common(1, 1, None, true); -} + #[test] + #[ignore] + fn single_oracle_numerical_test() { + numerical_polynomial_common(1, 1, None, false); + } -#[test] -#[ignore] -fn single_oracle_numerical_hyperbola_test() { - numerical_common(1, 1, get_hyperbola_payout_curve_pieces, None, false); -} + #[test] + #[ignore] + fn single_oracle_numerical_manual_test() { + numerical_polynomial_common(1, 1, None, true); + } -#[test] -#[ignore] -fn three_of_three_oracle_numerical_test() { - numerical_polynomial_common(3, 3, None, false); -} + #[test] + #[ignore] + fn single_oracle_numerical_hyperbola_test() { + numerical_common(1, 1, get_hyperbola_payout_curve_pieces, None, false); + } -#[test] -#[ignore] -fn two_of_five_oracle_numerical_test() { - numerical_polynomial_common(5, 2, None, false); -} + #[test] + #[ignore] + fn three_of_three_oracle_numerical_test() { + numerical_polynomial_common(3, 3, None, false); + } -#[test] -#[ignore] -fn two_of_five_oracle_numerical_manual_test() { - numerical_polynomial_common(5, 2, None, true); -} + #[test] + #[ignore] + fn two_of_five_oracle_numerical_test() { + numerical_polynomial_common(5, 2, None, false); + } -#[test] -#[ignore] -fn three_of_three_oracle_numerical_with_diff_test() { - numerical_polynomial_common(3, 3, Some(get_difference_params()), false); -} + #[test] + #[ignore] + fn two_of_five_oracle_numerical_manual_test() { + numerical_polynomial_common(5, 2, None, true); + } -#[test] -#[ignore] -fn two_of_five_oracle_numerical_with_diff_test() { - numerical_polynomial_common(5, 2, Some(get_difference_params()), false); -} + #[test] + #[ignore] + fn three_of_three_oracle_numerical_with_diff_test() { + numerical_polynomial_common(3, 3, Some(get_difference_params()), false); + } -#[test] -#[ignore] -fn three_of_five_oracle_numerical_with_diff_test() { - numerical_polynomial_common(5, 3, Some(get_difference_params()), false); -} + #[test] + #[ignore] + fn two_of_five_oracle_numerical_with_diff_test() { + numerical_polynomial_common(5, 2, Some(get_difference_params()), false); + } -#[test] -#[ignore] -fn three_of_five_oracle_numerical_with_diff_manual_test() { - numerical_polynomial_common(5, 3, Some(get_difference_params()), true); -} + #[test] + #[ignore] + fn three_of_five_oracle_numerical_with_diff_test() { + numerical_polynomial_common(5, 3, Some(get_difference_params()), false); + } -#[test] -#[ignore] -fn enum_single_oracle_test() { - manager_execution_test(get_enum_test_params(1, 1, None), TestPath::Close, false); -} + #[test] + #[ignore] + fn three_of_five_oracle_numerical_with_diff_manual_test() { + numerical_polynomial_common(5, 3, Some(get_difference_params()), true); + } -#[test] -#[ignore] -fn enum_single_oracle_manual_test() { - manager_execution_test(get_enum_test_params(1, 1, None), TestPath::Close, true); -} + #[test] + #[ignore] + fn enum_single_oracle_test() { + manager_execution_test(get_enum_test_params(1, 1, None), TestPath::Close, false); + } -#[test] -#[ignore] -fn enum_3_of_3_test() { - manager_execution_test(get_enum_test_params(3, 3, None), TestPath::Close, false); -} + #[test] + #[ignore] + fn enum_single_oracle_manual_test() { + manager_execution_test(get_enum_test_params(1, 1, None), TestPath::Close, true); + } -#[test] -#[ignore] -fn enum_3_of_3_manual_test() { - manager_execution_test(get_enum_test_params(3, 3, None), TestPath::Close, true); -} + #[test] + #[ignore] + fn enum_3_of_3_test() { + manager_execution_test(get_enum_test_params(3, 3, None), TestPath::Close, false); + } -#[test] -#[ignore] -fn enum_3_of_5_test() { - manager_execution_test(get_enum_test_params(5, 3, None), TestPath::Close, false); -} + #[test] + #[ignore] + fn enum_3_of_3_manual_test() { + manager_execution_test(get_enum_test_params(3, 3, None), TestPath::Close, true); + } -#[test] -#[ignore] -fn enum_3_of_5_manual_test() { - manager_execution_test(get_enum_test_params(5, 3, None), TestPath::Close, true); -} + #[test] + #[ignore] + fn enum_3_of_5_test() { + manager_execution_test(get_enum_test_params(5, 3, None), TestPath::Close, false); + } -#[test] -#[ignore] -fn enum_and_numerical_with_diff_3_of_5_test() { - manager_execution_test( - get_enum_and_numerical_test_params(5, 3, true, Some(get_difference_params())), - TestPath::Close, - false, - ); -} + #[test] + #[ignore] + fn enum_3_of_5_manual_test() { + manager_execution_test(get_enum_test_params(5, 3, None), TestPath::Close, true); + } -#[test] -#[ignore] -fn enum_and_numerical_with_diff_3_of_5_manual_test() { - manager_execution_test( - get_enum_and_numerical_test_params(5, 3, true, Some(get_difference_params())), - TestPath::Close, - true, - ); -} + #[test] + #[ignore] + fn enum_and_numerical_with_diff_3_of_5_test() { + manager_execution_test( + get_enum_and_numerical_test_params(5, 3, true, Some(get_difference_params())), + TestPath::Close, + false, + ); + } -#[test] -#[ignore] -fn enum_and_numerical_with_diff_5_of_5_test() { - manager_execution_test( - get_enum_and_numerical_test_params(5, 5, true, Some(get_difference_params())), - TestPath::Close, - false, - ); -} + #[test] + #[ignore] + fn enum_and_numerical_with_diff_3_of_5_manual_test() { + manager_execution_test( + get_enum_and_numerical_test_params(5, 3, true, Some(get_difference_params())), + TestPath::Close, + true, + ); + } -#[test] -#[ignore] -fn enum_and_numerical_with_diff_5_of_5_manual_test() { - manager_execution_test( - get_enum_and_numerical_test_params(5, 5, true, Some(get_difference_params())), - TestPath::Close, - true, - ); -} + #[test] + #[ignore] + fn enum_and_numerical_with_diff_5_of_5_test() { + manager_execution_test( + get_enum_and_numerical_test_params(5, 5, true, Some(get_difference_params())), + TestPath::Close, + false, + ); + } -#[test] -#[ignore] -fn enum_and_numerical_3_of_5_test() { - manager_execution_test( - get_enum_and_numerical_test_params(5, 3, false, None), - TestPath::Close, - false, - ); -} + #[test] + #[ignore] + fn enum_and_numerical_with_diff_5_of_5_manual_test() { + manager_execution_test( + get_enum_and_numerical_test_params(5, 5, true, Some(get_difference_params())), + TestPath::Close, + true, + ); + } -#[test] -#[ignore] -fn enum_and_numerical_3_of_5_manual_test() { - manager_execution_test( - get_enum_and_numerical_test_params(5, 3, false, None), - TestPath::Close, - true, - ); -} + #[test] + #[ignore] + fn enum_and_numerical_3_of_5_test() { + manager_execution_test( + get_enum_and_numerical_test_params(5, 3, false, None), + TestPath::Close, + false, + ); + } -#[test] -#[ignore] -fn enum_and_numerical_5_of_5_test() { - manager_execution_test( - get_enum_and_numerical_test_params(5, 5, false, None), - TestPath::Close, - false, - ); -} + #[test] + #[ignore] + fn enum_and_numerical_3_of_5_manual_test() { + manager_execution_test( + get_enum_and_numerical_test_params(5, 3, false, None), + TestPath::Close, + true, + ); + } -#[test] -#[ignore] -fn enum_and_numerical_5_of_5_manual_test() { - manager_execution_test( - get_enum_and_numerical_test_params(5, 5, false, None), - TestPath::Close, - true, - ); -} + #[test] + #[ignore] + fn enum_and_numerical_5_of_5_test() { + manager_execution_test( + get_enum_and_numerical_test_params(5, 5, false, None), + TestPath::Close, + false, + ); + } -#[test] -#[ignore] -fn enum_single_oracle_refund_test() { - manager_execution_test( - get_enum_test_params(1, 1, Some(get_enum_oracles(1, 0))), - TestPath::Refund, - false, - ); -} + #[test] + #[ignore] + fn enum_and_numerical_5_of_5_manual_test() { + manager_execution_test( + get_enum_and_numerical_test_params(5, 5, false, None), + TestPath::Close, + true, + ); + } -#[test] -#[ignore] -fn enum_single_oracle_refund_manual_test() { - manager_execution_test( - get_enum_test_params(1, 1, Some(get_enum_oracles(1, 0))), - TestPath::Refund, - true, - ); -} + #[test] + #[ignore] + fn enum_single_oracle_refund_test() { + manager_execution_test( + get_enum_test_params(1, 1, Some(get_enum_oracles(1, 0))), + TestPath::Refund, + false, + ); + } -#[test] -#[ignore] -fn enum_single_oracle_bad_accept_cet_sig_test() { - manager_execution_test( - get_enum_test_params(1, 1, Some(get_enum_oracles(1, 0))), - TestPath::BadAcceptCetSignature, - false, - ); -} + #[test] + #[ignore] + fn enum_single_oracle_refund_manual_test() { + manager_execution_test( + get_enum_test_params(1, 1, Some(get_enum_oracles(1, 0))), + TestPath::Refund, + true, + ); + } -#[test] -#[ignore] -fn enum_single_oracle_bad_accept_refund_sig_test() { - manager_execution_test( - get_enum_test_params(1, 1, Some(get_enum_oracles(1, 0))), - TestPath::BadAcceptRefundSignature, - false, - ); -} + #[test] + #[ignore] + fn enum_single_oracle_bad_accept_cet_sig_test() { + manager_execution_test( + get_enum_test_params(1, 1, Some(get_enum_oracles(1, 0))), + TestPath::BadAcceptCetSignature, + false, + ); + } -#[test] -#[ignore] -fn enum_single_oracle_bad_sign_cet_sig_test() { - manager_execution_test( - get_enum_test_params(1, 1, Some(get_enum_oracles(1, 0))), - TestPath::BadSignCetSignature, - false, - ); -} + #[test] + #[ignore] + fn enum_single_oracle_bad_accept_refund_sig_test() { + manager_execution_test( + get_enum_test_params(1, 1, Some(get_enum_oracles(1, 0))), + TestPath::BadAcceptRefundSignature, + false, + ); + } -#[test] -#[ignore] -fn enum_single_oracle_bad_sign_refund_sig_test() { - manager_execution_test( - get_enum_test_params(1, 1, Some(get_enum_oracles(1, 0))), - TestPath::BadSignRefundSignature, - false, - ); -} + #[test] + #[ignore] + fn enum_single_oracle_bad_sign_cet_sig_test() { + manager_execution_test( + get_enum_test_params(1, 1, Some(get_enum_oracles(1, 0))), + TestPath::BadSignCetSignature, + false, + ); + } -#[test] -#[ignore] -fn two_of_two_oracle_numerical_diff_nb_digits_test() { - numerical_common_diff_nb_digits(2, 2, None, false, false); -} + #[test] + #[ignore] + fn enum_single_oracle_bad_sign_refund_sig_test() { + manager_execution_test( + get_enum_test_params(1, 1, Some(get_enum_oracles(1, 0))), + TestPath::BadSignRefundSignature, + false, + ); + } -#[test] -#[ignore] -fn two_of_two_oracle_numerical_diff_nb_digits_manual_test() { - numerical_common_diff_nb_digits(2, 2, None, false, true); -} + #[test] + #[ignore] + fn two_of_two_oracle_numerical_diff_nb_digits_test() { + numerical_common_diff_nb_digits(2, 2, None, false, false); + } -#[test] -#[ignore] -fn two_of_five_oracle_numerical_diff_nb_digits_test() { - numerical_common_diff_nb_digits(5, 2, None, false, false); -} + #[test] + #[ignore] + fn two_of_two_oracle_numerical_diff_nb_digits_manual_test() { + numerical_common_diff_nb_digits(2, 2, None, false, true); + } -#[test] -#[ignore] -fn two_of_five_oracle_numerical_diff_nb_digits_manual_test() { - numerical_common_diff_nb_digits(5, 2, None, false, true); -} + #[test] + #[ignore] + fn two_of_five_oracle_numerical_diff_nb_digits_test() { + numerical_common_diff_nb_digits(5, 2, None, false, false); + } -#[test] -#[ignore] -fn two_of_two_oracle_numerical_with_diff_diff_nb_digits_test() { - numerical_common_diff_nb_digits(2, 2, Some(get_difference_params()), false, false); -} + #[test] + #[ignore] + fn two_of_five_oracle_numerical_diff_nb_digits_manual_test() { + numerical_common_diff_nb_digits(5, 2, None, false, true); + } -#[test] -#[ignore] -fn three_of_three_oracle_numerical_with_diff_diff_nb_digits_test() { - numerical_common_diff_nb_digits(3, 3, Some(get_difference_params()), false, false); -} + #[test] + #[ignore] + fn two_of_two_oracle_numerical_with_diff_diff_nb_digits_test() { + numerical_common_diff_nb_digits(2, 2, Some(get_difference_params()), false, false); + } -#[test] -#[ignore] -fn two_of_five_oracle_numerical_with_diff_diff_nb_digits_test() { - numerical_common_diff_nb_digits(5, 2, Some(get_difference_params()), false, false); -} + #[test] + #[ignore] + fn three_of_three_oracle_numerical_with_diff_diff_nb_digits_test() { + numerical_common_diff_nb_digits(3, 3, Some(get_difference_params()), false, false); + } -#[test] -#[ignore] -fn two_of_two_oracle_numerical_with_diff_diff_nb_digits_max_value_test() { - numerical_common_diff_nb_digits(2, 2, Some(get_difference_params()), true, false); -} + #[test] + #[ignore] + fn two_of_five_oracle_numerical_with_diff_diff_nb_digits_test() { + numerical_common_diff_nb_digits(5, 2, Some(get_difference_params()), false, false); + } -#[test] -#[ignore] -fn two_of_three_oracle_numerical_with_diff_diff_nb_digits_max_value_test() { - numerical_common_diff_nb_digits(3, 2, Some(get_difference_params()), true, false); -} + #[test] + #[ignore] + fn two_of_two_oracle_numerical_with_diff_diff_nb_digits_max_value_test() { + numerical_common_diff_nb_digits(2, 2, Some(get_difference_params()), true, false); + } -#[test] -#[ignore] -fn two_of_five_oracle_numerical_with_diff_diff_nb_digits_max_value_test() { - numerical_common_diff_nb_digits(5, 2, Some(get_difference_params()), true, false); -} + #[test] + #[ignore] + fn two_of_three_oracle_numerical_with_diff_diff_nb_digits_max_value_test() { + numerical_common_diff_nb_digits(3, 2, Some(get_difference_params()), true, false); + } -#[test] -#[ignore] -fn two_of_five_oracle_numerical_with_diff_diff_nb_digits_max_value_manual_test() { - numerical_common_diff_nb_digits(5, 2, Some(get_difference_params()), true, true); -} + #[test] + #[ignore] + fn two_of_five_oracle_numerical_with_diff_diff_nb_digits_max_value_test() { + numerical_common_diff_nb_digits(5, 2, Some(get_difference_params()), true, false); + } -#[test] -#[ignore] -fn two_of_two_oracle_numerical_diff_nb_digits_max_value_test() { - numerical_common_diff_nb_digits(2, 2, None, true, false); -} + #[test] + #[ignore] + fn two_of_five_oracle_numerical_with_diff_diff_nb_digits_max_value_manual_test() { + numerical_common_diff_nb_digits(5, 2, Some(get_difference_params()), true, true); + } -#[test] -#[ignore] -fn two_of_three_oracle_numerical_diff_nb_digits_max_value_test() { - numerical_common_diff_nb_digits(3, 2, None, true, false); -} + #[test] + #[ignore] + fn two_of_two_oracle_numerical_diff_nb_digits_max_value_test() { + numerical_common_diff_nb_digits(2, 2, None, true, false); + } -#[test] -#[ignore] -fn two_of_five_oracle_numerical_diff_nb_digits_max_value_test() { - numerical_common_diff_nb_digits(5, 2, None, true, false); -} + #[test] + #[ignore] + fn two_of_three_oracle_numerical_diff_nb_digits_max_value_test() { + numerical_common_diff_nb_digits(3, 2, None, true, false); + } -#[test] -#[ignore] -fn two_of_five_oracle_numerical_diff_nb_digits_max_value_manual_test() { - numerical_common_diff_nb_digits(5, 2, None, true, true); -} + #[test] + #[ignore] + fn two_of_five_oracle_numerical_diff_nb_digits_max_value_test() { + numerical_common_diff_nb_digits(5, 2, None, true, false); + } -fn alter_adaptor_sig(input: &mut CetAdaptorSignatures) { - let sig_index = thread_rng().next_u32() as usize % input.ecdsa_adaptor_signatures.len(); - - let mut copy = input.ecdsa_adaptor_signatures[sig_index] - .signature - .as_ref() - .to_vec(); - let i = thread_rng().next_u32() as usize % secp256k1_zkp::ffi::ECDSA_ADAPTOR_SIGNATURE_LENGTH; - copy[i] = copy[i].checked_add(1).unwrap_or(0); - input.ecdsa_adaptor_signatures[sig_index].signature = - EcdsaAdaptorSignature::from_slice(©).unwrap(); -} + #[test] + #[ignore] + fn two_of_five_oracle_numerical_diff_nb_digits_max_value_manual_test() { + numerical_common_diff_nb_digits(5, 2, None, true, true); + } -fn alter_refund_sig(refund_signature: &Signature) -> Signature { - let mut copy = refund_signature.serialize_compact(); - let i = thread_rng().next_u32() as usize % secp256k1_zkp::constants::COMPACT_SIGNATURE_SIZE; - copy[i] = copy[i].checked_add(1).unwrap_or(0); - Signature::from_compact(©).unwrap() -} + fn alter_adaptor_sig(input: &mut CetAdaptorSignatures) { + let sig_index = thread_rng().next_u32() as usize % input.ecdsa_adaptor_signatures.len(); + + let mut copy = input.ecdsa_adaptor_signatures[sig_index] + .signature + .as_ref() + .to_vec(); + let i = + thread_rng().next_u32() as usize % secp256k1_zkp::ffi::ECDSA_ADAPTOR_SIGNATURE_LENGTH; + copy[i] = copy[i].checked_add(1).unwrap_or(0); + input.ecdsa_adaptor_signatures[sig_index].signature = + EcdsaAdaptorSignature::from_slice(©).unwrap(); + } -fn get_attestations(test_params: &TestParams) -> Vec<(usize, OracleAttestation)> { - for contract_info in test_params.contract_input.contract_infos.iter() { - let attestations: Vec<_> = contract_info - .oracles - .public_keys - .iter() - .enumerate() - .filter_map(|(i, pk)| { - let oracle = test_params - .oracles - .iter() - .find(|x| x.get_public_key() == *pk); - - oracle - .and_then(|o| o.get_attestation(&contract_info.oracles.event_id).ok()) - .map(|a| (i, a)) - }) - .collect(); - if attestations.len() >= contract_info.oracles.threshold as usize { - return attestations; + fn alter_refund_sig(refund_signature: &Signature) -> Signature { + let mut copy = refund_signature.serialize_compact(); + let i = thread_rng().next_u32() as usize % secp256k1_zkp::constants::COMPACT_SIGNATURE_SIZE; + copy[i] = copy[i].checked_add(1).unwrap_or(0); + Signature::from_compact(©).unwrap() + } + + fn get_attestations(test_params: &TestParams) -> Vec<(usize, OracleAttestation)> { + for contract_info in test_params.contract_input.contract_infos.iter() { + let attestations: Vec<_> = contract_info + .oracles + .public_keys + .iter() + .enumerate() + .filter_map(|(i, pk)| { + let oracle = test_params + .oracles + .iter() + .find(|x| x.get_public_key() == *pk); + + oracle + .and_then(|o| o.get_attestation(&contract_info.oracles.event_id).ok()) + .map(|a| (i, a)) + }) + .collect(); + if attestations.len() >= contract_info.oracles.threshold as usize { + return attestations; + } } + + panic!("No attestations found"); } - panic!("No attestations found"); -} + fn manager_execution_test(test_params: TestParams, path: TestPath, manual_close: bool) { + env_logger::try_init().ok(); + let (alice_send, bob_receive) = channel::>(); + let (bob_send, alice_receive) = channel::>(); + let (sync_send, sync_receive) = channel::<()>(); + let alice_sync_send = sync_send.clone(); + let bob_sync_send = sync_send; + let (_, _, sink_rpc) = init_clients(); + + let mut alice_oracles = HashMap::with_capacity(1); + let mut bob_oracles = HashMap::with_capacity(1); + + for oracle in test_params.oracles.clone() { + let oracle = Arc::new(oracle); + alice_oracles.insert(oracle.get_public_key(), Arc::clone(&oracle)); + bob_oracles.insert(oracle.get_public_key(), Arc::clone(&oracle)); + } + + let alice_store = Arc::new(mocks::memory_storage_provider::MemoryStorage::new()); + let bob_store = Arc::new(mocks::memory_storage_provider::MemoryStorage::new()); + let mock_time = Arc::new(mocks::mock_time::MockTime {}); + mocks::mock_time::set_time((EVENT_MATURITY as u64) - 1); + + let electrs = Arc::new(ElectrsBlockchainProvider::new( + "http://localhost:3004/".to_string(), + bitcoin::Network::Regtest, + )); + + let alice_wallet = Arc::new(SimpleWallet::new( + electrs.clone(), + alice_store.clone(), + bitcoin::Network::Regtest, + )); + + let bob_wallet = Arc::new(SimpleWallet::new( + electrs.clone(), + bob_store.clone(), + bitcoin::Network::Regtest, + )); + + let alice_fund_address = alice_wallet.get_new_address().unwrap(); + let bob_fund_address = bob_wallet.get_new_address().unwrap(); -fn manager_execution_test(test_params: TestParams, path: TestPath, manual_close: bool) { - env_logger::try_init().ok(); - let (alice_send, bob_receive) = channel::>(); - let (bob_send, alice_receive) = channel::>(); - let (sync_send, sync_receive) = channel::<()>(); - let alice_sync_send = sync_send.clone(); - let bob_sync_send = sync_send; - let (_, _, sink_rpc) = init_clients(); - - let mut alice_oracles = HashMap::with_capacity(1); - let mut bob_oracles = HashMap::with_capacity(1); - - for oracle in test_params.oracles.clone() { - let oracle = Arc::new(oracle); - alice_oracles.insert(oracle.get_public_key(), Arc::clone(&oracle)); - bob_oracles.insert(oracle.get_public_key(), Arc::clone(&oracle)); - } - - let alice_store = Arc::new(mocks::memory_storage_provider::MemoryStorage::new()); - let bob_store = Arc::new(mocks::memory_storage_provider::MemoryStorage::new()); - let mock_time = Arc::new(mocks::mock_time::MockTime {}); - mocks::mock_time::set_time((EVENT_MATURITY as u64) - 1); - - let electrs = Arc::new(ElectrsBlockchainProvider::new( - "http://localhost:3004/".to_string(), - bitcoin::Network::Regtest, - )); - - let alice_wallet = Arc::new(SimpleWallet::new( - electrs.clone(), - alice_store.clone(), - bitcoin::Network::Regtest, - )); - - let bob_wallet = Arc::new(SimpleWallet::new( - electrs.clone(), - bob_store.clone(), - bitcoin::Network::Regtest, - )); - - let alice_fund_address = alice_wallet.get_new_address().unwrap(); - let bob_fund_address = bob_wallet.get_new_address().unwrap(); - - sink_rpc - .send_to_address( - &alice_fund_address, - Amount::from_btc(2.0).unwrap(), - None, - None, - None, - None, - None, - None, - ) - .unwrap(); - - sink_rpc - .send_to_address( - &bob_fund_address, - Amount::from_btc(2.0).unwrap(), - None, - None, - None, - None, - None, - None, - ) - .unwrap(); - - let generate_blocks = |nb_blocks: u64| { - let prev_blockchain_height = electrs.get_blockchain_height().unwrap(); - - let sink_address = sink_rpc - .get_new_address(None, None) - .expect("RPC Error") - .assume_checked(); sink_rpc - .generate_to_address(nb_blocks, &sink_address) - .expect("RPC Error"); - - // Wait for electrs to have processed the new blocks - let mut cur_blockchain_height = prev_blockchain_height; - while cur_blockchain_height < prev_blockchain_height + nb_blocks { - std::thread::sleep(std::time::Duration::from_millis(200)); - cur_blockchain_height = electrs.get_blockchain_height().unwrap(); - } - }; + .send_to_address( + &alice_fund_address, + Amount::from_btc(2.0).unwrap(), + None, + None, + None, + None, + None, + None, + ) + .unwrap(); - generate_blocks(6); - - refresh_wallet(&alice_wallet, 200000000); - refresh_wallet(&bob_wallet, 200000000); - - let alice_manager = Arc::new(Mutex::new( - Manager::new( - Arc::clone(&alice_wallet), - Arc::clone(&alice_wallet), - Arc::clone(&electrs), - alice_store, - alice_oracles, - Arc::clone(&mock_time), - Arc::clone(&electrs), - ) - .unwrap(), - )); - - let alice_manager_loop = Arc::clone(&alice_manager); - let alice_manager_send = Arc::clone(&alice_manager); - - let bob_manager = Arc::new(Mutex::new( - Manager::new( - Arc::clone(&bob_wallet), - Arc::clone(&bob_wallet), - Arc::clone(&electrs), - bob_store, - bob_oracles, - Arc::clone(&mock_time), - Arc::clone(&electrs), - ) - .unwrap(), - )); - - let bob_manager_loop = Arc::clone(&bob_manager); - let bob_manager_send = Arc::clone(&bob_manager); - let alice_send_loop = alice_send.clone(); - let bob_send_loop = bob_send.clone(); - - let alice_expect_error = Arc::new(AtomicBool::new(false)); - let bob_expect_error = Arc::new(AtomicBool::new(false)); - - let alice_expect_error_loop = alice_expect_error.clone(); - let bob_expect_error_loop = bob_expect_error.clone(); - - let path_copy = path.clone(); - let alter_sign = move |msg| match msg { - Message::Sign(mut sign_dlc) => { - match path_copy { - TestPath::BadSignCetSignature => { - alter_adaptor_sig(&mut sign_dlc.cet_adaptor_signatures) - } - TestPath::BadSignRefundSignature => { - sign_dlc.refund_signature = alter_refund_sig(&sign_dlc.refund_signature); + sink_rpc + .send_to_address( + &bob_fund_address, + Amount::from_btc(2.0).unwrap(), + None, + None, + None, + None, + None, + None, + ) + .unwrap(); + + let generate_blocks = |nb_blocks: u64| { + let prev_blockchain_height = electrs.get_blockchain_height().unwrap(); + + let sink_address = sink_rpc + .get_new_address(None, None) + .expect("RPC Error") + .assume_checked(); + sink_rpc + .generate_to_address(nb_blocks, &sink_address) + .expect("RPC Error"); + + // Wait for electrs to have processed the new blocks + let mut cur_blockchain_height = prev_blockchain_height; + while cur_blockchain_height < prev_blockchain_height + nb_blocks { + std::thread::sleep(std::time::Duration::from_millis(200)); + cur_blockchain_height = electrs.get_blockchain_height().unwrap(); + } + }; + + generate_blocks(6); + + refresh_wallet(&alice_wallet, 200000000); + refresh_wallet(&bob_wallet, 200000000); + + let alice_manager = Arc::new(Mutex::new( + Manager::new( + Arc::clone(&alice_wallet), + Arc::clone(&alice_wallet), + Arc::clone(&electrs), + alice_store, + alice_oracles, + Arc::clone(&mock_time), + Arc::clone(&electrs), + ) + .unwrap(), + )); + + let alice_manager_loop = Arc::clone(&alice_manager); + let alice_manager_send = Arc::clone(&alice_manager); + + let bob_manager = Arc::new(Mutex::new( + Manager::new( + Arc::clone(&bob_wallet), + Arc::clone(&bob_wallet), + Arc::clone(&electrs), + bob_store, + bob_oracles, + Arc::clone(&mock_time), + Arc::clone(&electrs), + ) + .unwrap(), + )); + + let bob_manager_loop = Arc::clone(&bob_manager); + let bob_manager_send = Arc::clone(&bob_manager); + let alice_send_loop = alice_send.clone(); + let bob_send_loop = bob_send.clone(); + + let alice_expect_error = Arc::new(AtomicBool::new(false)); + let bob_expect_error = Arc::new(AtomicBool::new(false)); + + let alice_expect_error_loop = alice_expect_error.clone(); + let bob_expect_error_loop = bob_expect_error.clone(); + + let path_copy = path.clone(); + let alter_sign = move |msg| match msg { + Message::Sign(mut sign_dlc) => { + match path_copy { + TestPath::BadSignCetSignature => { + alter_adaptor_sig(&mut sign_dlc.cet_adaptor_signatures) + } + TestPath::BadSignRefundSignature => { + sign_dlc.refund_signature = alter_refund_sig(&sign_dlc.refund_signature); + } + _ => {} } - _ => {} + Some(Message::Sign(sign_dlc)) } - Some(Message::Sign(sign_dlc)) - } - _ => Some(msg), - }; + _ => Some(msg), + }; - let msg_callback = |msg: &Message| { - if let Message::Sign(s) = msg { - write_message("sign_message", s.clone()); - } - }; + let msg_callback = |msg: &Message| { + if let Message::Sign(s) = msg { + write_message("sign_message", s.clone()); + } + }; - let alice_handle = receive_loop!( - alice_receive, - alice_manager_loop, - alice_send_loop, - alice_expect_error_loop, - alice_sync_send, - Some, - msg_callback - ); - - let bob_handle = receive_loop!( - bob_receive, - bob_manager_loop, - bob_send_loop, - bob_expect_error_loop, - bob_sync_send, - alter_sign, - msg_callback - ); - - let offer_msg = bob_manager_send - .lock() - .unwrap() - .send_offer( - &test_params.contract_input, - "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166" - .parse() - .unwrap(), - ) - .expect("Send offer error"); - - write_message("offer_message", offer_msg.clone()); - let temporary_contract_id = offer_msg.temporary_contract_id; - bob_send.send(Some(Message::Offer(offer_msg))).unwrap(); - - assert_contract_state!(bob_manager_send, temporary_contract_id, Offered); - - sync_receive.recv().expect("Error synchronizing"); - - assert_contract_state!(alice_manager_send, temporary_contract_id, Offered); - - let (contract_id, _, mut accept_msg) = alice_manager_send - .lock() - .unwrap() - .accept_contract_offer(&temporary_contract_id) - .expect("Error accepting contract offer"); - - write_message("accept_message", accept_msg.clone()); - - assert_contract_state!(alice_manager_send, contract_id, Accepted); - - match path { - TestPath::BadAcceptCetSignature | TestPath::BadAcceptRefundSignature => { - match path { - TestPath::BadAcceptCetSignature => { - alter_adaptor_sig(&mut accept_msg.cet_adaptor_signatures) - } - TestPath::BadAcceptRefundSignature => { - accept_msg.refund_signature = alter_refund_sig(&accept_msg.refund_signature); - } - _ => {} - }; - bob_expect_error.store(true, Ordering::Relaxed); - alice_send.send(Some(Message::Accept(accept_msg))).unwrap(); - sync_receive.recv().expect("Error synchronizing"); - assert_contract_state!(bob_manager_send, temporary_contract_id, FailedAccept); - } - TestPath::BadSignCetSignature | TestPath::BadSignRefundSignature => { - alice_expect_error.store(true, Ordering::Relaxed); - alice_send.send(Some(Message::Accept(accept_msg))).unwrap(); - // Bob receives accept message - sync_receive.recv().expect("Error synchronizing"); - // Alice receives sign message - sync_receive.recv().expect("Error synchronizing"); - assert_contract_state!(alice_manager_send, contract_id, FailedSign); - } - TestPath::Close | TestPath::Refund => { - alice_send.send(Some(Message::Accept(accept_msg))).unwrap(); - sync_receive.recv().expect("Error synchronizing"); + let alice_handle = receive_loop!( + alice_receive, + alice_manager_loop, + alice_send_loop, + alice_expect_error_loop, + alice_sync_send, + Some, + msg_callback + ); + + let bob_handle = receive_loop!( + bob_receive, + bob_manager_loop, + bob_send_loop, + bob_expect_error_loop, + bob_sync_send, + alter_sign, + msg_callback + ); + + let offer_msg = bob_manager_send + .lock() + .unwrap() + .send_offer( + &test_params.contract_input, + "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166" + .parse() + .unwrap(), + ) + .expect("Send offer error"); - assert_contract_state!(bob_manager_send, contract_id, Signed); + write_message("offer_message", offer_msg.clone()); + let temporary_contract_id = offer_msg.temporary_contract_id; + bob_send.send(Some(Message::Offer(offer_msg))).unwrap(); - // Should not change state and should not error - periodic_check!(bob_manager_send, contract_id, Signed); + assert_contract_state!(bob_manager_send, temporary_contract_id, Offered); - sync_receive.recv().expect("Error synchronizing"); + sync_receive.recv().expect("Error synchronizing"); - assert_contract_state!(alice_manager_send, contract_id, Signed); + assert_contract_state!(alice_manager_send, temporary_contract_id, Offered); - generate_blocks(6); + let (contract_id, _, mut accept_msg) = alice_manager_send + .lock() + .unwrap() + .accept_contract_offer(&temporary_contract_id) + .expect("Error accepting contract offer"); + + write_message("accept_message", accept_msg.clone()); - periodic_check!(alice_manager_send, contract_id, Confirmed); - periodic_check!(bob_manager_send, contract_id, Confirmed); + assert_contract_state!(alice_manager_send, contract_id, Accepted); - if !manual_close { - mocks::mock_time::set_time((EVENT_MATURITY as u64) + 1); + match path { + TestPath::BadAcceptCetSignature | TestPath::BadAcceptRefundSignature => { + match path { + TestPath::BadAcceptCetSignature => { + alter_adaptor_sig(&mut accept_msg.cet_adaptor_signatures) + } + TestPath::BadAcceptRefundSignature => { + accept_msg.refund_signature = + alter_refund_sig(&accept_msg.refund_signature); + } + _ => {} + }; + bob_expect_error.store(true, Ordering::Relaxed); + alice_send.send(Some(Message::Accept(accept_msg))).unwrap(); + sync_receive.recv().expect("Error synchronizing"); + assert_contract_state!(bob_manager_send, temporary_contract_id, FailedAccept); + } + TestPath::BadSignCetSignature | TestPath::BadSignRefundSignature => { + alice_expect_error.store(true, Ordering::Relaxed); + alice_send.send(Some(Message::Accept(accept_msg))).unwrap(); + // Bob receives accept message + sync_receive.recv().expect("Error synchronizing"); + // Alice receives sign message + sync_receive.recv().expect("Error synchronizing"); + assert_contract_state!(alice_manager_send, contract_id, FailedSign); } + TestPath::Close | TestPath::Refund => { + alice_send.send(Some(Message::Accept(accept_msg))).unwrap(); + sync_receive.recv().expect("Error synchronizing"); - // Select the first one to close or refund randomly - let (first, second) = if thread_rng().next_u32() % 2 == 0 { - (alice_manager_send, bob_manager_send) - } else { - (bob_manager_send, alice_manager_send) - }; + assert_contract_state!(bob_manager_send, contract_id, Signed); - match path { - TestPath::Close => { - let case = thread_rng().next_u64() % 3; - let blocks: Option = if case == 2 { - Some(6) - } else if case == 1 { - Some(1) - } else { - None - }; - - if manual_close { - periodic_check!(first, contract_id, Confirmed); + // Should not change state and should not error + periodic_check!(bob_manager_send, contract_id, Signed); + + sync_receive.recv().expect("Error synchronizing"); + + assert_contract_state!(alice_manager_send, contract_id, Signed); - let attestations = get_attestations(&test_params); - - let f = first.lock().unwrap(); - let contract = f - .close_confirmed_contract(&contract_id, attestations) - .expect("Error closing contract"); - - if let Contract::PreClosed(contract) = contract { - let mut s = second.lock().unwrap(); - let second_contract = - s.get_store().get_contract(&contract_id).unwrap().unwrap(); - if let Contract::Confirmed(signed) = second_contract { - s.on_counterparty_close( - &signed, - contract.signed_cet, - blocks.unwrap_or(0), - ) - .expect("Error registering counterparty close"); + generate_blocks(6); + + periodic_check!(alice_manager_send, contract_id, Confirmed); + periodic_check!(bob_manager_send, contract_id, Confirmed); + + if !manual_close { + mocks::mock_time::set_time((EVENT_MATURITY as u64) + 1); + } + + // Select the first one to close or refund randomly + let (first, second) = if thread_rng().next_u32() % 2 == 0 { + (alice_manager_send, bob_manager_send) + } else { + (bob_manager_send, alice_manager_send) + }; + + match path { + TestPath::Close => { + let case = thread_rng().next_u64() % 3; + let blocks: Option = if case == 2 { + Some(6) + } else if case == 1 { + Some(1) + } else { + None + }; + + if manual_close { + periodic_check!(first, contract_id, Confirmed); + + let attestations = get_attestations(&test_params); + + let f = first.lock().unwrap(); + let contract = f + .close_confirmed_contract(&contract_id, attestations) + .expect("Error closing contract"); + + if let Contract::PreClosed(contract) = contract { + let mut s = second.lock().unwrap(); + let second_contract = + s.get_store().get_contract(&contract_id).unwrap().unwrap(); + if let Contract::Confirmed(signed) = second_contract { + s.on_counterparty_close( + &signed, + contract.signed_cet, + blocks.unwrap_or(0), + ) + .expect("Error registering counterparty close"); + } else { + panic!("Invalid contract state: {:?}", second_contract); + } } else { - panic!("Invalid contract state: {:?}", second_contract); + panic!("Invalid contract state {:?}", contract); } } else { - panic!("Invalid contract state {:?}", contract); + periodic_check!(first, contract_id, PreClosed); } - } else { - periodic_check!(first, contract_id, PreClosed); - } - // mine blocks for the CET to be confirmed - if let Some(b) = blocks { - generate_blocks(b as u64); - } + // mine blocks for the CET to be confirmed + if let Some(b) = blocks { + generate_blocks(b as u64); + } - // Randomly check with or without having the CET mined - if case == 2 { - // cet becomes fully confirmed to blockchain - periodic_check!(first, contract_id, Closed); - periodic_check!(second, contract_id, Closed); - } else { - periodic_check!(first, contract_id, PreClosed); - periodic_check!(second, contract_id, PreClosed); + // Randomly check with or without having the CET mined + if case == 2 { + // cet becomes fully confirmed to blockchain + periodic_check!(first, contract_id, Closed); + periodic_check!(second, contract_id, Closed); + } else { + periodic_check!(first, contract_id, PreClosed); + periodic_check!(second, contract_id, PreClosed); + } } - } - TestPath::Refund => { - periodic_check!(first, contract_id, Confirmed); + TestPath::Refund => { + periodic_check!(first, contract_id, Confirmed); - periodic_check!(second, contract_id, Confirmed); + periodic_check!(second, contract_id, Confirmed); - mocks::mock_time::set_time( - ((EVENT_MATURITY + dlc_manager::manager::REFUND_DELAY) as u64) + 1, - ); + mocks::mock_time::set_time( + ((EVENT_MATURITY + dlc_manager::manager::REFUND_DELAY) as u64) + 1, + ); - generate_blocks(10); + generate_blocks(10); - periodic_check!(first, contract_id, Refunded); + periodic_check!(first, contract_id, Refunded); - // Randomly check with or without having the Refund mined. - if thread_rng().next_u32() % 2 == 0 { - generate_blocks(1); - } + // Randomly check with or without having the Refund mined. + if thread_rng().next_u32() % 2 == 0 { + generate_blocks(1); + } - periodic_check!(second, contract_id, Refunded); + periodic_check!(second, contract_id, Refunded); + } + _ => unreachable!(), } - _ => unreachable!(), } } - } - alice_send.send(None).unwrap(); - bob_send.send(None).unwrap(); + alice_send.send(None).unwrap(); + bob_send.send(None).unwrap(); - alice_handle.join().unwrap(); - bob_handle.join().unwrap(); + alice_handle.join().unwrap(); + bob_handle.join().unwrap(); - create_test_vector(); + create_test_vector(); + } } diff --git a/p2pd-oracle-client/src/lib.rs b/p2pd-oracle-client/src/lib.rs index 567eaa5e..5211293d 100644 --- a/p2pd-oracle-client/src/lib.rs +++ b/p2pd-oracle-client/src/lib.rs @@ -227,6 +227,7 @@ impl Oracle for P2PDOracleClient { .map_err(|e| DlcManagerError::OracleError(e.to_string()))?; Ok(OracleAttestation { + event_id: event_id.to_string(), oracle_public_key: self.public_key, signatures, outcomes: values,