Skip to content

Commit 5d80ef1

Browse files
graph, store: Add option to disable store call cache
Signed-off-by: Maksim Dimitrov <dimitrov.maksim@gmail.com>
1 parent 55b9465 commit 5d80ef1

File tree

5 files changed

+69
-0
lines changed

5 files changed

+69
-0
lines changed

docs/environment-variables.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,7 @@ those.
287287
- `GRAPH_ENABLE_SQL_QUERIES`: Enable the experimental [SQL query
288288
interface](implementation/sql-interface.md).
289289
(default: false)
290+
- `GRAPH_STORE_DISABLE_CALL_CACHE`: Disables the store call cache entirely. Graph node will skip writing and reading from the
291+
call cache. The buffered block call cache will still be enabled. This option may be useful
292+
for indexers who are running their own RPC nodes. Disabling the store call cache may have
293+
significant performance impact. (default: false)

graph/src/env/mod.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ lazy_static! {
2525
lazy_static! {
2626
pub static ref TEST_WITH_NO_REORG: Mutex<bool> = Mutex::new(false);
2727
pub static ref TEST_SQL_QUERIES_ENABLED: Mutex<bool> = Mutex::new(false);
28+
pub static ref TEST_STORE_CALL_CACHE_DISABLED: Mutex<bool> = Mutex::new(false);
2829
}
2930

3031
/// Panics if:
@@ -441,6 +442,25 @@ impl EnvVars {
441442
let mut lock = TEST_SQL_QUERIES_ENABLED.lock().unwrap();
442443
*lock = enable;
443444
}
445+
446+
#[cfg(debug_assertions)]
447+
pub fn store_call_cache_disabled(&self) -> bool {
448+
if *TEST_STORE_CALL_CACHE_DISABLED.lock().unwrap() {
449+
true
450+
} else {
451+
self.store.disable_call_cache
452+
}
453+
}
454+
455+
#[cfg(not(debug_assertions))]
456+
pub fn store_call_cache_disabled(&self) -> bool {
457+
self.store.disable_call_cache
458+
}
459+
460+
#[cfg(debug_assertions)]
461+
pub fn set_store_call_cache_disabled_for_tests(&self, value: bool) {
462+
*TEST_STORE_CALL_CACHE_DISABLED.lock().unwrap() = value;
463+
}
444464
}
445465

446466
impl Default for EnvVars {

graph/src/env/store.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@ pub struct EnvVarsStore {
149149
/// The number of rows to fetch from the foreign data wrapper in one go,
150150
/// this will be set as the option 'fetch_size' on all foreign servers
151151
pub fdw_fetch_size: usize,
152+
/// Disables the store call cache entirely. Graph node will skip writing and reading from the
153+
/// call cache. The buffered block call cache will still be enabled.
154+
/// Set by `GRAPH_STORE_DISABLE_CALL_CACHE`. Defaults to false.
155+
pub disable_call_cache: bool,
152156
}
153157

154158
// This does not print any values avoid accidentally leaking any sensitive env vars
@@ -206,6 +210,7 @@ impl TryFrom<InnerStore> for EnvVarsStore {
206210
disable_block_cache_for_lookup: x.disable_block_cache_for_lookup,
207211
insert_extra_cols: x.insert_extra_cols,
208212
fdw_fetch_size: x.fdw_fetch_size,
213+
disable_call_cache: x.disable_call_cache,
209214
};
210215
if let Some(timeout) = vars.batch_timeout {
211216
if timeout < 2 * vars.batch_target_duration {
@@ -295,6 +300,8 @@ pub struct InnerStore {
295300
insert_extra_cols: usize,
296301
#[envconfig(from = "GRAPH_STORE_FDW_FETCH_SIZE", default = "1000")]
297302
fdw_fetch_size: usize,
303+
#[envconfig(from = "GRAPH_STORE_DISABLE_CALL_CACHE", default = "false")]
304+
disable_call_cache: bool,
298305
}
299306

300307
#[derive(Clone, Copy, Debug)]

store/postgres/src/chain_store.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2960,6 +2960,10 @@ impl EthereumCallCache for ChainStore {
29602960
req: &call::Request,
29612961
block: BlockPtr,
29622962
) -> Result<Option<call::Response>, Error> {
2963+
if ENV_VARS.store_call_cache_disabled() {
2964+
return Ok(None);
2965+
}
2966+
29632967
let id = contract_call_id(req, &block);
29642968
let conn = &mut *self.get_conn()?;
29652969
let return_value = conn.transaction::<_, Error, _>(|conn| {
@@ -3036,6 +3040,10 @@ impl EthereumCallCache for ChainStore {
30363040
block: BlockPtr,
30373041
return_value: call::Retval,
30383042
) -> Result<(), Error> {
3043+
if ENV_VARS.store_call_cache_disabled() {
3044+
return Ok(());
3045+
}
3046+
30393047
let return_value = match return_value {
30403048
call::Retval::Value(return_value) if !return_value.is_empty() => return_value,
30413049
_ => {

store/test-store/tests/postgres/chain_head.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,36 @@ fn eth_call_cache() {
505505
})
506506
}
507507

508+
#[test]
509+
fn test_disable_call_cache() {
510+
let chain = vec![&*GENESIS_BLOCK, &*BLOCK_ONE, &*BLOCK_TWO];
511+
512+
run_test(chain, |store, _| {
513+
ENV_VARS.set_store_call_cache_disabled_for_tests(true);
514+
515+
let logger = LOGGER.cheap_clone();
516+
let address = H160([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5]);
517+
let call: [u8; 6] = [1, 2, 3, 4, 5, 6];
518+
let return_value: [u8; 3] = [7, 8, 9];
519+
520+
let call = call::Request::new(address, call.to_vec(), 0);
521+
522+
store
523+
.set_call(
524+
&logger,
525+
call.cheap_clone(),
526+
BLOCK_ONE.block_ptr(),
527+
call::Retval::Value(Bytes::from(return_value)),
528+
)
529+
.unwrap();
530+
531+
let ret = store.get_call(&call, BLOCK_ONE.block_ptr()).unwrap();
532+
533+
assert!(ret.is_none());
534+
Ok(())
535+
});
536+
}
537+
508538
#[test]
509539
/// Tests mainly query correctness. Requires data in order not to hit early returns when no stale contracts are found.
510540
fn test_clear_stale_call_cache() {

0 commit comments

Comments
 (0)