stratum_server/
route.rs

1use crate::{Session, StratumRequest};
2use async_trait::async_trait;
3use futures::Future;
4use tracing::error;
5
6pub(crate) type DynEndpoint<State, CState> = dyn Endpoint<State, CState>;
7
8#[async_trait]
9pub trait Endpoint<State: Clone, CState: Clone>: Send + Sync + 'static {
10    async fn call(
11        &self,
12        req: StratumRequest<State>,
13        connection: Session<CState>,
14    ) -> serde_json::Value;
15}
16
17#[async_trait]
18impl<State, CState, F, Fut, Res, E> Endpoint<State, CState> for F
19where
20    State: Clone + Send + Sync + 'static,
21    CState: Clone + Send + Sync + 'static,
22    F: Send + Sync + 'static + Fn(StratumRequest<State>, Session<CState>) -> Fut,
23    Fut: Future<Output = std::result::Result<Res, E>> + Send + 'static,
24    E: std::error::Error + 'static + std::marker::Send,
25    Res: Into<serde_json::Value> + 'static + std::marker::Send,
26{
27    async fn call(
28        &self,
29        req: StratumRequest<State>,
30        connection: Session<CState>,
31    ) -> serde_json::Value {
32        let fut = (self)(req, connection.clone());
33
34        match fut.await {
35            Ok(response) => response.into(),
36            Err(e) => {
37                error!(
38                    connection_id = connection.id().to_string(),
39                    error.cause_chain = ?e,
40                    error.message = %e,
41                    "Request failed disconnecting miner"
42                );
43
44                //@todo better response values here if we can.
45                connection.disconnect();
46                serde_json::Value::Null
47            }
48        }
49    }
50}