Skip to content

Commit e1e7a4f

Browse files
committed
Simplify away the JsonRpcResponse code.
1 parent 68f2ba6 commit e1e7a4f

File tree

1 file changed

+8
-129
lines changed

1 file changed

+8
-129
lines changed

linera-ethereum/src/client.rs

+8-129
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Zefchain Labs, Inc.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use std::{fmt, fmt::Debug};
4+
use std::fmt::Debug;
55

66
use alloy::{
77
primitives::{Address, U256},
@@ -13,8 +13,7 @@ use alloy::{
1313
use alloy_primitives::{Bytes, U64};
1414
use async_trait::async_trait;
1515
use serde::{de::DeserializeOwned, Deserialize, Serialize};
16-
use serde_json::{value::RawValue, Value};
17-
use thiserror::Error;
16+
use serde_json::value::RawValue;
1817

1918
use crate::common::{
2019
event_name_from_expanded, parse_log, EthereumEvent, EthereumQueryError, EthereumServiceError,
@@ -38,12 +37,7 @@ pub trait JsonRpcClient {
3837
let payload = serde_json::to_vec(&payload)?;
3938
let body = self.request_inner(payload).await?;
4039
let result = serde_json::from_slice::<JsonRpcResponse>(&body)?;
41-
let raw = match result {
42-
JsonRpcResponse::Success { result, .. } => result.to_owned(),
43-
JsonRpcResponse::Error { error: _, .. } => {
44-
return Err(EthereumQueryError::DeserializationError.into());
45-
}
46-
};
40+
let raw = result.result;
4741
let res = serde_json::from_str(raw.get())?;
4842
Ok(res)
4943
}
@@ -69,126 +63,11 @@ impl<'a, T> Request<'a, T> {
6963
}
7064
}
7165

72-
#[derive(Deserialize, Debug, Clone, Error)]
73-
pub struct JsonRpcError {
74-
/// The error code
75-
pub code: i64,
76-
/// The error message
77-
pub message: String,
78-
/// Additional data
79-
pub data: Option<Value>,
80-
}
81-
82-
impl fmt::Display for JsonRpcError {
83-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84-
write!(
85-
f,
86-
"(code: {}, message: {}, data: {:?})",
87-
self.code, self.message, self.data
88-
)
89-
}
90-
}
91-
92-
#[derive(Debug)]
93-
pub enum JsonRpcResponse<'a> {
94-
Success { id: u64, result: &'a RawValue },
95-
Error { id: u64, error: JsonRpcError },
96-
}
97-
98-
impl<'de: 'a, 'a> Deserialize<'de> for JsonRpcResponse<'a> {
99-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
100-
where
101-
D: serde::Deserializer<'de>,
102-
{
103-
#[allow(dead_code)]
104-
struct JsonRpcResponseVisitor<'a>(&'a ());
105-
impl<'de: 'a, 'a> serde::de::Visitor<'de> for JsonRpcResponseVisitor<'a> {
106-
type Value = JsonRpcResponse<'a>;
107-
108-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
109-
formatter.write_str("a valid jsonrpc 2.0 response object")
110-
}
111-
112-
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
113-
where
114-
A: serde::de::MapAccess<'de>,
115-
{
116-
let mut jsonrpc = false;
117-
118-
// response & error
119-
let mut id = None;
120-
// only response
121-
let mut result = None;
122-
// only error
123-
let mut error = None;
124-
125-
while let Some(key) = map.next_key()? {
126-
match key {
127-
"jsonrpc" => {
128-
if jsonrpc {
129-
return Err(serde::de::Error::duplicate_field("jsonrpc"));
130-
}
131-
132-
let value = map.next_value()?;
133-
if value != "2.0" {
134-
return Err(serde::de::Error::invalid_value(
135-
serde::de::Unexpected::Str(value),
136-
&"2.0",
137-
));
138-
}
139-
140-
jsonrpc = true;
141-
}
142-
"id" => {
143-
if id.is_some() {
144-
return Err(serde::de::Error::duplicate_field("id"));
145-
}
146-
147-
let value: u64 = map.next_value()?;
148-
id = Some(value);
149-
}
150-
"result" => {
151-
if result.is_some() {
152-
return Err(serde::de::Error::duplicate_field("result"));
153-
}
154-
155-
let value: &RawValue = map.next_value()?;
156-
result = Some(value);
157-
}
158-
"error" => {
159-
if error.is_some() {
160-
return Err(serde::de::Error::duplicate_field("error"));
161-
}
162-
163-
let value: JsonRpcError = map.next_value()?;
164-
error = Some(value);
165-
}
166-
key => {
167-
return Err(serde::de::Error::unknown_field(
168-
key,
169-
&["id", "jsonrpc", "result", "error"],
170-
))
171-
}
172-
}
173-
}
174-
175-
// jsonrpc version must be present in all responses
176-
if !jsonrpc {
177-
return Err(serde::de::Error::missing_field("jsonrpc"));
178-
}
179-
180-
match (id, result, error) {
181-
(Some(id), Some(result), None) => Ok(JsonRpcResponse::Success { id, result }),
182-
(Some(id), None, Some(error)) => Ok(JsonRpcResponse::Error { id, error }),
183-
_ => Err(serde::de::Error::custom(
184-
"response must be either a success/error or notification object",
185-
)),
186-
}
187-
}
188-
}
189-
190-
deserializer.deserialize_map(JsonRpcResponseVisitor(&()))
191-
}
66+
#[derive(Debug, Deserialize)]
67+
pub struct JsonRpcResponse {
68+
pub id: u64,
69+
pub jsonrpc: String,
70+
pub result: Box<RawValue>,
19271
}
19372

19473
/// The basic Ethereum queries that can be used from a smart contract and do not require

0 commit comments

Comments
 (0)