Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BOOTSTRAP_PVT_KEY=308204bd020100300d06092a864886f70d0101010500048204a7308204a30201000282010100d31f4fc9f46fa664ce46637ecda1e415d45dd471f0c8c7f6f921c9375a1cb97d121c0322e376d1dca942fafd284c25d71b917ce68b3379057e2a270ae38395624306ec2149eb58fd6eef50bc99819d59fbcfafc337d89109d75be8715a6c0857a5efc7ec51d6d248ab08a9da9568ff953df3248f7d88788e572eb78b3391078837fa3d1513523d85c8534ca9c3887ba057bb730511028866c6d9eab8be11503280f9239a718c39725e9c6efac75fcc99924ef32ef613178403054517628616604eeb6d949b5e45b8d367193b3266fb4a747386bc9e7062bfbbd1ce34fa3459c702dad13e81a8717c74214fdc2a8926404aefeb4e05cf9eb1e3f40a878f1d4c9702030100010282010059932969485aaec08a7c76ee7014c60f35017287bd5f92e8089ffb1d8f102ceb11e9ecb2bacbc912d485e4b3d08b2e6aebf97882e080c052424b64314c82a1b9053344b0830a65c17175fc4d68dc0385103ff814ddf6f6e2b40afcbe4b5d16d5094489108d5095fbdb055bfbaff4d2abe192edea2b9ae17b9325f11e108cf222660dd7e57732524151df3a56f214c83bcbb445b9f198b0eb73390252c92ab486d925977122412361d4f6750c1dab32dacbbdb03a39986a672f814890bd9c7d962a647c0bc8248ab166e36ca262d8c715195df7b2a861d00707b50509497130143fb48ebf9c8f274c205f0b04760b2d82e77e60ccb128372c3e24b1a22879e71102818100ddb06ab74e6c46ba35f6f2a0fea07fe3b31118dcf31c62e90d20c17f9369e5dd78331098746c2d5b2e3f3a3f4731417e11b2057a0c20a13e16ed69d60c988fcf978a420983308c5334bcfb7d412600649a55047cee9b86e0597cea69ec47494e5c1330026faa15b060867956db955d095bc6ed7affedc20377f425467887ede302818100f3cc39a267610fdbe73443963c0fa486b61572f9d047f8b56ca419b3ea10984bbd12982f36f0bf300fe6171e5ae6b55443dcf3ac63dfc10d9d803da32084987e69e8ab62663ac5836f4c449d3a0c9d02764f2f0889cdbf61252017918b97a644c3caaea808a6a84ae90f327b35499895967394bf8ac7f3954ffbfe7446b264bd02818100d10a97b67e26af92cb6c2f620c787fdfd06ca0cb481b4e517fe59150a14acc4c4819aede7379c653228ad07bf6bfc588015ba2ba71511b7a96d80c62a0c20369b6f5d24b71ff8772b65a35b2e889d2f90a667cb2e9b4923c5f65e10d3c9603d3f612c9c4a252f9dcb5485886c4cc554c8bd44aff1ef1ad6ee3dfbe7e730d8a0d0281804d29fba7fa7e8f2d73fd67d2fa499d32821941ddeddd89cbaa8a3a1466e63fbde1272c81ed2abfe8af6f8d2baf6bcc42d283f1a043b0438352b18f50bd6f1a71108673105ef90520f7ae351d6a8d2978e90761049bd1425cb60a754b3cda8fe6bdedbde03374c4598970a4f2b84806027aaf348a779b97ee4f759bf1239b3d250281801a21da15b58bff6a52f660bf7ecb3d93cefd49f247caf333191ba56f1ecc0493cd9d73d58f142d91bef3d60efd58a7fe1e70f231407777bd1bd6f44e8233c9b4ce37bcb757b107a18d0d24b590f7272dd011c601edd0d92823d5968a397f4d66f1a905572a39910481e7a963b4bc65b323bf8c74fcabad7a25a8e48d54c2aa09
BOOTSTRAP_NODE=/ip4/127.0.0.1/tcp/8888/p2p/6wrGkCFmUe2H8c23pCfPcXktZztSu2eckvqaWP6y4E2w
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/target
Cargo.lock
Cargo.lock
.env
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace]
members = ["examples/inference", "core"]
members = ["examples/raw", "examples/agentic", "inode"]


resolver = "2"
Expand All @@ -9,6 +9,7 @@ rust-version = "1.90.0"
edition = "2021"

