koibumi_node/
lib.rs

1//! This crate is a Bitmessage node implementation as a library for Koibumi, an experimental Bitmessage client.
2//!
3//! See [`koibumi`](https://crates.io/crates/koibumi) for more about the application.
4//! See [Bitmessage](https://bitmessage.org/) for more about the protocol.
5//!
6//! # Examples
7//!
8//! ```no_run
9//! use std::str::FromStr;
10//!
11//! use async_std::task;
12//! use futures::{sink::SinkExt, stream::StreamExt};
13//!
14//! use koibumi_node::{self as node, db, Command, Config, Event, Response};
15//!
16//! let (command_sender, mut response_receiver, handle) = node::spawn();
17//!
18//! let config = Config::builder()
19//!     .server(Some("127.0.0.1:8444".parse().unwrap()))
20//!     .socks(Some("127.0.0.1:9050".parse().unwrap()))
21//!     .connect_to_onion(true)
22//!     .connect_to_ip(true)
23//!     .seeds(vec!["quzwelsuziwqgpt2.onion:8444".parse().unwrap()])
24//!     .build();
25//!
26//! let mut sender = command_sender;
27//! let response = task::block_on(async {
28//!     let pool = db::SqlitePool::connect_with(
29//!         sqlx::sqlite::SqliteConnectOptions::from_str("sqlite::memory:").unwrap()
30//!     ).await;
31//!     if let Err(err) = pool {
32//!         eprintln!("{}", err);
33//!         return None;
34//!     }
35//!     let pool = pool.unwrap();
36//!
37//!     if let Err(err) = sender.send(Command::Start(config.into(), pool, Vec::new())).await {
38//!         eprintln!("{}", err);
39//!         return None;
40//!     }
41//!     response_receiver.next().await
42//! });
43//! let Response::Started(mut receiver) = response.unwrap();
44//!
45//! task::block_on(async {
46//!     while let Some(event) = receiver.next().await {
47//!         match event {
48//!             Event::ConnectionCounts { .. } => (),
49//!             Event::AddrCount(_count) => (),
50//!             Event::Established { addr, user_agent, rating } => {
51//!                 println!("established: {} {} rating:{}", addr, user_agent, rating);
52//!             }
53//!             Event::Disconnected { addr } => {
54//!                 println!("disconnected: {}", addr);
55//!             }
56//!             Event::Objects { .. } => (),
57//!             Event::Stopped => {
58//!                 break;
59//!             }
60//!             Event::Broadcast {
61//!                 user_id,
62//!                 address,
63//!                 object,
64//!             } => {
65//!                 println!("broadcast received from {}", address);
66//!             }
67//!             Event::Msg {
68//!                 user_id,
69//!                 address,
70//!                 object,
71//!             } => {
72//!                 println!("received msg for {}", address);
73//!             }
74//!         }
75//!     }
76//!
77//!     handle.await;
78//! });
79//! ```
80
81#![deny(unsafe_code)]
82#![warn(missing_docs)]
83#![recursion_limit = "2048"]
84
85mod config;
86mod connection;
87mod connection_loop;
88mod constant;
89pub mod db;
90mod inv_manager;
91mod manager;
92mod message_handler;
93mod net;
94mod node_manager;
95mod object_processor;
96mod pow_manager;
97mod user_manager;
98
99pub use config::{Builder as ConfigBuilder, Config, SocksAuth};
100pub use manager::{run, Command, Event, Response};
101pub use net::SocketAddrNode;
102pub use node_manager::Rating;
103pub use user_manager::User;
104
105use async_std::task;
106use futures::channel::mpsc::{self, Receiver, Sender};
107
108/// Spawns a task that manage a Bitmessage node.
109pub fn spawn() -> (Sender<Command>, Receiver<Response>, task::JoinHandle<()>) {
110    const COMMAND_BUFFER: usize = 0x10000;
111    const RESPONSE_BUFFER: usize = 0x10000;
112    let (command_sender, command_receiver) = mpsc::channel(COMMAND_BUFFER);
113    let (response_sender, response_receiver) = mpsc::channel(RESPONSE_BUFFER);
114    let handle = task::spawn(manager::run(command_receiver, response_sender));
115    (command_sender, response_receiver, handle)
116}