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

[back-2425] Light weight APi #12

Merged
merged 5 commits into from
Apr 4, 2024
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
339 changes: 211 additions & 128 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ once_cell = "1.19.0"
rand = "0.8.5"
runit = "0.1.0"
futures-util = "0.3"

axum = "0.7.5"
alloy = { git = "https://github.com/alloy-rs/alloy", rev = "7e39c85f9f51e6449a8b661f54df0ac213f18639", features = [
"sol-types",
"network",
Expand All @@ -55,11 +55,11 @@ alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "7e39c85f9f5
] }
alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "7e39c85f9f51e6449a8b661f54df0ac213f18639", features = [
"eip712",
]}
alloy-signer-wallet = {git = "https://github.com/alloy-rs/alloy", rev = "7e39c85f9f51e6449a8b661f54df0ac213f18639" }
] }
alloy-signer-wallet = { git = "https://github.com/alloy-rs/alloy", rev = "7e39c85f9f51e6449a8b661f54df0ac213f18639" }

alloy-core = { git = "https://github.com/alloy-rs/core", rev = "525a233" }
alloy-sol-types = { git = "https://github.com/alloy-rs/core", rev = "525a233" , features = ["eip712-serde"]}
alloy-sol-types = { git = "https://github.com/alloy-rs/core", rev = "525a233", features = ["eip712-serde"] }
alloy-primitives = { git = "https://github.com/alloy-rs/core", rev = "525a233", features = ["serde"] }
alloy-sol-macro = { git = "https://github.com/alloy-rs/core", rev = "525a233" }
futures = "0.3.30"
Expand Down
73 changes: 73 additions & 0 deletions src/api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use crate::config::Config;
use crate::controller::{ControllerCommands, ControllerInterface, DBQuery};
use crate::storage;
use crate::types::PremintTypes;
use axum::extract::State;
use axum::handler::Handler;
use axum::http::StatusCode;
use axum::routing::{get, post};
use axum::{Json, Router};
use sqlx::SqlitePool;
use tokio::net::TcpListener;

#[derive(Clone)]
pub struct AppState {
pub db: SqlitePool,
pub controller: ControllerInterface,
}
pub async fn make_router(config: &Config, controller: ControllerInterface) -> Router {
let (snd, recv) = tokio::sync::oneshot::channel();
controller
.send_command(ControllerCommands::Query(DBQuery::Direct(snd)))
.await
.unwrap();
let db = recv.await.unwrap().expect("Failed to get db");
Router::new()
.route("/health", get(health))
.route("/list-all", get(list_all))
.route("/submit-premint", post(submit_premint))
.with_state(AppState { db, controller })
}

pub async fn start_api(config: &Config, router: Router) -> eyre::Result<()> {
let addr = format!("{}:{}", config.initial_network_ip(), config.api_port);
let listener = TcpListener::bind(addr.clone()).await.unwrap();

tracing::info!(address = addr, "Starting API server");
tokio::spawn(async move {
axum::serve(listener, router)
.await
.expect("API Server failed");
});
Ok(())
}

async fn list_all(
State(state): State<AppState>,
) -> Result<Json<Vec<PremintTypes>>, (StatusCode, String)> {
match storage::list_all(&state.db).await {
Ok(premints) => Ok(Json(premints)),
Err(_e) => Err((
StatusCode::INTERNAL_SERVER_ERROR,
"Failed to list all premints".to_string(),
)),
}
}

async fn health() -> &'static str {
"OK"
}