[workspace.dependencies]
rnet-p2p = { git = "https://github.com/rnet-stack/rnet-p2p.git" }
tokio = { version = "1", features = ["full"] }
anyhow = "1"
async-trait = "0.1"
Expand All @@ -23,6 +24,8 @@ unsigned-varint = "0.7"
prost = "0.13"
x25519-dalek = "2"
chacha20poly1305 = { version = "0.10.1" }
dotenvy = "0.15.7"
rand = "0.10.1"

[workspace.lints]
clippy.pedantic = { level = "allow", priority = -1 }
Expand Down
Empty file removed core/src/agent/mod.rs
Empty file.
Empty file removed core/src/p2p/mod.rs
Empty file.
2 changes: 1 addition & 1 deletion core/Cargo.toml → examples/agentic/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "core"
name = "agentic"
version = "0.1.0"
edition = "2021"

Expand Down
File renamed without changes.
24 changes: 24 additions & 0 deletions examples/raw/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "raw"
version = "0.1.0"
edition = "2021"

[[bin]]
name = "raw"
path = "src/main.rs"

[dependencies]
tokio = { workspace = true }
anyhow = { workspace = true }
async-trait = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
rsa = { workspace = true }
sha2 = { workspace = true }
serde = { workspace = true }
bincode = { workspace = true }
x25519-dalek = { workspace = true }
chacha20poly1305 = { workspace = true }
dotenvy = { workspace = true }

inode = { path = "../../inode" }
33 changes: 33 additions & 0 deletions examples/raw/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use std::io::{self, Write};

use anyhow::Result;
use inode::p2p::{cmds::io_loop, node::InferenceNode, types::Mode};
use tracing_subscriber::EnvFilter;

#[tokio::main]
async fn main() -> Result<()> {
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::new("trace"))
.without_time()
.with_target(false)
.compact()
.init();

dotenvy::dotenv().ok();

print!("Intiate at BOOTSTRAP node (Y/n): ");
io::stdout().flush().unwrap();

let mut io = String::new();
io::stdin().read_line(&mut io).unwrap();

let mut mode = Mode::Bootstrap;
if io.trim().to_lowercase() != "" {
mode = Mode::Provider;
}

let inode = InferenceNode::new(mode).await;
io_loop(inode).await.unwrap();

Ok(())
}
7 changes: 6 additions & 1 deletion examples/inference/Cargo.toml → inode/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
[package]
name = "inference"
name = "inode"
version = "0.1.0"
edition = "2021"

[dependencies]
rnet-p2p = { workspace = true }

tokio = { workspace = true }
anyhow = { workspace = true }
async-trait = { workspace = true }
Expand All @@ -14,3 +16,6 @@ serde = { workspace = true }
bincode = { workspace = true }
x25519-dalek = { workspace = true }
chacha20poly1305 = { workspace = true }
dotenvy = { workspace = true }
rand = { workspace = true }
hex = { workspace = true }
1 change: 1 addition & 0 deletions inode/src/agent/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod tools;
3 changes: 3 additions & 0 deletions inode/src/agent/tools.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub struct Tools {}

impl Tools {}
24 changes: 24 additions & 0 deletions inode/src/common/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
use rand::{distr::Alphanumeric, rng, RngExt};
use sha2::{Digest, Sha256};
use std::time::{SystemTime, UNIX_EPOCH};

pub fn unix_epoch() -> u64 {
let now = SystemTime::now();
let duration = now.duration_since(UNIX_EPOCH).unwrap();

duration.as_secs()
}

pub fn generate_entropy() -> (String, String) {
let secret: String = rng()
.sample_iter(&Alphanumeric)
.take(16)
.map(char::from)
.collect();

let mut hasher = Sha256::new();
hasher.update(secret.as_bytes());
let hash = hex::encode(hasher.finalize());

(secret, hash)
}
2 changes: 1 addition & 1 deletion core/src/lib.rs → inode/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@

pub mod agent;
pub mod common;
pub mod p2p;
163 changes: 163 additions & 0 deletions inode/src/p2p/cmds.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
use anyhow::Result;
use rnet_p2p::identity::multiaddr::Multiaddr;
use rnet_p2p::identity::traits::{
core::INode,
protocols::{INodeFloodsubAPI, INodePingAPI},
};
use std::collections::HashMap;
use std::{io::Write, sync::Arc, time::Duration};
use tokio::io::{self, AsyncBufReadExt};

