Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,3 +287,7 @@ those.
- `GRAPH_ENABLE_SQL_QUERIES`: Enable the experimental [SQL query
interface](implementation/sql-interface.md).
(default: false)
- `GRAPH_STORE_DISABLE_CALL_CACHE`: Disables the store call cache entirely. Graph node will skip writing and reading from the
call cache. The buffered block call cache will still be enabled. This option may be useful
for indexers who are running their own RPC nodes. Disabling the store call cache may have
significant performance impact. (default: false)
20 changes: 20 additions & 0 deletions graph/src/env/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ lazy_static! {
lazy_static! {
pub static ref TEST_WITH_NO_REORG: Mutex<bool> = Mutex::new(false);
pub static ref TEST_SQL_QUERIES_ENABLED: Mutex<bool> = Mutex::new(false);
pub static ref TEST_STORE_CALL_CACHE_DISABLED: Mutex<bool> = Mutex::new(false);
}

/// Panics if:
Expand Down Expand Up @@ -441,6 +442,25 @@ impl EnvVars {
let mut lock = TEST_SQL_QUERIES_ENABLED.lock().unwrap();
*lock = enable;
}

#[cfg(debug_assertions)]
pub fn store_call_cache_disabled(&self) -> bool {
if *TEST_STORE_CALL_CACHE_DISABLED.lock().unwrap() {
true
} else {
self.store.disable_call_cache
}
}

#[cfg(not(debug_assertions))]
pub fn store_call_cache_disabled(&self) -> bool {
self.store.disable_call_cache
}

#[cfg(debug_assertions)]
pub fn set_store_call_cache_disabled_for_tests(&self, value: bool) {
*TEST_STORE_CALL_CACHE_DISABLED.lock().unwrap() = value;
}
}

impl Default for EnvVars {
Expand Down
7 changes: 7 additions & 0 deletions graph/src/env/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ pub struct EnvVarsStore {
/// The number of rows to fetch from the foreign data wrapper in one go,
/// this will be set as the option 'fetch_size' on all foreign servers
pub fdw_fetch_size: usize,
/// Disables the store call cache entirely. Graph node will skip writing and reading from the
/// call cache. The buffered block call cache will still be enabled.
/// Set by `GRAPH_STORE_DISABLE_CALL_CACHE`. Defaults to false.
pub disable_call_cache: bool,
}

// This does not print any values avoid accidentally leaking any sensitive env vars
Expand Down Expand Up @@ -206,6 +210,7 @@ impl TryFrom<InnerStore> for EnvVarsStore {
disable_block_cache_for_lookup: x.disable_block_cache_for_lookup,
insert_extra_cols: x.insert_extra_cols,
fdw_fetch_size: x.fdw_fetch_size,
disable_call_cache: x.disable_call_cache,
};
if let Some(timeout) = vars.batch_timeout {
if timeout < 2 * vars.batch_target_duration {
Expand Down Expand Up @@ -295,6 +300,8 @@ pub struct InnerStore {
insert_extra_cols: usize,
#[envconfig(from = "GRAPH_STORE_FDW_FETCH_SIZE", default = "1000")]
fdw_fetch_size: usize,
#[envconfig(from = "GRAPH_STORE_DISABLE_CALL_CACHE", default = "false")]
disable_call_cache: bool,
}

#[derive(Clone, Copy, Debug)]
Expand Down
8 changes: 8 additions & 0 deletions store/postgres/src/chain_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2960,6 +2960,10 @@ impl EthereumCallCache for ChainStore {
req: &call::Request,
block: BlockPtr,
) -> Result<Option<call::Response>, Error> {
if ENV_VARS.store_call_cache_disabled() {
return Ok(None);
}

let id = contract_call_id(req, &block);
let conn = &mut *self.get_conn()?;
let return_value = conn.transaction::<_, Error, _>(|conn| {
Expand Down Expand Up @@ -3036,6 +3040,10 @@ impl EthereumCallCache for ChainStore {
block: BlockPtr,
return_value: call::Retval,
) -> Result<(), Error> {
if ENV_VARS.store_call_cache_disabled() {
return Ok(());
}

let return_value = match return_value {
call::Retval::Value(return_value) if !return_value.is_empty() => return_value,
_ => {
Expand Down
30 changes: 30 additions & 0 deletions store/test-store/tests/postgres/chain_head.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,36 @@ fn eth_call_cache() {
})
}

#[test]
fn test_disable_call_cache() {
let chain = vec![&*GENESIS_BLOCK, &*BLOCK_ONE, &*BLOCK_TWO];

run_test(chain, |store, _| {
ENV_VARS.set_store_call_cache_disabled_for_tests(true);

let logger = LOGGER.cheap_clone();
let address = H160([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5]);
let call: [u8; 6] = [1, 2, 3, 4, 5, 6];
let return_value: [u8; 3] = [7, 8, 9];

let call = call::Request::new(address, call.to_vec(), 0);

store
.set_call(
&logger,
call.cheap_clone(),
BLOCK_ONE.block_ptr(),
call::Retval::Value(Bytes::from(return_value)),
)
.unwrap();

let ret = store.get_call(&call, BLOCK_ONE.block_ptr()).unwrap();

assert!(ret.is_none());
Ok(())
});
}

#[test]
/// Tests mainly query correctness. Requires data in order not to hit early returns when no stale contracts are found.
fn test_clear_stale_call_cache() {
Expand Down
Loading