fix: parse 66 blockid str as hash (#1890)

This commit is contained in:
Matthias Seitz
2023-03-21 22:36:06 +01:00
committed by GitHub
parent 02e78c4bd7
commit 724ec1b5cc
5 changed files with 54 additions and 3 deletions

5
Cargo.lock generated
View File

@@ -5184,6 +5184,7 @@ dependencies = [
"reth-tracing",
"reth-transaction-pool",
"serde",
"serde_json",
"strum",
"thiserror",
"tokio",
@@ -5836,9 +5837,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.93"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76"
checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea"
dependencies = [
"itoa",
"ryu",

View File

@@ -328,7 +328,14 @@ impl<'de> Deserialize<'de> for BlockId {
where
E: serde::de::Error,
{
Ok(BlockId::Number(v.parse().map_err(serde::de::Error::custom)?))
// Since there is no way to clearly distinguish between a DATA parameter and a QUANTITY parameter. A str is therefor deserialized into a Block Number: <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1898.md>
// However, since the hex string should be a QUANTITY, we can safely assume that if the len is 66 bytes, it is in fact a hash, ref <https://github.com/ethereum/go-ethereum/blob/ee530c0d5aa70d2c00ab5691a89ab431b73f8165/rpc/types.go#L184-L184>
if v.len() == 66 {
Ok(BlockId::Hash(v.parse::<H256>().map_err(serde::de::Error::custom)?.into()))
} else {
// quantity hex string or tag
Ok(BlockId::Number(v.parse().map_err(serde::de::Error::custom)?))
}
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
@@ -623,6 +630,7 @@ impl BlockBody {
#[cfg(test)]
mod test {
use super::{BlockId, BlockNumberOrTag::*, *};
/// Check parsing according to EIP-1898.
#[test]
fn can_parse_blockid_u64() {
@@ -684,6 +692,7 @@ mod test {
assert_eq!(deserialized, *block_id)
}
}
#[test]
fn serde_blockid_number() {
let block_id = BlockId::from(100u64);
@@ -691,6 +700,7 @@ mod test {
let deserialized: BlockId = serde_json::from_str(&serialized).unwrap();
assert_eq!(deserialized, block_id)
}
#[test]
fn serde_blockid_hash() {
let block_id = BlockId::from(H256::default());
@@ -698,6 +708,15 @@ mod test {
let deserialized: BlockId = serde_json::from_str(&serialized).unwrap();
assert_eq!(deserialized, block_id)
}
#[test]
fn serde_blockid_hash_from_str() {
let val = "\"0x898753d8fdd8d92c1907ca21e68c7970abd290c647a202091181deec3f30a0b2\"";
let block_hash: H256 = serde_json::from_str(val).unwrap();
let block_id: BlockId = serde_json::from_str(val).unwrap();
assert_eq!(block_id, BlockId::Hash(block_hash.into()));
}
#[test]
fn serde_rpc_payload_block_tag() {
let payload = r#"{"method":"eth_call","params":[{"to":"0xebe8efa441b9302a0d7eaecc277c09d20d684540","data":"0x45848dfc"},"latest"],"id":1,"jsonrpc":"2.0"}"#;

View File

@@ -36,3 +36,4 @@ reth-provider = { path = "../../storage/provider", features = ["test-utils"] }
reth-network-api = { path = "../../net/network-api", features = ["test-utils"] }
tokio = { version = "1", features = ["rt", "rt-multi-thread"] }
serde_json = "1.0.94"

View File

@@ -1,4 +1,5 @@
mod http;
mod serde;
pub mod utils;
fn main() {}

View File

@@ -0,0 +1,29 @@
//! various serde test
use crate::utils::launch_http;
use jsonrpsee::{
core::{client::ClientT, traits::ToRpcParams, Error},
types::Request,
};
use reth_primitives::U256;
use reth_rpc_builder::RethRpcModule;
use serde_json::value::RawValue;
struct RawRpcParams(Box<RawValue>);
impl ToRpcParams for RawRpcParams {
fn to_rpc_params(self) -> Result<Option<Box<RawValue>>, Error> {
Ok(Some(self.0))
}
}
#[tokio::test(flavor = "multi_thread")]
async fn test_eth_balance_serde() {
let handle = launch_http(vec![RethRpcModule::Eth]).await;
let s = r#"{"jsonrpc":"2.0","id":1,"method":"eth_getBalance","params":["0xaa00000000000000000000000000000000000000","0x898753d8fdd8d92c1907ca21e68c7970abd290c647a202091181deec3f30a0b2"]}"#;
let req: Request = serde_json::from_str(s).unwrap();
let client = handle.http_client().unwrap();
let params = RawRpcParams(RawValue::from_string(req.params.unwrap().to_string()).unwrap());
client.request::<U256, _>("eth_getBalance", params).await.unwrap();
}