use crate::p2p::node::InferenceNode;
use crate::p2p::types::IMsgType;

const CLI_DELAY: Duration = Duration::from_nanos(1000);
const FLOODSUB: &str = "rnet/floodsub/0.0.1";
const COMMANDS: &[&str] = &[
"help => print all the commands",
"local => get local peer-info",
"connect <maddr> => connect with a new peer",
"ping <maddr> <count> => exchange ping with a peer",
"peers => list the connected peers",
"\n",
"fsub <maddr> => open a new floodsub stream with the peer",
"join <topic> => subscribe to a new-topic",
"leave <topic> => unsubscribe to a new-topic",
"publish <topic> <msg> => publish a msg to a topic",
"topics => list the subscribed topics",
"fpeers => list the connected Floodsub peers",
"bootmesh => map of topics -> peer (BOOTSTRAP)",
"mesh => map of topics -> peer",
"\n",
];

pub fn print_commands() {
for cmd in COMMANDS {
println!(" {}", cmd);
}
}

pub async fn handle_cmd(line: &str, inode: &Arc<InferenceNode>) -> Result<()> {
let mut parts = line.split_whitespace();
let cmd = parts.next().unwrap();

match cmd {
"help" => {
print_commands();
}

"local" => {
let peer_info = inode.local.clone();
println!("{}", peer_info);
}

"connect" => {
let maddr = Multiaddr::new(parts.next().unwrap()).unwrap();
inode.p2p.connect(&maddr).await?;
tokio::time::sleep(Duration::from_millis(300)).await;
}

"ping" => {
let maddr = parts.next().unwrap();
let count: u32 = parts.next().unwrap_or("0").parse().unwrap_or(0);
inode.p2p.ping(Some(count), maddr).await.unwrap();
}

"fsub" => {
let maddr = parts.next().unwrap();
inode
.p2p
.new_stream(maddr, vec![FLOODSUB.to_string()])
.await
.unwrap();
tokio::time::sleep(Duration::from_millis(300)).await;
}

"join" => {
let topic = parts.next().unwrap().to_string();
inode.p2p.floodsub_subscribe(topic).await.unwrap();
}

"leave" => {
let topic = parts.next().unwrap().to_string();
inode.p2p.floodsub_unsubscribe(vec![topic]).await.unwrap();
}

"publish" => {
let topic = parts.next().unwrap().to_string();
let msg = parts.collect::<Vec<_>>().join(" ");

// Wrap this into IMsgType::General
let mpc_general = IMsgType::General(msg);
let payload = bincode::serialize(&mpc_general).unwrap();

inode.p2p.floodsub_publish(topic, payload).await.unwrap();
}

"topics" => {
let topics = inode.p2p.floodsub_topics().await.unwrap_or(vec![]);
println!("{:?}", topics);
}

"fpeers" => {
let fpeers = inode.p2p.floodsub_peers().await.unwrap_or(vec![]);
fpeers.iter().for_each(|x| {
println!("{}", x);
});
}

"bootmesh" => {
let bootmesh = inode.bootmesh.lock().await.clone();

bootmesh.iter().for_each(|(topic, peers)| {
println!("- {}", topic);
peers.iter().for_each(|peer| println!(" - {}", peer));
});
}

"peers" => {
let gpeers = inode.p2p.get_peers().await;
gpeers.iter().for_each(|peer| println!("{}", peer));
}

"mesh" => {
let mesh = inode.p2p.floodsub_mesh().await.unwrap_or(HashMap::new());

mesh.iter().for_each(|(topic, peers)| {
println!("- {}", topic);
peers.iter().for_each(|peer| println!(" - {}", peer));
});
}

_ => println!("Unknown command"),
}
Ok(())
}

pub async fn io_loop(inode: Arc<InferenceNode>) -> Result<()> {
let stdin = io::BufReader::new(io::stdin());
let mut lines = stdin.lines();

println!("\n inode CLI ready. Commands:");
print_commands();

loop {
print!("\nCommand => ");
std::io::stdout().flush().unwrap();

let line = match lines.next_line().await? {
Some(line) => line,
None => break,
};

let line = line.trim();
if line.is_empty() {
continue;
}

handle_cmd(line, &inode).await?;
tokio::time::sleep(CLI_DELAY).await;
}

Ok(())
}
4 changes: 4 additions & 0 deletions inode/src/p2p/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub mod cmds;
pub mod node;
pub mod service;
pub mod types;
Loading
Loading