From c7230752c0dd47f335f1fb39704658efbf4250db Mon Sep 17 00:00:00 2001 From: Gusto Date: Thu, 20 Jun 2024 16:48:17 +0300 Subject: [PATCH] Api endpoint to add blob and receive attestation --- nodes/nomos-node/Cargo.toml | 4 +- nodes/nomos-node/src/api.rs | 72 ++++++++++++++++++++++------ nodes/nomos-node/src/config.rs | 4 +- nodes/nomos-node/src/lib.rs | 7 ++- nomos-services/api/Cargo.toml | 3 ++ nomos-services/api/src/http/da.rs | 75 ++++++++++++++++++++++++++++++ nomos-services/api/src/http/mod.rs | 1 + 7 files changed, 148 insertions(+), 18 deletions(-) create mode 100644 nomos-services/api/src/http/da.rs diff --git a/nodes/nomos-node/Cargo.toml b/nodes/nomos-node/Cargo.toml index 123ef8db..fa5e8662 100644 --- a/nodes/nomos-node/Cargo.toml +++ b/nodes/nomos-node/Cargo.toml @@ -15,11 +15,13 @@ chrono = "0.4" futures = "0.3" http = "0.2.9" hex = "0.4.3" +kzgrs-backend = { path = "../../nomos-da/kzgrs-backend" } overwatch-rs = { git = "https://github.com/logos-co/Overwatch", rev = "2f70806" } overwatch-derive = { git = "https://github.com/logos-co/Overwatch", rev = "ac28d01" } tracing = "0.1" multiaddr = "0.18" nomos-core = { path = "../../nomos-core" } +nomos-da-verifier = { path = "../../nomos-services/data-availability/verifier", features = ["rocksdb-backend", "libp2p"] } nomos-network = { path = "../../nomos-services/network", features = ["libp2p"] } nomos-api = { path = "../../nomos-services/api" } nomos-log = { path = "../../nomos-services/log" } @@ -52,4 +54,4 @@ time = "0.3" [features] mixnet = ["nomos-network/mixnet"] -metrics = [] \ No newline at end of file +metrics = [] diff --git a/nodes/nomos-node/src/api.rs b/nodes/nomos-node/src/api.rs index 5d53cd51..0688db6e 100644 --- a/nodes/nomos-node/src/api.rs +++ b/nodes/nomos-node/src/api.rs @@ -1,3 +1,4 @@ +use std::error::Error; use std::{fmt::Debug, hash::Hash}; use axum::{ @@ -10,6 +11,23 @@ use hyper::{ header::{CONTENT_TYPE, USER_AGENT}, Body, StatusCode, }; +use nomos_api::{ + http::{cl, consensus, da, libp2p, mempool, metrics, storage}, + Backend, +}; +use nomos_core::da::DaVerifier as CoreDaVerifier; +use nomos_core::{ + da::{attestation::Attestation, blob::Blob}, + header::HeaderId, + tx::Transaction, +}; +use nomos_da_verifier::backend::VerifierBackend; +use nomos_mempool::{ + network::adapters::libp2p::Libp2pAdapter as MempoolNetworkAdapter, + tx::service::openapi::Status, MempoolMetrics, +}; +use nomos_network::backends::libp2p::Libp2p as NetworkBackend; +use nomos_storage::backends::StorageSerde; use overwatch_rs::overwatch::handle::OverwatchHandle; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use tower_http::{ @@ -19,19 +37,6 @@ use tower_http::{ use utoipa::OpenApi; use utoipa_swagger_ui::SwaggerUi; -use nomos_core::{header::HeaderId, tx::Transaction}; -use nomos_mempool::{ - network::adapters::libp2p::Libp2pAdapter as MempoolNetworkAdapter, - tx::service::openapi::Status, MempoolMetrics, -}; -use nomos_network::backends::libp2p::Libp2p as NetworkBackend; -use nomos_storage::backends::StorageSerde; - -use nomos_api::{ - http::{cl, consensus, libp2p, mempool, metrics, storage}, - Backend, -}; - /// Configuration for the Http Server #[derive(Debug, Clone, serde::Deserialize, serde::Serialize)] pub struct AxumBackendSettings { @@ -41,8 +46,11 @@ pub struct AxumBackendSettings { pub cors_origins: Vec, } -pub struct AxumBackend { +pub struct AxumBackend { settings: AxumBackendSettings, + _attestation: core::marker::PhantomData, + _blob: core::marker::PhantomData, + _verifier_backend: core::marker::PhantomData, _tx: core::marker::PhantomData, _storage_serde: core::marker::PhantomData, } @@ -61,8 +69,14 @@ pub struct AxumBackend { struct ApiDoc; #[async_trait::async_trait] -impl Backend for AxumBackend +impl Backend for AxumBackend where + A: Attestation + Serialize + DeserializeOwned + Clone + Send + Sync + 'static, + B: Blob + Serialize + DeserializeOwned + Clone + Send + Sync + 'static, + ::BlobId: AsRef<[u8]> + Send + Sync + 'static, + VB: VerifierBackend + CoreDaVerifier + Send + Sync + 'static, + ::Settings: Clone, + ::Error: Error, T: Transaction + Clone + Debug @@ -86,6 +100,9 @@ where { Ok(Self { settings, + _attestation: core::marker::PhantomData, + _blob: core::marker::PhantomData, + _verifier_backend: core::marker::PhantomData, _tx: core::marker::PhantomData, _storage_serde: core::marker::PhantomData, }) @@ -124,6 +141,7 @@ where "/cryptarchia/headers", routing::get(cryptarchia_headers::), ) + .route("/da/add_blob", routing::post(add_blob::)) .route("/network/info", routing::get(libp2p_info)) .route("/storage/block", routing::post(block::)) .route("/mempool/add/tx", routing::post(add_tx::)) @@ -261,6 +279,30 @@ where )) } +#[utoipa::path( + post, + path = "/da/add_blob", + responses( + (status = 200, description = "Attestation for DA blob", body = Option), + (status = 500, description = "Internal server error", body = String), + ) +)] +async fn add_blob( + State(handle): State, + Json(blob): Json, +) -> Response +where + A: Attestation + Serialize + DeserializeOwned + Clone + Send + Sync + 'static, + B: Blob + Serialize + DeserializeOwned + Clone + Send + Sync + 'static, + ::BlobId: AsRef<[u8]> + Send + Sync + 'static, + VB: VerifierBackend + CoreDaVerifier, + ::Settings: Clone, + ::Error: Error, + SS: StorageSerde + Send + Sync + 'static, +{ + make_request_and_return_response!(da::add_blob::(&handle, blob)) +} + #[utoipa::path( get, path = "/network/info", diff --git a/nodes/nomos-node/src/config.rs b/nodes/nomos-node/src/config.rs index fa0a2295..09a97c2a 100644 --- a/nodes/nomos-node/src/config.rs +++ b/nodes/nomos-node/src/config.rs @@ -9,7 +9,9 @@ use clap::{Parser, ValueEnum}; use color_eyre::eyre::{eyre, Result}; use cryptarchia_ledger::Coin; use hex::FromHex; +use kzgrs_backend::common::{attestation::Attestation, blob::DaBlob}; use nomos_api::ApiService; +use nomos_da_verifier::backend::kzgrs::KzgrsDaVerifier; use nomos_libp2p::{secp256k1::SecretKey, Multiaddr}; use nomos_log::{Logger, LoggerBackend, LoggerFormat}; use nomos_network::backends::libp2p::Libp2p as NetworkBackend; @@ -116,7 +118,7 @@ pub struct MetricsArgs { pub struct Config { pub log: ::Settings, pub network: as ServiceData>::Settings, - pub http: > as ServiceData>::Settings, + pub http: > as ServiceData>::Settings, pub cryptarchia: ::Settings, } diff --git a/nodes/nomos-node/src/lib.rs b/nodes/nomos-node/src/lib.rs index 2c27f89c..71976b15 100644 --- a/nodes/nomos-node/src/lib.rs +++ b/nodes/nomos-node/src/lib.rs @@ -8,8 +8,11 @@ use full_replication::{Certificate, VidCertificate}; use api::AxumBackend; use bytes::Bytes; pub use config::{Config, CryptarchiaArgs, HttpArgs, LogArgs, MetricsArgs, NetworkArgs}; +use kzgrs_backend::common::attestation::Attestation; +use kzgrs_backend::common::blob::DaBlob; use nomos_api::ApiService; use nomos_core::{da::certificate, header::HeaderId, tx::Transaction, wire}; +use nomos_da_verifier::backend::kzgrs::KzgrsDaVerifier; use nomos_log::Logger; use nomos_mempool::da::verify::fullreplication::DaVerificationProvider as MempoolVerificationProvider; use nomos_mempool::network::adapters::libp2p::Libp2pAdapter as MempoolNetworkAdapter; @@ -79,7 +82,9 @@ pub struct Nomos { cl_mempool: ServiceHandle, da_mempool: ServiceHandle, cryptarchia: ServiceHandle, - http: ServiceHandle>>, + http: ServiceHandle< + ApiService>, + >, storage: ServiceHandle>>, #[cfg(feature = "metrics")] metrics: ServiceHandle, diff --git a/nomos-services/api/Cargo.toml b/nomos-services/api/Cargo.toml index acab9f8c..0aeb11ab 100644 --- a/nomos-services/api/Cargo.toml +++ b/nomos-services/api/Cargo.toml @@ -9,6 +9,7 @@ axum = ["dep:axum", "dep:hyper", "dep:tower-http", "utoipa-swagger-ui/axum"] [dependencies] async-trait = "0.1" +bytes = "1.2" overwatch-rs = { git = "https://github.com/logos-co/Overwatch", rev = "2f70806" } overwatch-derive = { git = "https://github.com/logos-co/Overwatch", rev = "ac28d01" } tracing = "0.1" @@ -21,6 +22,8 @@ nomos-mempool = { path = "../../nomos-services/mempool", features = [ "openapi", ] } nomos-metrics = { path = "../../nomos-services/metrics" } +nomos-da-indexer = { path = "../data-availability/indexer", features = ["rocksdb-backend"] } +nomos-da-verifier = { path = "../data-availability/verifier", features = ["rocksdb-backend", "libp2p"] } nomos-storage = { path = "../../nomos-services/storage", features = ["rocksdb"] } nomos-libp2p = { path = "../../nomos-libp2p" } full-replication = { path = "../../nomos-da/full-replication" } diff --git a/nomos-services/api/src/http/da.rs b/nomos-services/api/src/http/da.rs new file mode 100644 index 00000000..81824e10 --- /dev/null +++ b/nomos-services/api/src/http/da.rs @@ -0,0 +1,75 @@ +use bytes::Bytes; +use cryptarchia_consensus::network::adapters::libp2p::LibP2pAdapter as ConsensusNetworkAdapter; +use nomos_core::da::attestation::Attestation; +use nomos_core::da::blob::Blob; +use nomos_core::da::certificate::{self, select::FillSize as FillSizeWithBlobsCertificate}; +use nomos_core::da::DaVerifier as CoreDaVerifier; +use nomos_core::header::HeaderId; +use nomos_core::tx::{select::FillSize as FillSizeWithTx, Transaction}; +use nomos_da_indexer::storage::adapters::rocksdb::RocksAdapter as IndexerStorageAdapter; +use nomos_da_indexer::{ + consensus::adapters::cryptarchia::CryptarchiaConsensusAdapter, DataIndexerService, +}; +use nomos_da_verifier::backend::VerifierBackend; +use nomos_da_verifier::network::adapters::libp2p::Libp2pAdapter; +use nomos_da_verifier::storage::adapters::rocksdb::RocksAdapter as VerifierStorageAdapter; +use nomos_da_verifier::{DaVerifierMsg, DaVerifierService}; +use nomos_mempool::backend::mockpool::MockPool; +use nomos_mempool::da::verify::fullreplication::DaVerificationProvider as MempoolVerificationProvider; +use nomos_mempool::network::adapters::libp2p::Libp2pAdapter as MempoolNetworkAdapter; +use nomos_storage::backends::rocksdb::RocksBackend; +use nomos_storage::backends::StorageSerde; +use overwatch_rs::overwatch::handle::OverwatchHandle; +use overwatch_rs::DynError; +use serde::de::DeserializeOwned; +use serde::Serialize; +use std::error::Error; +use tokio::sync::oneshot; + +pub type DaIndexer = DataIndexerService< + // Indexer specific. + Bytes, + IndexerStorageAdapter, + CryptarchiaConsensusAdapter, + // Cryptarchia specific. + ConsensusNetworkAdapter, + MockPool::Hash>, + MempoolNetworkAdapter::Hash>, + MockPool::CertificateId>, + MempoolNetworkAdapter::Id>, + MempoolVerificationProvider, + FillSizeWithTx, + FillSizeWithBlobsCertificate, + RocksBackend, +>; + +pub type DaVerifier = + DaVerifierService, VerifierStorageAdapter>; + +pub async fn add_blob( + handle: &OverwatchHandle, + blob: B, +) -> Result, DynError> +where + A: Attestation + Serialize + DeserializeOwned + Clone + Send + Sync + 'static, + B: Blob + Serialize + DeserializeOwned + Clone + Send + Sync + 'static, + ::BlobId: AsRef<[u8]> + Send + Sync + 'static, + VB: VerifierBackend + CoreDaVerifier, + ::Settings: Clone, + ::Error: Error, + SS: StorageSerde + Send + Sync + 'static, +{ + let relay = handle.relay::>().connect().await?; + let (sender, receiver) = oneshot::channel(); + relay + .send(DaVerifierMsg::AddBlob { + blob, + reply_channel: sender, + }) + .await + .map_err(|(e, _)| e)?; + + Ok(receiver.await?) +} + +pub async fn get_range() {} diff --git a/nomos-services/api/src/http/mod.rs b/nomos-services/api/src/http/mod.rs index d63a1021..6ab13b2a 100644 --- a/nomos-services/api/src/http/mod.rs +++ b/nomos-services/api/src/http/mod.rs @@ -1,6 +1,7 @@ pub type DynError = Box; pub mod cl; pub mod consensus; +pub mod da; pub mod libp2p; pub mod mempool; pub mod metrics;