Skip to content

Commit

Permalink
Merge pull request #373 from mojoX911/fix-connection-state2
Browse files Browse the repository at this point in the history
fix the connection state map
  • Loading branch information
mojoX911 authored Jan 8, 2025
2 parents 1a3d987 + 16aeb97 commit 290e643
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 34 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ edition = "2018"

description = "Functioning, minimal-viable binaries and libraries to perform a trustless, p2p Maxwell-Belcher Coinswap Protocol"
license = "MIT OR Apache-2.0"
license-file = "LICENSE"
documentation = "https://docs.rs/coinswap"
homepage = "https://github.com/citadel-tech/coinswap"
repository = "https://github.com/citadel-tech/coinswap"
Expand Down
7 changes: 3 additions & 4 deletions src/maker/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ use bitcoin::{
use bitcoind::bitcoincore_rpc::RpcApi;
use std::{
collections::HashMap,
net::IpAddr,
path::PathBuf,
sync::{
atomic::{AtomicBool, Ordering::Relaxed},
Expand Down Expand Up @@ -226,7 +225,7 @@ pub struct Maker {
/// A flag to trigger shutdown event
pub shutdown: AtomicBool,
/// Map of IP address to Connection State + last Connected instant
pub(crate) connection_state: Mutex<HashMap<IpAddr, (ConnectionState, Instant)>>,
pub(crate) connection_state: Mutex<HashMap<String, (ConnectionState, Instant)>>,
/// Highest Value Fidelity Proof
pub(crate) highest_fidelity_proof: RwLock<Option<FidelityProof>>,
/// Is setup complete
Expand Down Expand Up @@ -566,7 +565,7 @@ pub(crate) fn check_for_broadcasted_contracts(maker: Arc<Maker>) -> Result<(), M
);
}
}
failed_swap_ip.push(*ip);
failed_swap_ip.push(ip.clone());

// Spawn a separate thread to wait for contract maturity and broadcasting timelocked.
let maker_clone = maker.clone();
Expand Down Expand Up @@ -697,7 +696,7 @@ pub(crate) fn check_for_idle_states(maker: Arc<Maker>) -> Result<(), MakerError>
let incoming_contract = ic_sc.get_fully_signed_contract_tx()?;
incomings.push((ic_sc.get_multisig_redeemscript(), incoming_contract));
}
bad_ip.push(*ip);
bad_ip.push(ip.clone());
// Spawn a separate thread to wait for contract maturity and broadcasting timelocked.
let maker_clone = maker.clone();
log::info!(
Expand Down
35 changes: 17 additions & 18 deletions src/maker/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//! The file includes functions to validate and sign contract transactions, verify proof of funding, and handle unexpected recovery scenarios.
//! Implements the core functionality for a Maker in a Bitcoin coinswap protocol.
use std::{collections::HashMap, net::IpAddr, sync::Arc, time::Instant};
use std::{collections::HashMap, sync::Arc, time::Instant};

use bitcoin::{
hashes::Hash,
Expand Down Expand Up @@ -48,7 +48,6 @@ pub(crate) fn handle_message(
maker: &Arc<Maker>,
connection_state: &mut ConnectionState,
message: TakerToMakerMessage,
ip: IpAddr,
) -> Result<Option<MakerToTakerMessage>, MakerError> {
let outgoing_message = match connection_state.allowed_message {
ExpectedMessage::TakerHello => {
Expand Down Expand Up @@ -106,7 +105,7 @@ pub(crate) fn handle_message(
TakerToMakerMessage::RespProofOfFunding(proof) => {
connection_state.allowed_message =
ExpectedMessage::ProofOfFundingORContractSigsForRecvrAndSender;
Some(maker.handle_proof_of_funding(connection_state, proof, ip)?)
Some(maker.handle_proof_of_funding(connection_state, proof)?)
}
TakerToMakerMessage::ReqContractSigsForRecvr(message) => {
connection_state.allowed_message = ExpectedMessage::HashPreimage;
Expand Down Expand Up @@ -138,7 +137,7 @@ pub(crate) fn handle_message(
if let TakerToMakerMessage::RespProofOfFunding(proof) = message {
connection_state.allowed_message =
ExpectedMessage::ProofOfFundingORContractSigsForRecvrAndSender;
Some(maker.handle_proof_of_funding(connection_state, proof, ip)?)
Some(maker.handle_proof_of_funding(connection_state, proof)?)
} else {
return Err(MakerError::UnexpectedMessage {
expected: "Proof OF Funding".to_string(),
Expand All @@ -151,16 +150,12 @@ pub(crate) fn handle_message(
TakerToMakerMessage::RespProofOfFunding(proof) => {
connection_state.allowed_message =
ExpectedMessage::ProofOfFundingORContractSigsForRecvrAndSender;
Some(maker.handle_proof_of_funding(connection_state, proof, ip)?)
Some(maker.handle_proof_of_funding(connection_state, proof)?)
}
TakerToMakerMessage::RespContractSigsForRecvrAndSender(message) => {
// Nothing to send. Maker now creates and broadcasts his funding Txs
connection_state.allowed_message = ExpectedMessage::ReqContractSigsForRecvr;
maker.handle_contract_sigs_for_recvr_and_sender(
connection_state,
message,
ip,
)?;
maker.handle_contract_sigs_for_recvr_and_sender(connection_state, message)?;
if let MakerBehavior::BroadcastContractAfterSetup = maker.behavior {
unexpected_recovery(maker.clone())?;
return Err(maker.behavior.into());
Expand Down Expand Up @@ -261,7 +256,6 @@ impl Maker {
&self,
connection_state: &mut ConnectionState,
message: ProofOfFunding,
ip: IpAddr,
) -> Result<MakerToTakerMessage, MakerError> {
if let MakerBehavior::CloseAtProofOfFunding = self.behavior {
return Err(self.behavior.into());
Expand Down Expand Up @@ -459,9 +453,12 @@ impl Maker {
.collect::<Result<Vec<SenderContractTxInfo>, WalletError>>()?;

// Update the connection state.
self.connection_state
.lock()?
.insert(ip, (connection_state.clone(), Instant::now()));
self.connection_state.lock()?.insert(
message.id.clone(),
(connection_state.clone(), Instant::now()),
);

log::info!("Connection state initiatilzed for swap id: {}", message.id);

Ok(MakerToTakerMessage::ReqContractSigsAsRecvrAndSender(
ContractSigsAsRecvrAndSender {
Expand All @@ -476,7 +473,6 @@ impl Maker {
&self,
connection_state: &mut ConnectionState,
message: ContractSigsForRecvrAndSender,
ip: IpAddr,
) -> Result<(), MakerError> {
if let MakerBehavior::CloseAtContractSigsForRecvrAndSender = self.behavior {
return Err(self.behavior.into());
Expand Down Expand Up @@ -537,9 +533,12 @@ impl Maker {
}

// Update the connection state.
self.connection_state
.lock()?
.insert(ip, (connection_state.clone(), Instant::now()));
self.connection_state.lock()?.insert(
message.id.clone(),
(connection_state.clone(), Instant::now()),
);

log::info!("Connection state timer reset for swap id: {}", message.id);

Ok(())
}
Expand Down
17 changes: 7 additions & 10 deletions src/maker/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use std::{
io::ErrorKind,
net::{Ipv4Addr, SocketAddr, TcpListener, TcpStream},
net::{Ipv4Addr, TcpListener, TcpStream},
path::PathBuf,
process::Child,
sync::{
Expand Down Expand Up @@ -36,6 +36,7 @@ use crate::{
rpc::start_rpc_server,
},
protocol::messages::{DnsMetadata, DnsRequest, TakerToMakerMessage},
taker::api::MINER_FEE,
utill::{get_tor_addrs, read_message, send_message, ConnectionType, HEART_BEAT_INTERVAL},
wallet::WalletError,
};
Expand Down Expand Up @@ -263,7 +264,7 @@ fn setup_fidelity_bond(maker: &Arc<Maker>, maker_address: &str) -> Result<(), Ma
let mut sleep_multiplier = 0;
log::info!("No active Fidelity Bonds found. Creating one.");
log::info!("Fidelity value chosen = {:?} sats", amount.to_sat());
log::info!("Fidelity Tx fee = 300 sats");
log::info!("Fidelity Tx fee = {} sats", MINER_FEE);
log::info!(
"Fidelity timelock {} blocks",
maker.config.fidelity_timelock
Expand Down Expand Up @@ -371,11 +372,7 @@ fn check_connection_with_core(
}

/// Handle a single client connection.
fn handle_client(
maker: Arc<Maker>,
stream: &mut TcpStream,
client_addr: SocketAddr,
) -> Result<(), MakerError> {
fn handle_client(maker: Arc<Maker>, stream: &mut TcpStream) -> Result<(), MakerError> {
stream.set_nonblocking(false)?; // Block this thread until message is read.

let mut connection_state = ConnectionState::default();
Expand All @@ -401,7 +398,7 @@ fn handle_client(
let taker_msg: TakerToMakerMessage = serde_cbor::from_slice(&taker_msg_bytes)?;
log::info!("[{}] <=== {}", maker.config.network_port, taker_msg);

let reply = handle_message(&maker, &mut connection_state, taker_msg, client_addr.ip());
let reply = handle_message(&maker, &mut connection_state, taker_msg);

match reply {
Ok(reply) => {
Expand Down Expand Up @@ -575,13 +572,13 @@ pub fn start_maker_server(maker: Arc<Maker>) -> Result<(), MakerError> {
}

match listener.accept() {
Ok((mut stream, client_addr)) => {
Ok((mut stream, _)) => {
log::info!(
"[{}] Received incoming connection",
maker.config.network_port
);

if let Err(e) = handle_client(maker, &mut stream, client_addr) {
if let Err(e) = handle_client(maker, &mut stream) {
log::error!("[{}] Error Handling client request {:?}", port, e);
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/protocol/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1295,6 +1295,7 @@ mod test {
}],
refund_locktime: u16::default(),
contract_feerate: u64::default(),
id: "random".to_string(),
};

// case with same hash value
Expand Down Expand Up @@ -1324,6 +1325,7 @@ mod test {
}],
refund_locktime: u16::default(),
contract_feerate: u64::default(),
id: "random".to_string(),
};

let hash_value_from_fn = check_hashvalues_are_equal(&funding_proof).unwrap_err();
Expand Down
3 changes: 3 additions & 0 deletions src/protocol/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ pub(crate) struct ProofOfFunding {
pub(crate) next_coinswap_info: Vec<NextHopInfo>,
pub(crate) refund_locktime: u16,
pub(crate) contract_feerate: u64,
pub(crate) id: String,
}

/// Signatures required for an intermediate Maker to perform receiving and sending of coinswaps.
Expand All @@ -159,6 +160,8 @@ pub(crate) struct ContractSigsForRecvrAndSender {
pub(crate) receivers_sigs: Vec<Signature>,
/// Sigs from the next peer for Contract Tx of next hop, (coinswap sent by this Maker).
pub(crate) senders_sigs: Vec<Signature>,
/// Unique ID for a swap
pub(crate) id: String,
}

/// Message to Transfer [`HashPreimage`] from Taker to Makers.
Expand Down
12 changes: 11 additions & 1 deletion src/taker/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use socks::Socks5Stream;
use bitcoin::{
consensus::encode::deserialize,
hashes::{hash160::Hash as Hash160, Hash},
hex::DisplayHex,
hex::{Case, DisplayHex},
secp256k1::{
rand::{rngs::OsRng, RngCore},
SecretKey,
Expand Down Expand Up @@ -140,6 +140,8 @@ struct OngoingSwapState {
pub(crate) active_preimage: Preimage,
/// Enum defining the position of the Taker at each steps of a multihop swap.
pub(crate) taker_position: TakerPosition,
/// Unique ID for a swap
pub(crate) id: String,
}

/// Information for the next maker in the hop.
Expand Down Expand Up @@ -385,8 +387,13 @@ impl Taker {
let mut preimage = [0u8; 32];
OsRng.fill_bytes(&mut preimage);

let unique_id = preimage[0..8].to_hex_string(Case::Lower);

log::info!("Initiating coinswap with id : {}", unique_id);

self.ongoing_swap_state.active_preimage = preimage;
self.ongoing_swap_state.swap_params = swap_params;
self.ongoing_swap_state.id = unique_id;

let available = self.wallet.spendable_balance()?;

Expand Down Expand Up @@ -1057,6 +1064,7 @@ impl Taker {
this_maker_info,
next_maker_info,
self.get_preimage_hash(),
self.ongoing_swap_state.id.clone(),
)?;
log::info!(
"<=== Recieved ContractSigsAsRecvrAndSender from {}",
Expand Down Expand Up @@ -1176,12 +1184,14 @@ impl Taker {
"===> Sending ContractSigsAsReceiverAndSender to {}",
this_maker.address
);
let id = self.ongoing_swap_state.id.clone();
send_message(
&mut socket,
&TakerToMakerMessage::RespContractSigsForRecvrAndSender(
ContractSigsForRecvrAndSender {
receivers_sigs,
senders_sigs,
id,
},
),
)?;
Expand Down
2 changes: 2 additions & 0 deletions src/taker/routines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ pub(crate) fn send_proof_of_funding_and_init_next_hop(
tmi: ThisMakerInfo,
npi: NextMakerInfo,
hashvalue: Hash160,
id: String,
) -> Result<(ContractSigsAsRecvrAndSender, Vec<ScriptBuf>), TakerError> {
// Send POF
let next_coinswap_info = npi
Expand All @@ -279,6 +280,7 @@ pub(crate) fn send_proof_of_funding_and_init_next_hop(
next_coinswap_info,
refund_locktime: tmi.this_maker_refund_locktime,
contract_feerate: MINER_FEE,
id,
});

send_message(socket, &pof_msg)?;
Expand Down

0 comments on commit 290e643

Please sign in to comment.