don't cache nulls

This commit is contained in:
Bryan Stitt 2023-07-31 14:26:07 -07:00
parent 2885bc6ef2
commit 7cd91af3a8
6 changed files with 37 additions and 4 deletions

2
Cargo.lock generated

@ -7219,7 +7219,7 @@ dependencies = [
[[package]] [[package]]
name = "web3_proxy" name = "web3_proxy"
version = "1.42.0" version = "1.42.1"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"arc-swap", "arc-swap",

@ -1,6 +1,6 @@
[package] [package]
name = "web3_proxy" name = "web3_proxy"
version = "1.42.0" version = "1.42.1"
edition = "2021" edition = "2021"
default-run = "web3_proxy_cli" default-run = "web3_proxy_cli"

@ -1731,11 +1731,17 @@ impl Web3ProxyApp {
// return all the errors now. moka will not cache Err results // return all the errors now. moka will not cache Err results
Err(err) Err(err)
} else { } else {
// convert jsonrpc errors into JsonRpcResponseEnum, but leave the rest as errors
let response_data: JsonRpcResponseEnum<Arc<RawValue>> = response_data.try_into()?; let response_data: JsonRpcResponseEnum<Arc<RawValue>> = response_data.try_into()?;
if response_data.is_null() {
// don't ever cache "null" as a success. its too likely to be a problem
Err(Web3ProxyError::NullJsonRpcResult)
} else {
// TODO: response data should maybe be Arc<JsonRpcResponseEnum<Box<RawValue>>>, but that's more work // TODO: response data should maybe be Arc<JsonRpcResponseEnum<Box<RawValue>>>, but that's more work
Ok(response_data) Ok(response_data)
} }
}
}).await? }).await?
} else { } else {
let x = timeout( let x = timeout(

@ -124,6 +124,8 @@ pub enum Web3ProxyError {
#[from(ignore)] #[from(ignore)]
NotImplemented(Cow<'static, str>), NotImplemented(Cow<'static, str>),
NoVolatileRedisDatabase, NoVolatileRedisDatabase,
/// make it easy to skip caching null results
NullJsonRpcResult,
OriginRequired, OriginRequired,
#[error(ignore)] #[error(ignore)]
#[from(ignore)] #[from(ignore)]
@ -759,6 +761,9 @@ impl Web3ProxyError {
}, },
) )
} }
Self::NullJsonRpcResult => {
return (StatusCode::OK, JsonRpcResponseEnum::NullResult);
}
Self::OriginRequired => { Self::OriginRequired => {
trace!("OriginRequired"); trace!("OriginRequired");
( (

@ -366,6 +366,10 @@ impl JsonRpcForwardedResponse {
pub fn from_response_data(data: JsonRpcResponseEnum<Arc<RawValue>>, id: Box<RawValue>) -> Self { pub fn from_response_data(data: JsonRpcResponseEnum<Arc<RawValue>>, id: Box<RawValue>) -> Self {
match data { match data {
JsonRpcResponseEnum::NullResult => {
let x: Box<RawValue> = Default::default();
Self::from_raw_response(x.into(), id)
}
JsonRpcResponseEnum::Result { value, .. } => Self::from_raw_response(value, id), JsonRpcResponseEnum::Result { value, .. } => Self::from_raw_response(value, id),
JsonRpcResponseEnum::RpcError { JsonRpcResponseEnum::RpcError {
error_data: value, .. error_data: value, ..

@ -89,6 +89,7 @@ pub type JsonRpcResponseCache = Cache<u64, JsonRpcResponseEnum<Arc<RawValue>>>;
/// TODO: we might need one that holds RawValue and one that holds serde_json::Value /// TODO: we might need one that holds RawValue and one that holds serde_json::Value
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum JsonRpcResponseEnum<R> { pub enum JsonRpcResponseEnum<R> {
NullResult,
Result { Result {
value: R, value: R,
num_bytes: u32, num_bytes: u32,
@ -103,12 +104,29 @@ pub enum JsonRpcResponseEnum<R> {
impl<R> JsonRpcResponseEnum<R> { impl<R> JsonRpcResponseEnum<R> {
pub fn num_bytes(&self) -> u32 { pub fn num_bytes(&self) -> u32 {
match self { match self {
Self::NullResult => 1,
Self::Result { num_bytes, .. } => *num_bytes, Self::Result { num_bytes, .. } => *num_bytes,
Self::RpcError { num_bytes, .. } => *num_bytes, Self::RpcError { num_bytes, .. } => *num_bytes,
} }
} }
} }
impl<R> JsonRpcResponseEnum<Option<R>> {
pub fn is_null(&self) -> bool {
matches!(self, Self::NullResult | Self::Result { value: None, .. })
}
}
impl JsonRpcResponseEnum<Arc<RawValue>> {
pub fn is_null(&self) -> bool {
match self {
Self::NullResult => true,
Self::Result { value, .. } => value.get() == "null",
_ => false,
}
}
}
impl From<serde_json::Value> for JsonRpcResponseEnum<Arc<RawValue>> { impl From<serde_json::Value> for JsonRpcResponseEnum<Arc<RawValue>> {
fn from(value: serde_json::Value) -> Self { fn from(value: serde_json::Value) -> Self {
let value = RawValue::from_string(value.to_string()).unwrap(); let value = RawValue::from_string(value.to_string()).unwrap();