Skip to main content

blueprint_tangle_aggregation_svc/
lib.rs

1//! Tangle BLS Signature Aggregation Service
2//!
3//! A simple HTTP service that collects BLS signatures from operators,
4//! aggregates them once threshold is met, and provides the aggregated
5//! result for submission to the Tangle contract.
6//!
7//! ## Architecture
8//!
9//! ```text
10//! Operator 1 ──┐
11//! Operator 2 ──┼──▶ Aggregation Service ──▶ Aggregated Result
12//! Operator 3 ──┘         │
13//!                        ▼
14//!                  Tangle Contract
15//! ```
16//!
17//! ## Usage
18//!
19//! ### Starting the service
20//!
21//! ```rust,ignore
22//! use blueprint_tangle_aggregation_svc::{AggregationService, api, ServiceConfig};
23//! use std::sync::Arc;
24//!
25//! #[tokio::main]
26//! async fn main() {
27//!     let service = Arc::new(AggregationService::new(ServiceConfig::default()));
28//!     let app = api::router(service);
29//!
30//!     let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();
31//!     axum::serve(listener, app).await.unwrap();
32//! }
33//! ```
34//!
35//! ### API Endpoints
36//!
37//! - `POST /v1/tasks/init` - Initialize an aggregation task
38//! - `POST /v1/tasks/submit` - Submit a signature
39//! - `POST /v1/tasks/status` - Get task status
40//! - `POST /v1/tasks/aggregate` - Get aggregated result
41//!
42//! ### Operator Flow
43//!
44//! 1. Someone (often the first operator) initializes the task
45//! 2. Each operator signs the output and submits their signature
46//! 3. Once threshold is met, anyone can fetch the aggregated result
47//! 4. Submit the aggregated result to the Tangle contract
48
49pub mod api;
50#[cfg(feature = "client")]
51pub mod client;
52pub mod persistence;
53pub mod service;
54pub mod state;
55pub mod types;
56
57#[cfg(feature = "client")]
58pub use client::{AggregationServiceClient, ClientError};
59pub use persistence::{
60    FilePersistence, NoPersistence, PersistedTaskState, PersistedThresholdType, PersistenceBackend,
61    PersistenceError,
62};
63pub use service::{
64    create_signing_message, AggregationService, CleanupWorkerHandle, ServiceConfig, ServiceError,
65    ServiceStats,
66};
67pub use state::{
68    AggregationState, OperatorInfo, TaskConfig, TaskCounts, TaskForAggregation, TaskState,
69    TaskStatus, ThresholdType,
70};
71pub use types::*;
72
73/// Run the aggregation service
74pub async fn run(addr: &str, config: ServiceConfig) -> Result<(), Box<dyn std::error::Error>> {
75    use std::sync::Arc;
76    use tracing::info;
77
78    let service = Arc::new(AggregationService::new(config));
79    let app = api::router(service);
80
81    let listener = tokio::net::TcpListener::bind(addr).await?;
82    info!("Aggregation service listening on {}", addr);
83
84    axum::serve(listener, app).await?;
85    Ok(())
86}