zebra_rpc/server/
rpc_call_compatibility.rs1use jsonrpsee::{
7 server::middleware::rpc::{layer::ResponseFuture, RpcServiceT},
8 MethodResponse,
9};
10use jsonrpsee_types::ErrorObject;
11
12#[derive(Clone)]
25pub struct FixRpcResponseMiddleware<S> {
26 service: S,
27}
28
29impl<S> FixRpcResponseMiddleware<S> {
30 pub fn new(service: S) -> Self {
32 Self { service }
33 }
34}
35
36impl<'a, S> RpcServiceT<'a> for FixRpcResponseMiddleware<S>
37where
38 S: RpcServiceT<'a> + Send + Sync + Clone + 'static,
39{
40 type Future = ResponseFuture<futures::future::BoxFuture<'a, jsonrpsee::MethodResponse>>;
41
42 fn call(&self, request: jsonrpsee::types::Request<'a>) -> Self::Future {
43 let service = self.service.clone();
44 ResponseFuture::future(Box::pin(async move {
45 let response = service.call(request).await;
46 if response.is_error() {
47 let original_error_code = response
48 .as_error_code()
49 .expect("response should have an error code");
50 if original_error_code == jsonrpsee_types::ErrorCode::InvalidParams.code() {
51 let new_error_code = crate::server::error::LegacyCode::Misc.into();
52 tracing::debug!(
53 "Replacing RPC error: {original_error_code} with {new_error_code}"
54 );
55 let json: serde_json::Value =
56 serde_json::from_str(response.into_parts().0.as_str())
57 .expect("response string should be valid json");
58 let id = match &json["id"] {
59 serde_json::Value::Null => Some(jsonrpsee::types::Id::Null),
60 serde_json::Value::Number(n) => {
61 n.as_u64().map(jsonrpsee::types::Id::Number)
62 }
63 serde_json::Value::String(s) => Some(jsonrpsee::types::Id::Str(s.into())),
64 _ => None,
65 }
66 .expect("response json should have an id");
67
68 return MethodResponse::error(
69 id,
70 ErrorObject::borrowed(
71 new_error_code,
72 json.get("error")
73 .and_then(|v| v.get("message"))
74 .and_then(|m| m.as_str())
75 .unwrap_or("Invalid params"),
76 None,
77 ),
78 );
79 }
80 }
81 response
82 }))
83 }
84}