Move iroh.proto to new crate
This commit is contained in:
parent
b461dc39a7
commit
d30188e7d9
21 changed files with 150 additions and 67 deletions
|
|
@ -26,7 +26,7 @@ caretta-sync-macros = { path="macros", optional = true}
|
|||
caretta-sync-core = {workspace = true, features = ["test"]}
|
||||
|
||||
[workspace]
|
||||
members = [ ".", "core", "macros", "cli", "mobile", "examples/*" , "bevy"]
|
||||
members = [ ".", "core", "macros", "cli", "mobile", "examples/*" , "bevy", "iroh-proto"]
|
||||
resolver = "3"
|
||||
|
||||
[workspace.package]
|
||||
|
|
@ -46,9 +46,15 @@ futures = { version = "0.3.31", features = ["executor"] }
|
|||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
thiserror = "2.0.12"
|
||||
tokio = { version = "1.45.0", features = ["macros", "rt", "rt-multi-thread"] }
|
||||
tokio-stream = "0.1.17"
|
||||
tonic = "0.14.0"
|
||||
url = { version = "2.5.7", features = ["serde"] }
|
||||
uuid = { version = "1.17.0", features = ["v7"] }
|
||||
iroh = { version = "0.91.2", features = ["discovery-local-network", "discovery-pkarr-dht"] }
|
||||
prost = "0.14.1"
|
||||
prost-types = "0.14.1"
|
||||
tonic-prost-build = "0.14.0"
|
||||
tonic-prost = "0.14.0"
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 1
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ ciborium.workspace = true
|
|||
clap = {workspace = true, optional = true}
|
||||
dirs = "6.0.0"
|
||||
futures.workspace = true
|
||||
iroh = { version = "0.91.2", features = ["discovery-local-network", "discovery-pkarr-dht"] }
|
||||
prost = "0.14.1"
|
||||
prost-types = "0.14.1"
|
||||
iroh.workspace = true
|
||||
prost.workspace = true
|
||||
prost-types.workspace = true
|
||||
rusqlite = { version = "0.37.0", features = ["bundled"] }
|
||||
serde.workspace = true
|
||||
sysinfo = "0.37.0"
|
||||
|
|
@ -51,4 +51,4 @@ objc2-app-kit = "0.3.1"
|
|||
tempfile = "3.20.0"
|
||||
|
||||
[build-dependencies]
|
||||
tonic-prost-build = "0.14.0"
|
||||
tonic-prost-build.workspace = true
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::ffi::OsString;
|
||||
use std::{array::TryFromSliceError, ffi::OsString};
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum Error {
|
||||
|
|
@ -23,6 +23,10 @@ pub enum Error {
|
|||
#[cfg(feature="cli")]
|
||||
#[error("Parse args error: {0}")]
|
||||
ParseCommand(#[from] clap::Error),
|
||||
#[error("Signature error: {0}")]
|
||||
Signature(#[from] ed25519_dalek::SignatureError),
|
||||
#[error("slice parse error: {0}")]
|
||||
SliceTryFrom(#[from] TryFromSliceError),
|
||||
#[error("toml deserialization error: {0}")]
|
||||
TomlDe(#[from] toml::de::Error),
|
||||
#[error("toml serialization error: {0}")]
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
use iroh::NodeId;
|
||||
|
||||
use crate::proto::iroh::RemoteInfoRequest;
|
||||
|
||||
impl From<NodeId> for RemoteInfoRequest {
|
||||
fn from(value: NodeId) -> Self {
|
||||
Self {
|
||||
node_id : value.to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1 @@
|
|||
pub mod iroh;
|
||||
|
||||
tonic::include_proto!("caretta_sync");
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
use crate::{global::{DATABASE_CONNECTION}, proto::CachedAddressMessage};
|
||||
use futures::future::join_all;
|
||||
use tonic::{Request, Response, Status};
|
||||
|
||||
use crate::proto::{cached_peer_service_server::{CachedPeerServiceServer}, CachedPeerListRequest, CachedPeerListResponse, CachedPeerMessage};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct CachedPeerService {}
|
||||
|
||||
|
||||
|
||||
#[tonic::async_trait]
|
||||
impl crate::proto::cached_peer_service_server::CachedPeerService for CachedPeerService {
|
||||
async fn list(&self, request: Request<CachedPeerListRequest>) -> Result<Response<CachedPeerListResponse>, Status> {
|
||||
println!("Got a request: {:?}", request);
|
||||
|
||||
let reply = CachedPeerListResponse {
|
||||
peers: join_all( CachedPeerEntity::find().all(DATABASE_CONNECTIONS.get_cache_unchecked()).await.or_else(|e| Err(Status::from_error(Box::new(e))))?.iter().map(|x| async move {
|
||||
let addresses = CachedAddressEntity::find()
|
||||
.all(DATABASE_CONNECTIONS.get_cache_unchecked())
|
||||
.await
|
||||
.or_else(|e| Err(Status::from_error(Box::new(e))))?;
|
||||
Ok::<CachedPeerMessage, Status>(CachedPeerMessage::from((x, &addresses)))
|
||||
})).await.into_iter().collect::<Result<Vec<_>,_>>()?,
|
||||
};
|
||||
|
||||
Ok(Response::new(reply))
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
pub mod cached_peer;
|
||||
pub mod iroh;
|
||||
21
iroh-proto/Cargo.toml
Normal file
21
iroh-proto/Cargo.toml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
[package]
|
||||
name = "iroh-proto"
|
||||
edition.workspace = true
|
||||
version = "0.1.0-alpha"
|
||||
description = "protobuf definition and tonic server implemention for fetch iroh server infomation"
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
[dependencies]
|
||||
ed25519-dalek = { version = "2.2.0", features = ["signature"] }
|
||||
futures.workspace = true
|
||||
iroh.workspace = true
|
||||
prost.workspace = true
|
||||
prost-types.workspace = true
|
||||
tokio-stream.workspace = true
|
||||
tonic.workspace = true
|
||||
tonic-prost.workspace = true
|
||||
thiserror.workspace = true
|
||||
|
||||
[build-dependencies]
|
||||
tonic-prost-build.workspace = true
|
||||
4
iroh-proto/build.rs
Normal file
4
iroh-proto/build.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
tonic_prost_build::compile_protos("proto/iroh.proto")?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -4,18 +4,22 @@ import "google/protobuf/timestamp.proto";
|
|||
import "google/protobuf/duration.proto";
|
||||
|
||||
service Iroh {
|
||||
rpc RemoteInfo(RemoteInfoRequest) returns (RemoteInfoMessage);
|
||||
rpc RemoteInfoIter(RemoteInfoIterRequest) returns (stream RemoteInfoMessage);
|
||||
rpc RemoteInfo(RemoteInfoRequest) returns (RemoteInfoResponse);
|
||||
rpc RemoteInfoIter(RemoteInfoIterRequest) returns (stream RemoteInfoResponse);
|
||||
}
|
||||
|
||||
message RemoteInfoRequest {
|
||||
string node_id = 1;
|
||||
bytes node_id = 1;
|
||||
}
|
||||
|
||||
message RemoteInfoIterRequest {}
|
||||
|
||||
message RemoteInfoResponse {
|
||||
RemoteInfoMessage remote_info = 1;
|
||||
}
|
||||
|
||||
message RemoteInfoMessage {
|
||||
string node_id = 1;
|
||||
bytes node_id = 1;
|
||||
string relay_url = 2;
|
||||
repeated DirectAddrInfoMessage addrs = 3;
|
||||
string conn_type = 4;
|
||||
9
iroh-proto/src/error.rs
Normal file
9
iroh-proto/src/error.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum Error {
|
||||
#[error("Duration parse error: {0}")]
|
||||
Duration(#[from] prost_types::DurationError),
|
||||
#[error("Signature error: {0}")]
|
||||
Signature(#[from] ed25519_dalek::SignatureError),
|
||||
#[error("slice parse error: {0}")]
|
||||
SliceTryFrom(#[from] std::array::TryFromSliceError)
|
||||
}
|
||||
3
iroh-proto/src/lib.rs
Normal file
3
iroh-proto/src/lib.rs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
pub mod error;
|
||||
pub mod proto;
|
||||
pub mod server;
|
||||
|
|
@ -1,18 +1,17 @@
|
|||
use iroh::endpoint::DirectAddrInfo;
|
||||
use prost_types::DurationError;
|
||||
|
||||
use crate::proto::iroh::{DirectAddrInfoMessage, SourceMessage};
|
||||
use crate::{error::Error, proto::{DirectAddrInfoMessage, LastControlMessage, SourceMessage}};
|
||||
|
||||
impl TryFrom<DirectAddrInfo> for DirectAddrInfoMessage {
|
||||
type Error = DurationError;
|
||||
type Error = Error;
|
||||
fn try_from(value: DirectAddrInfo) -> Result<Self, Self::Error> {
|
||||
Ok(DirectAddrInfoMessage {
|
||||
addr: value.addr.to_string(),
|
||||
latency: value.latency.map(|x| x.try_into()).transpose()?,
|
||||
last_control: value.last_control.map(|x| super::LastControlMessage::try_from(x)).transpose()?,
|
||||
last_control: value.last_control.map(|x| LastControlMessage::try_from(x)).transpose()?,
|
||||
last_payload: value.last_payload.map(|x| x.try_into()).transpose()?,
|
||||
last_alive: value.last_alive.map(|x| x.try_into()).transpose()?,
|
||||
sources: value.sources.into_iter().map(|x| SourceMessage::try_from(x)).collect::<Result<Vec<SourceMessage>, DurationError>>()?
|
||||
sources: value.sources.into_iter().map(|x| SourceMessage::try_from(x)).collect::<Result<Vec<SourceMessage>, Error>>()?
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ use std::time::Duration;
|
|||
use iroh::endpoint::ControlMsg;
|
||||
use prost_types::DurationError;
|
||||
|
||||
use crate::proto::iroh::LastControlMessage;
|
||||
use crate::proto::LastControlMessage;
|
||||
|
||||
impl TryFrom<(Duration, ControlMsg)> for LastControlMessage {
|
||||
type Error = DurationError;
|
||||
|
|
@ -3,6 +3,7 @@ mod last_control_message;
|
|||
mod remote_info_iter_request;
|
||||
mod remote_info_message;
|
||||
mod remote_info_request;
|
||||
mod remote_info_response;
|
||||
mod source_message;
|
||||
|
||||
tonic::include_proto!("iroh");
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::proto::iroh::RemoteInfoIterRequest;
|
||||
use crate::proto::RemoteInfoIterRequest;
|
||||
|
||||
impl RemoteInfoIterRequest {
|
||||
pub fn new() -> Self {
|
||||
|
|
@ -1,17 +1,16 @@
|
|||
use iroh::endpoint::RemoteInfo;
|
||||
use prost_types::DurationError;
|
||||
|
||||
use crate::proto::iroh::{DirectAddrInfoMessage, RemoteInfoMessage};
|
||||
use crate::{error::Error, proto::{DirectAddrInfoMessage, RemoteInfoMessage}};
|
||||
|
||||
impl TryFrom<RemoteInfo> for RemoteInfoMessage {
|
||||
type Error = DurationError;
|
||||
type Error = Error;
|
||||
fn try_from(value: RemoteInfo) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
node_id: value.node_id.to_string(),
|
||||
node_id: Vec::from(value.node_id.as_bytes()),
|
||||
relay_url: value.relay_url.map_or(String::from(""), |x| x.relay_url.to_string()),
|
||||
addrs: value.addrs.into_iter()
|
||||
.map(|x| DirectAddrInfoMessage::try_from(x))
|
||||
.collect::<Result<Vec<DirectAddrInfoMessage>,DurationError>>()?,
|
||||
.collect::<Result<Vec<DirectAddrInfoMessage>,Error>>()?,
|
||||
conn_type: value.conn_type.to_string(),
|
||||
latency: value.latency.map(|x| x.try_into()).transpose()?,
|
||||
last_used: value.last_used.map(|x| x.try_into()).transpose()?,
|
||||
19
iroh-proto/src/proto/remote_info_request.rs
Normal file
19
iroh-proto/src/proto/remote_info_request.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
use iroh::NodeId;
|
||||
|
||||
use crate::proto::RemoteInfoRequest;
|
||||
|
||||
impl From<NodeId> for RemoteInfoRequest {
|
||||
fn from(value: NodeId) -> Self {
|
||||
Self {
|
||||
node_id : Vec::from(value.as_bytes())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<RemoteInfoRequest> for NodeId {
|
||||
type Error = crate::error::Error;
|
||||
fn try_from(value: RemoteInfoRequest) -> Result<Self, Self::Error> {
|
||||
let slice: [u8; 32] = value.node_id[0..32].try_into()?;
|
||||
Ok(NodeId::from_bytes(&slice)?)
|
||||
}
|
||||
}
|
||||
16
iroh-proto/src/proto/remote_info_response.rs
Normal file
16
iroh-proto/src/proto/remote_info_response.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
use crate::{ proto::{RemoteInfoMessage, RemoteInfoResponse}};
|
||||
|
||||
impl From<RemoteInfoMessage> for RemoteInfoResponse {
|
||||
fn from(value: RemoteInfoMessage) -> Self {
|
||||
Self {
|
||||
remote_info: Some(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<Option<RemoteInfoMessage>> for RemoteInfoResponse {
|
||||
fn from(value: Option<RemoteInfoMessage>) -> Self {
|
||||
Self{
|
||||
remote_info: value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,10 +2,10 @@ use std::time::Duration;
|
|||
|
||||
use iroh::endpoint::Source;
|
||||
|
||||
use crate::proto::iroh::SourceMessage;
|
||||
use crate::{error::Error, proto::SourceMessage};
|
||||
|
||||
impl TryFrom<(Source, Duration)> for SourceMessage {
|
||||
type Error = prost_types::DurationError;
|
||||
type Error = Error;
|
||||
fn try_from(src: (Source, Duration)) -> Result<Self, Self::Error> {
|
||||
let (source, duration )= src;
|
||||
Ok(Self {
|
||||
40
iroh-proto/src/server.rs
Normal file
40
iroh-proto/src/server.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
use std::pin::Pin;
|
||||
|
||||
use iroh::{Endpoint, NodeId};
|
||||
use tonic::{Response, Request, Status};
|
||||
use tokio_stream::Stream;
|
||||
|
||||
use crate::proto::{RemoteInfoIterRequest, RemoteInfoMessage, RemoteInfoRequest, RemoteInfoResponse};
|
||||
|
||||
#[tonic::async_trait]
|
||||
pub trait AsEndpoint: Send + Sync + 'static {
|
||||
async fn as_endpoint(&self) -> &Endpoint;
|
||||
}
|
||||
pub struct IrohServer<T>
|
||||
where
|
||||
T: AsEndpoint
|
||||
{
|
||||
endpoint: T
|
||||
}
|
||||
|
||||
#[tonic::async_trait]
|
||||
impl<T> crate::proto::iroh_server::Iroh for IrohServer<T>
|
||||
where
|
||||
T: AsEndpoint
|
||||
{
|
||||
type RemoteInfoIterStream = Pin<Box<dyn Stream<Item = Result<RemoteInfoResponse, Status>> + Send>>;
|
||||
async fn remote_info(&self, request: Request<RemoteInfoRequest>) -> Result<Response<RemoteInfoResponse>, Status> {
|
||||
let node_id = NodeId::try_from(request.into_inner()).or_else(|e| {
|
||||
Err(Status::from_error(Box::new(e)))
|
||||
})?;
|
||||
let remote_info: Option<RemoteInfoMessage> = self.endpoint.as_endpoint().await.remote_info(node_id).map(|x| x.try_into()).transpose().or_else(|e| {
|
||||
Err(Status::from_error(Box::new(e)))
|
||||
})?;
|
||||
Ok(Response::new(RemoteInfoResponse::from(remote_info)))
|
||||
}
|
||||
async fn remote_info_iter(&self, _: Request<RemoteInfoIterRequest>) -> Result<Response<Self::RemoteInfoIterStream>, Status> {
|
||||
let iter = self.endpoint.as_endpoint().await.remote_info_iter();
|
||||
let stream = futures::stream::iter(iter);
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue