feat(homeserver): add in memory pkarr relay api for testing

This commit is contained in:
nazeh
2024-07-28 12:22:20 +03:00
parent c40ba8390b
commit dac2284065
6 changed files with 227 additions and 3 deletions

121
Cargo.lock generated
View File

@@ -26,6 +26,55 @@ dependencies = [
"memchr",
]
[[package]]
name = "anstream"
version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
[[package]]
name = "anstyle-parse"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
]
[[package]]
name = "anyhow"
version = "1.0.86"
@@ -271,12 +320,58 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]]
name = "cobs"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15"
[[package]]
name = "colorchoice"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]]
name = "console_error_panic_hook"
version = "0.1.7"
@@ -819,6 +914,12 @@ dependencies = [
"stable_deref_trait",
]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "heed"
version = "0.20.3"
@@ -1019,6 +1120,12 @@ version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itoa"
version = "1.0.11"
@@ -1525,10 +1632,12 @@ dependencies = [
"axum-extra",
"base32",
"bytes",
"clap",
"dirs-next",
"flume",
"futures-util",
"heed",
"once_cell",
"pkarr",
"postcard",
"pubky-common",
@@ -2043,6 +2152,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "subtle"
version = "2.6.1"
@@ -2446,6 +2561,12 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "valuable"
version = "0.1.0"

View File

@@ -9,10 +9,12 @@ axum = "0.7.5"
axum-extra = { version = "0.9.3", features = ["typed-header", "async-read-body"] }
base32 = "0.5.1"
bytes = "1.6.1"
clap = { version = "4.5.11", features = ["derive"] }
dirs-next = "2.0.0"
flume = "0.11.0"
futures-util = "0.3.30"
heed = "0.20.3"
once_cell = "1.19.0"
pkarr = { version = "2.1.0", features = ["async"] }
postcard = { version = "1.0.8", features = ["alloc"] }
pubky-common = { version = "0.1.0", path = "../pubky-common" }

View File

@@ -1,13 +1,36 @@
use anyhow::Result;
use pkarr::mainline::Testnet;
use pubky_homeserver::Homeserver;
use clap::Parser;
#[derive(Parser, Debug)]
struct Cli {
/// [tracing_subscriber::EnvFilter]
#[clap(short, long)]
tracing_env_filter: Option<String>,
#[clap(long)]
testnet: bool,
}
#[tokio::main]
async fn main() -> Result<()> {
let args = Cli::parse();
tracing_subscriber::fmt()
.with_env_filter("pubky_homeserver=debug,tower_http=debug")
.with_env_filter(
args.tracing_env_filter
.unwrap_or("pubky_homeserver=debug,tower_http=debug".to_string()),
)
.init();
let server = Homeserver::start(Default::default()).await?;
let server = if args.testnet {
let testnet = Testnet::new(3);
Homeserver::start_test(&testnet).await?
} else {
Homeserver::start(Default::default()).await?
};
server.run_until_done().await?;

View File

@@ -8,11 +8,14 @@ use tower_http::trace::TraceLayer;
use crate::server::AppState;
use self::pkarr::pkarr_router;
mod auth;
mod pkarr;
mod public;
mod root;
pub fn create_app(state: AppState) -> Router {
fn base(state: AppState) -> Router {
Router::new()
.route("/", get(root::handler))
.route("/:pubky", put(auth::signup))
@@ -28,3 +31,7 @@ pub fn create_app(state: AppState) -> Router {
.layer(DefaultBodyLimit::max(16 * 1024))
.with_state(state)
}
pub fn create_app(state: AppState) -> Router {
base(state).merge(pkarr_router())
}

View File

@@ -0,0 +1,69 @@
use std::{collections::HashMap, sync::RwLock};
use axum::{
body::{Body, Bytes},
http::StatusCode,
response::IntoResponse,
routing::{get, put},
Router,
};
use futures_util::stream::StreamExt;
use once_cell::sync::OnceCell;
use pkarr::{PublicKey, SignedPacket};
use crate::{
error::{Error, Result},
extractors::Pubky,
};
// TODO: maybe replace after we have local storage of users packets?
static IN_MEMORY: OnceCell<RwLock<HashMap<PublicKey, SignedPacket>>> = OnceCell::new();
/// Pkarr relay, helpful for testing.
///
/// For real productioin, you should use a [production ready
/// relay](https://github.com/pubky/pkarr/server).
pub fn pkarr_router() -> Router {
Router::new()
.route("/pkarr/:pubky", put(pkarr_put))
.route("/pkarr/:pubky", get(pkarr_get))
}
pub async fn pkarr_put(pubky: Pubky, body: Body) -> Result<impl IntoResponse> {
let mut bytes = Vec::with_capacity(1104);
let mut stream = body.into_data_stream();
while let Some(chunk) = stream.next().await {
bytes.extend_from_slice(&chunk?)
}
let public_key = pubky.public_key().to_owned();
let signed_packet = SignedPacket::from_relay_payload(&public_key, &Bytes::from(bytes))?;
let mut store = IN_MEMORY
.get()
.expect("In memory pkarr store is not initialized")
.write()
.unwrap();
store.insert(public_key, signed_packet);
Ok(())
}
pub async fn pkarr_get(pubky: Pubky) -> Result<impl IntoResponse> {
let store = IN_MEMORY
.get()
.expect("In memory pkarr store is not initialized")
.read()
.unwrap();
if let Some(signed_packet) = store.get(pubky.public_key()) {
return Ok(signed_packet.to_relay_payload());
}
Err(Error::with_status(StatusCode::NOT_FOUND))
}

View File

@@ -82,6 +82,8 @@ impl Homeserver {
/// Test version of [Homeserver::start], using mainline Testnet, and a temporary storage.
pub async fn start_test(testnet: &Testnet) -> Result<Self> {
info!("Running testnet..");
Homeserver::start(Config::test(testnet)).await
}