Skip to content

Commit d54e858

Browse files
graph, store: Add option to disable store call cache
Signed-off-by: Maksim Dimitrov <[email protected]>
1 parent 06d3247 commit d54e858

File tree

5 files changed

+69
-1
lines changed

5 files changed

+69
-1
lines changed

docs/environment-variables.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,3 +294,7 @@ those.
294294
`GRAPH_STORE_ACCOUNT_LIKE_MIN_VERSIONS_COUNT` and `GRAPH_STORE_ACCOUNT_LIKE_MAX_UNIQUE_RATIO`.
295295
- `GRAPH_STORE_ACCOUNT_LIKE_MIN_VERSIONS_COUNT`: Sets the minimum total number of versions a table must have to be considered for account-like flagging. Expects a positive integer value. No default value.
296296
- `GRAPH_STORE_ACCOUNT_LIKE_MAX_UNIQUE_RATIO`: Sets the maximum unique entities to version ratio (e.g., 0.01 ≈ 1:100 entity-to-version ratio).
297+
- `GRAPH_STORE_DISABLE_CALL_CACHE`: Disables the store call cache entirely. Graph node will skip writing and reading from the
298+
call cache. The buffered block call cache will still be enabled. This option may be useful
299+
for indexers who are running their own RPC nodes. Disabling the store call cache may have
300+
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 & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ 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-
153152
/// Experimental feature to automatically set the account-like flag on eligible tables
154153
/// Set by the environment variable `GRAPH_STORE_ACCOUNT_LIKE_SCAN_INTERVAL_HOURS`
155154
/// If not set, the job is disabled.
@@ -161,6 +160,10 @@ pub struct EnvVarsStore {
161160
/// Set by the environment variable `GRAPH_STORE_ACCOUNT_LIKE_MAX_UNIQUE_RATIO`
162161
/// Defines the maximum share of unique entities (e.g. 0.01 for a 1:100 entity-to-version ratio).
163162
pub account_like_max_unique_ratio: Option<f64>,
163+
/// Disables the store call cache entirely. Graph node will skip writing and reading from the
164+
/// call cache. The buffered block call cache will still be enabled.
165+
/// Set by `GRAPH_STORE_DISABLE_CALL_CACHE`. Defaults to false.
166+
pub disable_call_cache: bool,
164167
}
165168

166169
// This does not print any values avoid accidentally leaking any sensitive env vars
@@ -221,6 +224,7 @@ impl TryFrom<InnerStore> for EnvVarsStore {
221224
account_like_scan_interval_hours: x.account_like_scan_interval_hours,
222225
account_like_min_versions_count: x.account_like_min_versions_count,
223226
account_like_max_unique_ratio: x.account_like_max_unique_ratio.map(|r| r.0),
227+
disable_call_cache: x.disable_call_cache,
224228
};
225229
if let Some(timeout) = vars.batch_timeout {
226230
if timeout < 2 * vars.batch_target_duration {
@@ -326,6 +330,8 @@ pub struct InnerStore {
326330
account_like_min_versions_count: Option<u64>,
327331
#[envconfig(from = "GRAPH_STORE_ACCOUNT_LIKE_MAX_UNIQUE_RATIO")]
328332
account_like_max_unique_ratio: Option<ZeroToOneF64>,
333+
#[envconfig(from = "GRAPH_STORE_DISABLE_CALL_CACHE", default = "false")]
334+
disable_call_cache: bool,
329335
}
330336

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

store/postgres/src/chain_store.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3103,6 +3103,10 @@ impl EthereumCallCache for ChainStore {
31033103
req: &call::Request,
31043104
block: BlockPtr,
31053105
) -> Result<Option<call::Response>, Error> {
3106+
if ENV_VARS.store_call_cache_disabled() {
3107+
return Ok(None);
3108+
}
3109+
31063110
let id = contract_call_id(req, &block);
31073111
let conn = &mut self.pool.get_permitted().await?;
31083112
let return_value = conn
@@ -3193,6 +3197,10 @@ impl EthereumCallCache for ChainStore {
31933197
block: BlockPtr,
31943198
return_value: call::Retval,
31953199
) -> Result<(), Error> {
3200+
if ENV_VARS.store_call_cache_disabled() {
3201+
return Ok(());
3202+
}
3203+
31963204
let return_value = match return_value {
31973205
call::Retval::Value(return_value) if !return_value.is_empty() => return_value,
31983206
_ => {

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,36 @@ fn eth_call_cache() {
529529
})
530530
}
531531

532+
#[test]
533+
fn test_disable_call_cache() {
534+
let chain = vec![&*GENESIS_BLOCK, &*BLOCK_ONE, &*BLOCK_TWO];
535+
536+
run_test(chain, |store, _| {
537+
ENV_VARS.set_store_call_cache_disabled_for_tests(true);
538+
539+
let logger = LOGGER.cheap_clone();
540+
let address = H160([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5]);
541+
let call: [u8; 6] = [1, 2, 3, 4, 5, 6];
542+
let return_value: [u8; 3] = [7, 8, 9];
543+
544+
let call = call::Request::new(address, call.to_vec(), 0);
545+
546+
store
547+
.set_call(
548+
&logger,
549+
call.cheap_clone(),
550+
BLOCK_ONE.block_ptr(),
551+
call::Retval::Value(Bytes::from(return_value)),
552+
)
553+
.unwrap();
554+
555+
let ret = store.get_call(&call, BLOCK_ONE.block_ptr()).unwrap();
556+
557+
assert!(ret.is_none());
558+
Ok(())
559+
});
560+
}
561+
532562
#[test]
533563
/// Tests mainly query correctness. Requires data in order not to hit early returns when no stale contracts are found.
534564
fn test_clear_stale_call_cache() {

0 commit comments

Comments
 (0)