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}