Skip to content

Commit bbcaefd

Browse files
Feat: Add option to disable store call cache (#6214)
* graph, store: Add option to disable store call cache Signed-off-by: Maksim Dimitrov <[email protected]> * store: Update test to async Signed-off-by: Maksim Dimitrov <[email protected]> * docs: small doc touch-up Signed-off-by: Maksim Dimitrov <[email protected]> * graph: Update inline docs Signed-off-by: Maksim Dimitrov <[email protected]> --------- Signed-off-by: Maksim Dimitrov <[email protected]>
1 parent 7e8d1f0 commit bbcaefd

File tree

5 files changed

+80
-4
lines changed

5 files changed

+80
-4
lines changed

docs/environment-variables.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,15 @@ those.
290290
- `GRAPH_STORE_ACCOUNT_LIKE_SCAN_INTERVAL_HOURS`: If set, enables an experimental job that
291291
periodically scans for entity tables that may benefit from an [account-like optimization](https://thegraph.com/docs/en/indexing/tooling/graph-node/#account-like-optimisation) and marks them with an
292292
account-like flag. The value is the interval in hours at which the job
293-
should run. The job reads data from the `info.table_stats` materialized view, which refreshes every six hours. Expects an integer value, e.g., 24. Requires also setting
293+
should run. The job reads data from the `info.table_stats` materialized view, which refreshes every six hours.
294+
Expects an integer value, e.g., 24. Requires also setting
294295
`GRAPH_STORE_ACCOUNT_LIKE_MIN_VERSIONS_COUNT` and `GRAPH_STORE_ACCOUNT_LIKE_MAX_UNIQUE_RATIO`.
295-
- `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.
296-
- `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).
296+
- `GRAPH_STORE_ACCOUNT_LIKE_MIN_VERSIONS_COUNT`: Sets the minimum total number of versions a table must have
297+
to be considered for account-like flagging. Expects a positive integer value. No default value.
298+
- `GRAPH_STORE_ACCOUNT_LIKE_MAX_UNIQUE_RATIO`: Sets the maximum unique entities to version ratio
299+
(e.g., 0.01 ≈ 1:100 entity-to-version ratio).
300+
- `GRAPH_STORE_DISABLE_CALL_CACHE`: Disables storing or reading `eth_call` results from the store call cache.
301+
This option may be useful for indexers who are running their own RPC nodes.
302+
Disabling the store call cache may significantly impact performance; the actual impact depends on
303+
the average execution time of an `eth_call` compared to the cost of a database lookup for a cached result.
304+
(default: false)

graph/src/env/mod.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ lazy_static! {
2929
lazy_static! {
3030
pub static ref TEST_WITH_NO_REORG: Mutex<bool> = Mutex::new(false);
3131
pub static ref TEST_SQL_QUERIES_ENABLED: Mutex<bool> = Mutex::new(false);
32+
pub static ref TEST_STORE_CALL_CACHE_DISABLED: Mutex<bool> = Mutex::new(false);
3233
}
3334

3435
/// Panics if:
@@ -444,6 +445,25 @@ impl EnvVars {
444445
let mut lock = TEST_SQL_QUERIES_ENABLED.lock().unwrap();
445446
*lock = enable;
446447
}
448+
449+
#[cfg(debug_assertions)]
450+
pub fn store_call_cache_disabled(&self) -> bool {
451+
if *TEST_STORE_CALL_CACHE_DISABLED.lock().unwrap() {
452+
true
453+
} else {
454+
self.store.disable_call_cache
455+
}
456+
}
457+
458+
#[cfg(not(debug_assertions))]
459+
pub fn store_call_cache_disabled(&self) -> bool {
460+
self.store.disable_call_cache
461+
}
462+
463+
#[cfg(debug_assertions)]
464+
pub fn set_store_call_cache_disabled_for_tests(&self, value: bool) {
465+
*TEST_STORE_CALL_CACHE_DISABLED.lock().unwrap() = value;
466+
}
447467
}
448468

449469
impl Default for EnvVars {

graph/src/env/store.rs

Lines changed: 6 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,9 @@ 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 storing or reading `eth_call` results from the store call cache.
164+
/// Set by `GRAPH_STORE_DISABLE_CALL_CACHE`. Defaults to false.
165+
pub disable_call_cache: bool,
164166
}
165167

166168
// This does not print any values avoid accidentally leaking any sensitive env vars
@@ -221,6 +223,7 @@ impl TryFrom<InnerStore> for EnvVarsStore {
221223
account_like_scan_interval_hours: x.account_like_scan_interval_hours,
222224
account_like_min_versions_count: x.account_like_min_versions_count,
223225
account_like_max_unique_ratio: x.account_like_max_unique_ratio.map(|r| r.0),
226+
disable_call_cache: x.disable_call_cache,
224227
};
225228
if let Some(timeout) = vars.batch_timeout {
226229
if timeout < 2 * vars.batch_target_duration {
@@ -326,6 +329,8 @@ pub struct InnerStore {
326329
account_like_min_versions_count: Option<u64>,
327330
#[envconfig(from = "GRAPH_STORE_ACCOUNT_LIKE_MAX_UNIQUE_RATIO")]
328331
account_like_max_unique_ratio: Option<ZeroToOneF64>,
332+
#[envconfig(from = "GRAPH_STORE_DISABLE_CALL_CACHE", default = "false")]
333+
disable_call_cache: bool,
329334
}
330335

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

store/postgres/src/chain_store.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3081,6 +3081,10 @@ impl EthereumCallCache for ChainStore {
30813081
req: &call::Request,
30823082
block: BlockPtr,
30833083
) -> Result<Option<call::Response>, Error> {
3084+
if ENV_VARS.store_call_cache_disabled() {
3085+
return Ok(None);
3086+
}
3087+
30843088
let id = contract_call_id(req, &block);
30853089
let conn = &mut self.pool.get_permitted().await?;
30863090
let return_value = conn
@@ -3171,6 +3175,10 @@ impl EthereumCallCache for ChainStore {
31713175
block: BlockPtr,
31723176
return_value: call::Retval,
31733177
) -> Result<(), Error> {
3178+
if ENV_VARS.store_call_cache_disabled() {
3179+
return Ok(());
3180+
}
3181+
31743182
let return_value = match return_value {
31753183
call::Retval::Value(return_value) if !return_value.is_empty() => return_value,
31763184
_ => {

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,41 @@ 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_async(chain, |store, _, _| async move {
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+
.cheap_clone()
548+
.set_call(
549+
&logger,
550+
call.cheap_clone(),
551+
BLOCK_ONE.block_ptr(),
552+
call::Retval::Value(Bytes::from(return_value)),
553+
)
554+
.await
555+
.unwrap();
556+
557+
let ret = store
558+
.cheap_clone()
559+
.get_call(&call, BLOCK_ONE.block_ptr())
560+
.await
561+
.unwrap();
562+
563+
assert!(ret.is_none());
564+
});
565+
}
566+
532567
#[test]
533568
/// Tests mainly query correctness. Requires data in order not to hit early returns when no stale contracts are found.
534569
fn test_clear_stale_call_cache() {

0 commit comments

Comments
 (0)