async fn submit_premint(
State(state): State<AppState>,
Json(premint): Json<PremintTypes>,
) -> (StatusCode, String) {
match state
.controller
.send_command(ControllerCommands::Broadcast { message: premint })
.await
{
Ok(()) => (StatusCode::OK, "Premint submitted".to_string()),
Err(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()),
}
}
13 changes: 9 additions & 4 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ pub struct Config {
#[envconfig(from = "SEED")]
pub seed: u64,

#[envconfig(from = "PORT", default = "7777")]
pub port: u64,
#[envconfig(from = "PEER_PORT", default = "7778")]
pub peer_port: u64,

#[envconfig(from = "CONNECT_EXTERNAL", default = "true")]
pub connect_external: bool,
Expand All @@ -25,6 +25,9 @@ pub struct Config {
#[envconfig(from = "PRUNE_MINTED_PREMINTS", default = "true")]
pub prune_minted_premints: bool,

#[envconfig(from = "API_PORT", default = "7777")]
pub api_port: u64,

#[envconfig(from = "PEER_LIMIT", default = "1000")]
pub peer_limit: u64,

Expand Down Expand Up @@ -130,11 +133,12 @@ mod test {
fn test_premint_names() {
let config = super::Config {
seed: 0,
port: 7777,
peer_port: 7777,
connect_external: false,
db_url: None,
persist_state: false,
prune_minted_premints: false,
api_port: 0,
peer_limit: 1000,
premint_types: "simple,zora_premint_v2".to_string(),
chain_inclusion_mode: ChainInclusionMode::Check,
Expand All @@ -149,11 +153,12 @@ mod test {

let config = super::Config {
seed: 0,
port: 7777,
peer_port: 7777,
connect_external: false,
db_url: None,
persist_state: false,
prune_minted_premints: false,
api_port: 0,
peer_limit: 1000,
premint_types: "zora_premint_v2".to_string(),
chain_inclusion_mode: ChainInclusionMode::Check,
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod api;
pub mod chain;
pub mod config;
pub mod controller;
Expand Down
5 changes: 5 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use clap::Parser;
use mintpool::api;
use mintpool::run::start_services;
use mintpool::stdin::watch_stdin;
use tracing_subscriber::EnvFilter;
Expand All @@ -15,6 +16,10 @@ async fn main() -> eyre::Result<()> {
tracing::info!("Starting mintpool with config: {:?}", config);

let ctl = start_services(&config).await?;

let router = api::make_router(&config, ctl.clone()).await;
api::start_api(&config, router).await?;

watch_stdin(ctl).await;

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub async fn start_services(config: &Config) -> eyre::Result<ControllerInterface
let mut controller = Controller::new(swrm_cmd_send, event_recv, ext_cmd_recv, store);
let controller_interface = ControllerInterface::new(ext_cmd_send);

let port = config.port;
let port = config.peer_port;
let network_ip = config.initial_network_ip();
tokio::spawn(async move {
swarm_controller
Expand Down
45 changes: 25 additions & 20 deletions src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ impl PremintStorage {
pub async fn store(&self, premint: PremintTypes) -> eyre::Result<()> {
let metadata = premint.metadata();
let json = premint.to_json()?;
let signer = format!("{:?}", metadata.signer);
let collection_address = format!("{:?}", metadata.collection_address);
let signer = metadata.signer.to_checksum(None);
let collection_address = metadata.collection_address.to_checksum(None);
let token_id = metadata.token_id.to_string();
let chain_id = metadata.chain_id.to::<i64>();
let id = premint.guid();
Expand All @@ -75,22 +75,7 @@ impl PremintStorage {
}

pub async fn list_all(&self) -> eyre::Result<Vec<PremintTypes>> {
let rows = sqlx::query(
r#"
SELECT json FROM premints
"#,
)
.fetch_all(&self.db)
.await
.map_err(|e| eyre::eyre!("Failed to list all premints: {}", e))?;
let premints = rows
.iter()
.map(|row| {
let json: String = row.get(0);
PremintTypes::from_json(json).unwrap()
})
.collect();
Ok(premints)
list_all(&self.db).await
}

pub async fn get_for_id(&self, id: String) -> eyre::Result<PremintTypes> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking about this earlier. I believe we'll need to remove the version from the id and make it a separate field of the metadata. Otherwise it'll be really hard to query for an existing premint when we get an update. Not for this PR necessarily, just wanted to put it out there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good call out

Expand All @@ -106,6 +91,24 @@ impl PremintStorage {
PremintTypes::from_json(json)
}
}
pub async fn list_all(db: &SqlitePool) -> eyre::Result<Vec<PremintTypes>> {
let rows = sqlx::query(
r#"
SELECT json FROM premints
"#,
)
.fetch_all(db)
.await
.map_err(|e| eyre::eyre!("Failed to list all premints: {}", e))?;
let premints = rows
.iter()
.map(|row| {
let json: String = row.get(0);
PremintTypes::from_json(json).unwrap()
})
.collect();
Ok(premints)
}

#[cfg(test)]
mod test {
Expand All @@ -117,7 +120,7 @@ mod test {
async fn test_insert_and_get() {
let config = Config {
seed: 0,
port: 7777,
peer_port: 7777,
connect_external: false,
db_url: None, // in-memory for testing
persist_state: false,
Expand All @@ -127,6 +130,7 @@ mod test {
chain_inclusion_mode: ChainInclusionMode::Check,
supported_chain_ids: "7777777,".to_string(),
trusted_peers: None,
api_port: 0,
};

let store = PremintStorage::new(&config).await;
Expand All @@ -141,11 +145,12 @@ mod test {
async fn test_list_all() {
let config = Config {
seed: 0,
port: 7777,
peer_port: 7778,
connect_external: false,
db_url: None, // in-memory for testing
persist_state: false,
prune_minted_premints: false,
api_port: 7777,
peer_limit: 1000,
premint_types: "simple".to_string(),
chain_inclusion_mode: ChainInclusionMode::Check,
Expand Down
3 changes: 2 additions & 1 deletion tests/p2p_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,12 @@ mod build {
for i in 0..num_nodes {
let config = Config {
seed: rand_n + i,
port: start_port + i,
peer_port: start_port + i,
connect_external: false,
db_url: None,
persist_state: false,
prune_minted_premints: false,
api_port: 0,
peer_limit,
premint_types: "simple,zora_premint_v2".to_string(),
chain_inclusion_mode: ChainInclusionMode::Check,
Expand Down
Loading