From f1f403c33f3c74c132b43b02d908e31db1960ac9 Mon Sep 17 00:00:00 2001 From: Maksim Dimitrov Date: Thu, 2 Oct 2025 23:36:09 +0300 Subject: [PATCH] store: Do not cache calls that return 0x Signed-off-by: Maksim Dimitrov --- store/postgres/src/chain_store.rs | 19 +++++++++++++------ store/test-store/tests/postgres/chain_head.rs | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/store/postgres/src/chain_store.rs b/store/postgres/src/chain_store.rs index db83199a56c..8f336185bb6 100644 --- a/store/postgres/src/chain_store.rs +++ b/store/postgres/src/chain_store.rs @@ -2839,13 +2839,20 @@ impl EthereumCallCache for ChainStore { block: BlockPtr, return_value: call::Retval, ) -> Result<(), Error> { - let call::Retval::Value(return_value) = return_value else { - // We do not want to cache unsuccessful calls as some RPC nodes - // have weird behavior near the chain head. The details are lost - // to time, but we had issues with some RPC clients in the past - // where calls first failed and later succeeded - return Ok(()); + let return_value = match return_value { + call::Retval::Value(return_value) if !return_value.is_empty() => return_value, + _ => { + // We do not want to cache unsuccessful calls as some RPC nodes + // have weird behavior near the chain head. The details are lost + // to time, but we had issues with some RPC clients in the past + // where calls first failed and later succeeded + // Also in some cases RPC nodes may return empty ("0x") values + // which in the context of graph-node most likely means an issue + // with the RPC node rather than a successful call. + return Ok(()); + } }; + let id = contract_call_id(&call, &block); let conn = &mut *self.get_conn()?; conn.transaction(|conn| { diff --git a/store/test-store/tests/postgres/chain_head.rs b/store/test-store/tests/postgres/chain_head.rs index cf501f1438f..a46f4fecb3d 100644 --- a/store/test-store/tests/postgres/chain_head.rs +++ b/store/test-store/tests/postgres/chain_head.rs @@ -475,6 +475,7 @@ fn eth_call_cache() { .unwrap(); assert_eq!(&new_return_value, ret.as_slice()); + // Reverted calls should not be cached store .set_call( &logger, @@ -486,6 +487,19 @@ fn eth_call_cache() { let ret = store.get_call(&call, BLOCK_THREE.block_ptr()).unwrap(); assert_eq!(None, ret); + // Empty return values should not be cached + let return_value: [u8; 0] = []; + store + .set_call( + &logger, + call.cheap_clone(), + BLOCK_FOUR.block_ptr(), + ccr(&return_value), + ) + .unwrap(); + let ret = store.get_call(&call, BLOCK_FOUR.block_ptr()).unwrap(); + assert_eq!(None, ret); + Ok(()) }) }