-
Notifications
You must be signed in to change notification settings - Fork 13
feat: disable zmq connectivity detection for windows build #53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,6 @@ use crossbeam_channel::Sender; | |
| use dash_sdk::dpp::dashcore::consensus::Decodable; | ||
| use dash_sdk::dpp::dashcore::{Block, InstantLock, Network, Transaction}; | ||
| use dash_sdk::dpp::prelude::CoreBlockHeight; | ||
| use image::EncodableLayout; | ||
| use std::error::Error; | ||
| use std::io::Cursor; | ||
| use std::sync::{ | ||
|
|
@@ -11,7 +10,18 @@ use std::sync::{ | |
| }; | ||
| use std::thread; | ||
| use std::time::Duration; | ||
|
|
||
| #[cfg(not(target_os = "windows"))] | ||
| use zmq::Context; | ||
| #[cfg(not(target_os = "windows"))] | ||
| use image::EncodableLayout; | ||
|
|
||
| #[cfg(target_os = "windows")] | ||
| use futures::StreamExt; | ||
| #[cfg(target_os = "windows")] | ||
| use tokio::runtime::Runtime; | ||
| #[cfg(target_os = "windows")] | ||
| use zeromq::{Socket, SocketRecv, SubSocket}; | ||
|
|
||
| pub struct CoreZMQListener { | ||
| should_stop: Arc<AtomicBool>, | ||
|
|
@@ -30,10 +40,18 @@ pub enum ZMQConnectionEvent { | |
| Disconnected, | ||
| } | ||
|
|
||
| #[cfg(not(target_os = "windows"))] | ||
| pub const IS_LOCK_SIG_MSG: &[u8; 12] = b"rawtxlocksig"; | ||
| #[cfg(not(target_os = "windows"))] | ||
| pub const CHAIN_LOCKED_BLOCK_MSG: &[u8; 12] = b"rawchainlock"; | ||
|
|
||
| #[cfg(target_os = "windows")] | ||
| pub const IS_LOCK_SIG_MSG: &str = "rawtxlocksig"; | ||
| #[cfg(target_os = "windows")] | ||
| pub const CHAIN_LOCKED_BLOCK_MSG: &str = "rawchainlock"; | ||
|
|
||
| impl CoreZMQListener { | ||
| #[cfg(not(target_os = "windows"))] | ||
| pub fn spawn_listener( | ||
| network: Network, | ||
| endpoint: &str, | ||
|
|
@@ -256,6 +274,142 @@ impl CoreZMQListener { | |
| }) | ||
| } | ||
|
|
||
| #[cfg(target_os = "windows")] | ||
| pub fn spawn_listener( | ||
| network: Network, | ||
| endpoint: &str, | ||
| sender: mpsc::Sender<(ZMQMessage, Network)>, | ||
| tx_zmq_status: Option<Sender<ZMQConnectionEvent>>, | ||
| ) -> Result<Self, Box<dyn Error>> { | ||
| let should_stop = Arc::new(AtomicBool::new(false)); | ||
| let endpoint = endpoint.to_string(); | ||
| let should_stop_clone = Arc::clone(&should_stop); | ||
| let sender_clone = sender.clone(); | ||
|
|
||
| let handle = thread::spawn(move || { | ||
| // Create the runtime inside the thread. | ||
| let rt = Runtime::new().unwrap(); | ||
| rt.block_on(async move { | ||
| // Create the socket inside the async context. | ||
| let mut socket = SubSocket::new(); | ||
|
|
||
| // Connect to the endpoint | ||
| socket | ||
| .connect(&endpoint) | ||
| .await | ||
| .expect("Failed to connect"); | ||
|
|
||
| // Subscribe to the "rawtxlocksig" events. | ||
| socket | ||
| .subscribe(IS_LOCK_SIG_MSG) | ||
| .await | ||
| .expect("Failed to subscribe to rawtxlocksig"); | ||
|
|
||
| // Subscribe to the "rawchainlock" events. | ||
| socket | ||
| .subscribe(CHAIN_LOCKED_BLOCK_MSG) | ||
| .await | ||
| .expect("Failed to subscribe to rawchainlock"); | ||
|
|
||
| println!("Subscribed to ZMQ at {}", endpoint); | ||
|
|
||
| while !should_stop_clone.load(Ordering::SeqCst) { | ||
| // Receive messages | ||
| match socket.recv().await { | ||
| Ok(msg) => { | ||
| // Access frames using msg.get(n) | ||
| if let Some(topic_frame) = msg.get(0) { | ||
| let topic = String::from_utf8_lossy(topic_frame).to_string(); | ||
|
|
||
| if let Some(data_frame) = msg.get(1) { | ||
| let data_bytes = data_frame; | ||
|
|
||
| match topic.as_str() { | ||
| "rawchainlock" => { | ||
| // Deserialize the Block | ||
| let mut cursor = Cursor::new(data_bytes); | ||
| match Block::consensus_decode(&mut cursor) { | ||
| Ok(block) => { | ||
| if let Err(e) = sender_clone.send(( | ||
| ZMQMessage::ChainLockedBlock(block), | ||
| network, | ||
| )) { | ||
| eprintln!( | ||
| "Error sending data to main thread: {}", | ||
| e | ||
| ); | ||
| } | ||
| } | ||
| Err(e) => { | ||
| eprintln!( | ||
| "Error deserializing chain locked block: {}", | ||
| e | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| "rawtxlocksig" => { | ||
| // Deserialize the Transaction and InstantLock | ||
| let mut cursor = Cursor::new(data_bytes); | ||
| match Transaction::consensus_decode(&mut cursor) { | ||
| Ok(tx) => { | ||
| match InstantLock::consensus_decode(&mut cursor) | ||
| { | ||
| Ok(islock) => { | ||
| if let Err(e) = sender_clone.send(( | ||
| ZMQMessage::ISLockedTransaction( | ||
| tx, islock, | ||
| ), | ||
| network, | ||
| )) { | ||
| eprintln!( | ||
| "Error sending data to main thread: {}", | ||
| e | ||
| ); | ||
| } | ||
| } | ||
| Err(e) => { | ||
| eprintln!( | ||
| "Error deserializing InstantLock: {}", | ||
| e | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| Err(e) => { | ||
| eprintln!( | ||
| "Error deserializing transaction: {}", | ||
| e | ||
| ); | ||
| } | ||
| } | ||
| } | ||
| _ => { | ||
| println!("Received unknown topic: {}", topic); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Err(e) => { | ||
| eprintln!("Error receiving message: {}", e); | ||
| // Sleep briefly before retrying | ||
| tokio::time::sleep(Duration::from_millis(100)).await; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| println!("Listener is stopping."); | ||
| // The socket will be dropped here | ||
| }); | ||
| }); | ||
|
Comment on lines
+277
to
+405
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Avoid creating a new Tokio runtime inside a thread In the Windows implementation, a new Apply this refactor to optimize runtime usage:
Example using #[cfg(target_os = "windows")]
pub fn spawn_listener(
network: Network,
endpoint: &str,
sender: mpsc::Sender<(ZMQMessage, Network)>,
tx_zmq_status: Option<Sender<ZMQConnectionEvent>>,
) -> Result<Self, Box<dyn Error>> {
let should_stop = Arc::new(AtomicBool::new(false));
let endpoint = endpoint.to_string();
let should_stop_clone = Arc::clone(&should_stop);
let sender_clone = sender.clone();
tokio::spawn(async move {
// Async listener code here...
while !should_stop_clone.load(Ordering::SeqCst) {
// Receive and handle messages...
}
});
Ok(CoreZMQListener {
should_stop,
handle: None, // No thread handle needed
})
}This refactor simplifies the code and aligns with best practices for asynchronous Rust applications. |
||
|
|
||
| Ok(CoreZMQListener { | ||
| should_stop, | ||
| handle: Some(handle), | ||
| }) | ||
| } | ||
|
|
||
|
Comment on lines
+277
to
+412
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Reduce code duplication in The Apply this refactor to reduce duplication:
Example: pub fn spawn_listener(
network: Network,
endpoint: &str,
sender: mpsc::Sender<(ZMQMessage, Network)>,
tx_zmq_status: Option<Sender<ZMQConnectionEvent>>,
) -> Result<Self, Box<dyn Error>> {
// Common setup code here...
#[cfg(not(target_os = "windows"))]
{
// Non-Windows specific code...
}
#[cfg(target_os = "windows")]
{
// Windows-specific code...
}
// Common code to finalize and return...
}This approach minimizes duplication and simplifies future updates. |
||
| /// Stops the listener by signaling the thread and waiting for it to finish. | ||
| pub fn stop(&mut self) { | ||
| self.should_stop.store(true, Ordering::SeqCst); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.