Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project Skeleton #5

Merged
merged 7 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from 3 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
1,923 changes: 1,923 additions & 0 deletions Cargo.lock

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,27 @@
name = "didethresolver"
version = "0.1.0"
edition = "2021"
resolver = "2"

[profile.release]
panic = 'abort'
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
log = "0.4"
tokio = { version = "1.34", features = ["macros", "rt"] }
async-trait = "0.1"
tracing = "0.1"
tracing-subscriber = "0.3.18"
tracing-forest = { version = "0.1", features = ["ansi", "chrono", "env-filter"] }
serde = { version = "1", features = ["derive"] }
jsonrpsee = { version = "0.20", features = ["macros", "server", "client-core"] }
anyhow = "1"

[dev-dependencies]
mockall = "0.11"
jsonrpsee = { version = "0.20", features = ["macros", "server", "client"] }
futures = "0.3"
tokio = { version = "1.34", features = ["macros", "rt", "time"] }


4 changes: 4 additions & 0 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[toolchain]
channel = "stable"
components = [ "rustc", "cargo", "clippy", "rustfmt", "rust-analyzer" ]
profile = "default"
13 changes: 13 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
mod rpc;
mod types;
mod util;

fn main() {
util::init_logging();
println!("Hello, world!");
}

/*
pub async fn run_server() -> Result<(), Error> {
insipx marked this conversation as resolved.
Show resolved Hide resolved
let server = Server::builder().build("127.0.0.1:0").await?;
let addr = server.local_addr()?;
let handle = server.start(DidRegistryMethods);
}
*/
51 changes: 51 additions & 0 deletions src/rpc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
mod api;
mod methods;

// re-export the defined API
pub use api::*;

#[cfg(test)]
mod tests {
use std::{future::Future, time::Duration};

use futures::future::FutureExt;
use jsonrpsee::{
server::Server,
ws_client::{WsClient, WsClientBuilder},
};
use tokio::time::timeout as timeout_tokio;

use super::*;

// Test harness for using a WebSockets Server
pub async fn with_client<F, R, T>(timeout: Option<Duration>, fun: F) -> T
where
F: FnOnce(WsClient) -> R + 'static,
R: Future<Output = T> + FutureExt + Send + 'static,
{
crate::util::init_logging();

let server = Server::builder().build("127.0.0.1:0").await.unwrap();
let addr = server.local_addr().unwrap();
let handle = server.start(methods::DidRegistryMethods.into_rpc());

let client = WsClientBuilder::default()
.build(&format!("ws://{addr}"))
.await
.unwrap();

// cant catch_unwind b/c jsonrpsee uses tokio mpsc which is !UnwindSafe, so we wrap with a
// timeout.
// If we panic in the closure without the timeout or catch_unwind, we never return and the server will never stop, hanging our
// tests.
let result = timeout_tokio(timeout.unwrap_or(Duration::from_millis(50)), fun(client)).await;

handle.stop().unwrap();
handle.stopped().await;

if let Err(_) = result {
log::debug!("Test timed out due to panic, or running too long.");
}
result.unwrap()
}
}
49 changes: 49 additions & 0 deletions src/rpc/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//! Trait Definitions for JSON-RPC

use crate::types::DidDocument;

use jsonrpsee::{proc_macros::rpc, types::ErrorObjectOwned};

/// Decentralized Identifier JSON-RPC Interface Methods
#[rpc(server, client, namespace = "did")]
pub trait DidRegistry {
#[method(name = "resolveDid")]
async fn resolve_did(&self, public_key: String) -> Result<DidDocument, ErrorObjectOwned>;
}

#[cfg(test)]
mod tests {
use super::*;

use async_trait::async_trait;
use mockall::{mock, predicate::*};

use crate::rpc::tests::with_client;

mock! {
pub DidRegistryMethods {}

#[async_trait]
impl DidRegistryServer for DidRegistryMethods {
async fn resolve_did(&self, _public_key: String) -> Result<DidDocument, ErrorObjectOwned>;
}
}

#[tokio::test]
pub async fn test_resolve_did() {
crate::util::init_logging();

let mut mock = MockDidRegistryMethods::new();
mock.expect_resolve_did().returning(|_| Ok(DidDocument));
// test stub
}

#[tokio::test]
pub async fn test_resolve_did_server() {
let _ = super::tests::with_client(None, |client| async move {
client.resolve_did("Hello".to_string()).await?;
Ok::<_, anyhow::Error>(())
})
.await;
}
}
20 changes: 20 additions & 0 deletions src/rpc/methods.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//! Trait Implementations for DID JSON-RPC
use super::api::*;
use crate::types::DidDocument;

use jsonrpsee::types::ErrorObjectOwned;

use async_trait::async_trait;

const LOG_TARGET: &str = "rpc";

pub struct DidRegistryMethods;

#[async_trait]
impl DidRegistryServer for DidRegistryMethods {
async fn resolve_did(&self, _public_key: String) -> Result<DidDocument, ErrorObjectOwned> {
//TODO: Stub for resolveDid, ref: [#4](https://github.com/xmtp/didethresolver/issues/4)
log::debug!(target: LOG_TARGET, "resolve_did called");
todo!();
}
}
7 changes: 7 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//! Type Definitions for the DID Registry compatible with JSON

use serde::{Deserialize, Serialize};

// TODO: Stub
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct DidDocument;
25 changes: 25 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#[cfg(test)]
use std::sync::Once;
use tracing_forest::ForestLayer;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Registry};

#[cfg(not(test))]
pub fn init_logging() {
Registry::default()
.with(ForestLayer::default())
.with(EnvFilter::from_default_env())
.init();
}

#[cfg(test)]
static INIT: Once = Once::new();

#[cfg(test)]
pub fn init_logging() {
INIT.call_once(|| {
Registry::default()
.with(ForestLayer::default())
.with(EnvFilter::from_default_env())
.init()
})
}
1 change: 1 addition & 0 deletions tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Integration Tests
Loading