Skip to main content

anvil_polkadot/server/
handler.rs

1//! Contains RPC handlers
2use anvil_core::eth::{EthPubSub, EthRequest, EthRpcCall, subscription::SubscriptionId};
3use anvil_rpc::{error::RpcError, response::ResponseResult};
4use anvil_server::{PubSubContext, PubSubRpcHandler, RpcHandler};
5use futures::{SinkExt, channel::oneshot};
6
7use crate::{
8    api_server::{ApiHandle, ApiRequest},
9    pubsub::EthSubscription,
10};
11
12/// A `RpcHandler` that expects `EthRequest` rpc calls via http
13#[derive(Clone)]
14pub struct HttpEthRpcHandler {
15    api_handle: ApiHandle,
16}
17
18impl HttpEthRpcHandler {
19    /// Creates a new instance of the handler using the given `ApiHandle`
20    pub fn new(api_handle: ApiHandle) -> Self {
21        Self { api_handle }
22    }
23}
24
25#[async_trait::async_trait]
26impl RpcHandler for HttpEthRpcHandler {
27    type Request = EthRequest;
28
29    async fn on_request(&self, request: Self::Request) -> ResponseResult {
30        let (tx, rx) = oneshot::channel();
31        self.api_handle
32            .clone()
33            .send(ApiRequest { req: request, resp_sender: tx })
34            .await
35            .expect("Dropped receiver");
36
37        rx.await.expect("Dropped sender")
38    }
39}
40
41/// A `RpcHandler` that expects `EthRequest` rpc calls and `EthPubSub` via pubsub connection
42#[derive(Clone)]
43pub struct PubSubEthRpcHandler {
44    api_handle: ApiHandle,
45}
46
47impl PubSubEthRpcHandler {
48    /// Creates a new instance of the handler using the given `ApiHandle`
49    pub fn new(api_handle: ApiHandle) -> Self {
50        Self { api_handle }
51    }
52
53    /// Invoked for an ethereum pubsub rpc call
54    async fn on_pub_sub(&self, _pubsub: EthPubSub, _cx: PubSubContext<Self>) -> ResponseResult {
55        ResponseResult::Error(RpcError::invalid_params("Not implemented"))
56    }
57}
58
59#[async_trait::async_trait]
60impl PubSubRpcHandler for PubSubEthRpcHandler {
61    type Request = EthRpcCall;
62    type SubscriptionId = SubscriptionId;
63    type Subscription = EthSubscription;
64
65    async fn on_request(&self, request: Self::Request, cx: PubSubContext<Self>) -> ResponseResult {
66        trace!(target: "rpc", "received pubsub request {:?}", request);
67        match request {
68            EthRpcCall::Request(request) => {
69                let (tx, rx) = oneshot::channel();
70                self.api_handle
71                    .clone()
72                    .send(ApiRequest { req: *request, resp_sender: tx })
73                    .await
74                    .expect("Dropped receiver");
75
76                rx.await.expect("Dropped sender")
77            }
78            EthRpcCall::PubSub(pubsub) => self.on_pub_sub(pubsub, cx).await,
79        }
80    }
81}