| 
					
				 | 
			
			
				@@ -1,72 +1,94 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 //! Code which enables sending messages between processes in the blocktree system. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-use btlib::{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Result, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    crypto::rand_array, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    BlockPath, Writecap, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use btlib::{crypto::rand_array, error::BoxInIoErr, BlockPath, Result, Writecap}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use btserde::{read_from, write_to}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use bytes::{BufMut, BytesMut}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use core::{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    future::Future, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pin::Pin, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    task::{Context, Poll}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-use std::{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    path::PathBuf, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    io::{Read, Write}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    os::unix::net::{UnixStream, UnixListener},  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use futures::{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    sink::{Send, Sink}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    stream::Stream, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SinkExt, StreamExt, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-use btserde::{read_from, write_to}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use lazy_static::lazy_static; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 use serde::{Deserialize, Serialize}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use std::{io, net::Shutdown, path::PathBuf}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use tokio::{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    io::{AsyncRead, AsyncWrite, ReadBuf}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    net::UnixDatagram, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use tokio_util::codec::{Decoder, Encoder, FramedRead, FramedWrite}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 use zerocopy::FromBytes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 pub use private::*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 mod private { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    use std::io; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     use super::*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    /// The directory where sockets are created. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    fn socket_dir() -> PathBuf { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let home_dir: PathBuf = std::env::var("HOME").unwrap().into(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        home_dir.join(".btmsg") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    lazy_static! { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// The default directory in which to place blocktree sockets. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        static ref SOCK_DIR: PathBuf = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let mut path: PathBuf = std::env::var("HOME").unwrap().into(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            path.push(".btmsg"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            path 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pub fn socket_path(block_path: &BlockPath) -> PathBuf { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        socket_dir().join(block_path.to_string()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// Appends the given Blocktree path to the path of the given directory. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fn socket_path(fs_path: &mut PathBuf, block_path: &BlockPath) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fs_path.push(block_path.to_string()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #[derive(PartialEq, Eq, Serialize, Deserialize)] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pub enum MsgError {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pub enum MsgError { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Unknown, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// The owned version of a message body. This is the body type for received messages. It's 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// very important that this enum's variants match those of [MsgBodyRef], otherwise runtime 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// deserialization errors will occur. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #[derive(Deserialize)] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     pub enum MsgBodyOwned { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Success, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Fail(MsgError), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Ping, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Hello(Writecap), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Read { offset: u64, size: u64, }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Read { offset: u64, size: u64 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Write { offset: u64, buf: Vec<u8> }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Custom(Vec<u8>), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// The reference version of a message body. This is the body type when sending messages. It's 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// very important that this enum's variants match those of [MsgBodyOwned], otherwise runtime 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// deserialization errors will occur. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #[derive(Serialize)] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     pub enum MsgBodyRef<'a> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Success, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Fail(&'a MsgError), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Ping, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Hello(&'a Writecap), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Read { offset: u64, buf: &'a [u8] }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        Write { offset: u64, buf: &'a mut [u8] }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Read { offset: u64, size: u64 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Write { offset: u64, buf: &'a [u8] }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Custom(&'a [u8]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// Trait which unifies owned and borrowed messages. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     pub trait Msg { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         type Body; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fn from(&self) -> &BlockPath; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         fn to(&self) -> &BlockPath; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn from(&self) -> &BlockPath; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         fn id(&self) -> u128; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         fn body(&self) -> &Self::Body; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// An owned message. This is the type which observed by the receiver. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #[derive(Deserialize)] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     pub struct MsgOwned { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        from: BlockPath, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         to: BlockPath, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        from: BlockPath, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         id: u128, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         body: MsgBodyOwned, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -74,14 +96,14 @@ mod private { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     impl Msg for MsgOwned { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         type Body = MsgBodyOwned; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fn from(&self) -> &BlockPath { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            &self.from 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         fn to(&self) -> &BlockPath { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             &self.to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn from(&self) -> &BlockPath { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            &self.from 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         fn id(&self) -> u128 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             self.id 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -91,23 +113,30 @@ mod private { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// A borrowed message. This is the type which is produced by the sender. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #[derive(Serialize)] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     pub struct MsgRef<'a> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        from: &'a BlockPath, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         to: &'a BlockPath, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        from: &'a BlockPath, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         id: u128, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         body: MsgBodyRef<'a>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    impl<'a> MsgRef<'a> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        pub fn new(to: &'a BlockPath, from: &'a BlockPath, id: u128, body: MsgBodyRef<'a>) -> Self { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Self { to, from, id, body } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     impl<'a> Msg for MsgRef<'a> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         type Body = MsgBodyRef<'a>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         fn to(&self) -> &BlockPath { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            &self.to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         fn from(&self) -> &BlockPath { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            &self.from 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.from 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         fn id(&self) -> u128 { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -119,185 +148,394 @@ mod private { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// An owned message tagged with a version. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #[derive(Deserialize)] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pub enum VerMsg { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    enum VerMsgOwned { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         V0(MsgOwned), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// A borrowed message tagged with a version. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #[derive(Serialize)] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pub enum VerMsgRef<'a> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    enum VerMsgRef<'a> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         V0(MsgRef<'a>), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pub trait Sender: Send { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fn send<'a>(&mut self, msg: MsgRef<'a>) -> Result<()>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// A type which can be used to send messages. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pub trait Sender<'a>: Sink<MsgRef<'a>, Error = btlib::Error> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type SendFut: Future<Output = Result<()>> + std::marker::Send; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         fn path(&self) -> &BlockPath; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// Creates a new message with the given `from` and `body` fields and sends it to the peer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /// this [Sender] is associated with. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn send_msg(&'a mut self, from: &'a BlockPath, body: MsgBodyRef<'a>) -> Self::SendFut; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /// Generates and returns a new message ID. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fn gen_id(&mut self) -> Result<u128> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn gen_id() -> Result<u128> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             const LEN: usize = std::mem::size_of::<u128>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let bytes = rand_array::<LEN>()?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             let option = u128::read_from(bytes.as_slice()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // Safety: because LEN == size_of::<u128>(), read_from should have returned Some. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             Ok(option.unwrap()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// A type which can be used to receive messages. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pub trait Receiver: Stream<Item = Result<MsgOwned>> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn path(&self) -> &BlockPath; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// Encodes and decodes messages using [btserde]. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    struct MessageCodec; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    impl<'a> Encoder<MsgRef<'a>> for MessageCodec { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type Error = btlib::Error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn encode(&mut self, item: MsgRef<'a>, dst: &mut BytesMut) -> Result<()> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            const U64_LEN: usize = std::mem::size_of::<u64>(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let payload = dst.split_off(U64_LEN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let mut writer = payload.writer(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            write_to(&VerMsgRef::V0(item), &mut writer)?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let payload = writer.into_inner(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let payload_len = payload.len() as u64; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let mut writer = dst.writer(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            write_to(&payload_len, &mut writer)?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let dst = writer.into_inner(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            dst.unsplit(payload); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    impl Decoder for MessageCodec { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type Item = MsgOwned; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type Error = btlib::Error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fn send_new<'a>(&mut self, to: &BlockPath, from: &BlockPath, body: MsgBodyRef<'a>) -> Result<()> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let id = self.gen_id()?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let msg = MsgRef { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                to, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                from, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                body, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let mut slice: &[u8] = src.as_ref(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let payload_len: u64 = match read_from(&mut slice) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Ok(payload_len) => payload_len, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                Err(err) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if let btserde::Error::Eof = err { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        return Ok(None); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return Err(err.into()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            self.send(msg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let payload_len: usize = payload_len.try_into().box_err()?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if slice.len() < payload_len { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                src.reserve(payload_len - slice.len()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return Ok(None); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let VerMsgOwned::V0(msg) = read_from(&mut slice)?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let _ = src.split_to(std::mem::size_of::<u64>() + payload_len); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Some(msg)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pub trait Receiver { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fn receive(&mut self) -> Result<MsgOwned>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fn path(&self) -> &BlockPath; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// Wraps a [UnixDatagram] and implements [AsyncRead] and [AsyncWrite] for it. Read operations 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// are translated  to calls to `recv_from` and write operations are translated to `send`. Note 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// that this means that writes will fail unless the wrapped socket is connected  to a peer. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    struct DatagramAdapter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        socket: UnixDatagram, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pub trait Channel: Sized + Receiver { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        type Sender: Sender; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    impl DatagramAdapter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn new(socket: UnixDatagram) -> Self { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Self { socket } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn get_ref(&self) -> &UnixDatagram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            &self.socket 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fn new(receiver_path: BlockPath) -> Result<Self>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fn connect_to(receiver_path: BlockPath) -> Result<Self::Sender>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn get_mut(&mut self) -> &mut UnixDatagram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            &mut self.socket 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pub struct WriteSender<W> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        write: W, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        path: BlockPath, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    impl AsRef<UnixDatagram> for DatagramAdapter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn as_ref(&self) -> &UnixDatagram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.get_ref() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    impl<W> WriteSender<W> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        pub fn new(write: W, path: BlockPath) -> Self { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Self { write, path } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    impl AsMut<UnixDatagram> for DatagramAdapter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn as_mut(&mut self) -> &mut UnixDatagram { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.get_mut() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    impl<W: Write + Send> Sender for WriteSender<W> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fn send<'a>(&mut self, msg: MsgRef<'a>) -> Result<()> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Ok(write_to(&VerMsgRef::V0(msg), &mut self.write)?) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    impl AsyncRead for DatagramAdapter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn poll_read( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self: Pin<&mut Self>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cx: &mut Context<'_>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            buf: &mut ReadBuf<'_>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ) -> Poll<io::Result<()>> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.socket.poll_recv(cx, buf) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fn path(&self) -> &BlockPath { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            &self.path 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    impl AsyncWrite for DatagramAdapter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn poll_write( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self: Pin<&mut Self>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            cx: &mut Context<'_>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            buf: &[u8], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ) -> Poll<io::Result<usize>> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.socket.poll_send(cx, buf) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn poll_shutdown(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Poll::Ready(self.socket.shutdown(Shutdown::Write)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<io::Result<()>> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Poll::Ready(Ok(())) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// Returns a [Receiver] which can be used to receive messages addressed to the given path. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// The `fs_path` argument specifies the filesystem directory under which the receiver's socket 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// will be stored. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pub fn local_receiver(fs_path: PathBuf, block_path: BlockPath) -> Result<impl Receiver> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        UnixReceiver::new(fs_path, block_path) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pub struct ReadReceiver<R> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        read: R, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// An implementation of [Receiver] which uses a Unix datagram socket for receiving messages. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    struct UnixReceiver { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         path: BlockPath, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        socket: FramedRead<DatagramAdapter, MessageCodec>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    impl<R> ReadReceiver<R> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        pub fn new(read: R, path: BlockPath) -> Self { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Self { read, path } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    impl UnixReceiver { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn new(mut fs_path: PathBuf, block_path: BlockPath) -> Result<Self> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            socket_path(&mut fs_path, &block_path); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            std::fs::create_dir_all(fs_path.parent().unwrap())?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let socket = DatagramAdapter::new(UnixDatagram::bind(fs_path)?); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let socket = FramedRead::new(socket, MessageCodec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Self { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                path: block_path, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                socket, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    impl<R: Read> Receiver for ReadReceiver<R> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fn receive(&mut self) -> Result<MsgOwned> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let VerMsg::V0(msg) = read_from(&mut self.read)?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Ok(msg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    impl Stream for UnixReceiver { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type Item = Result<MsgOwned>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.socket.poll_next_unpin(cx) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    impl Receiver for UnixReceiver { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         fn path(&self) -> &BlockPath { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             &self.path 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pub struct UnixChannel { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        receiver_path: BlockPath, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        listener: UnixListener, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        streams: Vec<ReadReceiver<UnixStream>>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        next: usize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// Returns a [Sender] which can be used to send messages to the given Blocktree path. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// The `fs_path` argument specifies the filesystem directory in which to locate the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// socket of the recipient. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pub fn local_sender( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fs_path: PathBuf, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        block_path: BlockPath, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ) -> Result<impl for<'a> Sender<'a>> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        UnixSender::new(fs_path, block_path) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    impl Receiver for UnixChannel { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fn path(&self) -> &BlockPath { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            &self.receiver_path 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// An implementation of [Sender] which uses a Unix datagram socket to send messages. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    struct UnixSender { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        path: BlockPath, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        socket: FramedWrite<DatagramAdapter, MessageCodec>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    impl UnixSender { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn new(mut fs_path: PathBuf, block_path: BlockPath) -> Result<Self> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let socket = UnixDatagram::unbound()?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            socket_path(&mut fs_path, &block_path); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            socket.connect(fs_path)?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let socket = FramedWrite::new(DatagramAdapter::new(socket), MessageCodec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(Self { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                path: block_path, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                socket, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fn receive(&mut self) -> Result<MsgOwned> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // Note that the listener is put in non-blocking mode when it is created. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            match self.listener.accept() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Ok((socket, ..)) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    self.streams.push(ReadReceiver::new(socket, self.receiver_path.clone())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                Err(err) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    // If the error is anything other than `WouldBlock`, then it is unexpected. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    if io::ErrorKind::WouldBlock != err.kind() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        return Err(err.into()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let receiver = self.streams.get_mut(self.next).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            self.next += 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            receiver.receive() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    impl Sink<MsgRef<'_>> for UnixSender { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type Error = btlib::Error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.socket.poll_ready_unpin(cx) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn start_send(mut self: Pin<&mut Self>, item: MsgRef<'_>) -> Result<()> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.socket.start_send_unpin(item) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.socket.poll_flush_unpin(cx) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.socket.poll_close_unpin(cx) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    impl Channel for UnixChannel { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        type Sender = WriteSender<UnixStream>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    impl<'a> Sender<'a> for UnixSender { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type SendFut = Send<'a, FramedWrite<DatagramAdapter, MessageCodec>, MsgRef<'a>>; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fn new(receiver_path: BlockPath) -> Result<Self> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let path = socket_path(&receiver_path); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            std::fs::create_dir_all(path.parent().unwrap())?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let listener = UnixListener::bind(&path)?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            listener.set_nonblocking(true)?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Ok(UnixChannel { receiver_path, listener, streams: Vec::new(), next: 0 }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn path(&self) -> &BlockPath { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            &self.path 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fn connect_to(receiver_path: BlockPath) -> Result<Self::Sender> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let path = socket_path(&receiver_path); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let stream = UnixStream::connect(&path)?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let sender = WriteSender::new(stream, receiver_path); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Ok(sender) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn send_msg(&'a mut self, from: &'a BlockPath, body: MsgBodyRef<'a>) -> Self::SendFut { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let id = Self::gen_id().unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let msg = MsgRef::new(&self.path, from, id, body); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.socket.send(msg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /// Returns a connected [Sender] and [Receiver]. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pub fn local_pair( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dir: PathBuf, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        block_path: BlockPath, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ) -> Result<(impl for<'a> Sender<'a>, impl Receiver)> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let receiver = local_receiver(dir.clone(), block_path.clone())?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let sender = local_sender(dir, block_path)?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        Ok((sender, receiver)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #[cfg(test)] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 mod tests { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     use super::*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //#[test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //fn ping_pong_via_pipes() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //    let ping_path = test_helpers::make_path(vec!["ping"]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //    let (mut ping_sender, mut ping_receiver) = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //        PipeChannel::new(ping_path.clone()).expect("failed to create a ping channel"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //    let pong_path = test_helpers::make_path(vec!["pong"]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //    let (mut pong_sender, mut pong_receiver) = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //        PipeChannel::new(pong_path.clone()).expect("failed to create a pong channel"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //    let pong = std::thread::spawn(move || loop { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //        let msg = pong_receiver.receive().expect("pong receive failed"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //        assert_eq!(pong_receiver.path(), msg.to()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //        match msg.body() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //            MsgBody::Ping => ping_sender 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //                .send_new(ping_path.clone(), MsgBody::Success) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //                .expect("send to ping failed"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //            MsgBody::Success => return, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //            _ => panic!("unexpected message received by pong"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //    let mut iter = 5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //    while iter > 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //        pong_sender 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //            .send_new(pong_path.clone(), MsgBody::Ping) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //            .expect("send to pong failed"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //        let msg = ping_receiver.receive().expect("ping receive failed"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //        assert_eq!(ping_receiver.path(), msg.to()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //        match msg.body() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //            MsgBody::Success => iter -= 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //            _ => panic!("unexpected message received by ping"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //    pong_sender 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //        .send_new(pong_path.clone(), MsgBody::Success) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //        .expect("send success to pong failed"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //    pong.join().expect("join failed"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    //} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    use tempdir::TempDir; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    lazy_static! { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        static ref BT_ROOT: BlockPath = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            BlockPath::try_from("0!dSip4J0kurN5VhVo_aTipM-ywOOWrqJuRRVQ7aa-bew").unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fn block_path<'a, I: Iterator<Item = &'a str>>(components: I) -> BlockPath { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let mut path = BT_ROOT.clone(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for component in components { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            path.push_component(component.to_string()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        path 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    struct TestCase { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dir: TempDir, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    impl TestCase { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn new() -> TestCase { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Self { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                dir: TempDir::new("btmsg").unwrap(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fn endpoint(&self, name: &str) -> (BlockPath, impl for<'a> Sender<'a>, impl Receiver) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let block_path = block_path(["apps", name].into_iter()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let (sender, receiver) = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                local_pair(self.dir.path().to_owned(), block_path.clone()).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (block_path, sender, receiver) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[tokio::test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async fn message_received_is_message_sent() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let case = TestCase::new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let (block_path, mut sender, mut receiver) = case.endpoint("social"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sender 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .send_msg(&block_path, MsgBodyRef::Ping) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let actual = receiver.next().await.unwrap().unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let matched = if let MsgBodyOwned::Ping = actual.body() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert!(matched); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!(&block_path, actual.to()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!(&block_path, actual.from()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[tokio::test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async fn ping_pong() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let case = TestCase::new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let (block_path_one, mut sender_one, mut receiver_one) = case.endpoint("one"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let (block_path_two, mut sender_two, mut receiver_two) = case.endpoint("two"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let handle = tokio::spawn(async move { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let msg = receiver_one.next().await.unwrap().unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let reply_body = if let MsgBodyOwned::Ping = msg.body() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                MsgBodyRef::Success 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                MsgBodyRef::Fail(&MsgError::Unknown) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sender_two 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .send_msg(&block_path_one, reply_body) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sender_one 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .send_msg(&block_path_two, MsgBodyRef::Ping) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handle.await.unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let reply = receiver_two.next().await.unwrap().unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let matched = if let MsgBodyOwned::Success = reply.body() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert!(matched) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[tokio::test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    async fn read_write() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let case = TestCase::new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let (block_path_one, mut sender_one, mut receiver_one) = case.endpoint("one"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let (block_path_two, mut sender_two, mut receiver_two) = case.endpoint("two"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let handle = tokio::spawn(async move { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let data: [u8; 8] = [0, 1, 2, 3, 4, 5, 6, 7]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let msg = receiver_one.next().await.unwrap().unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            let reply_body = if let MsgBodyOwned::Read { offset, size } = msg.body() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let offset: usize = (*offset).try_into().unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let size: usize = (*size).try_into().unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                let end: usize = offset + size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                MsgBodyRef::Write { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    offset: offset as u64, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    buf: &data[offset..end], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                MsgBodyRef::Fail(&MsgError::Unknown) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sender_two 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .send_msg(&block_path_one, reply_body) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sender_one 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .send_msg(&block_path_two, MsgBodyRef::Read { offset: 2, size: 2 }) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .await 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        handle.await.unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let reply = receiver_two.next().await.unwrap().unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if let MsgBodyOwned::Write { offset, buf } = reply.body() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            assert_eq!(2, *offset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            assert_eq!([2, 3].as_slice(), buf.as_slice()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            panic!("replay was not the right type"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |