improve CacheMode on eth_getLogs

This commit is contained in:
Bryan Stitt 2023-10-27 15:41:24 -07:00
parent d50a7a06d9
commit 47d2a62555
5 changed files with 163 additions and 87 deletions

98
Cargo.lock generated
View File

@ -1005,13 +1005,14 @@ dependencies = [
[[package]] [[package]]
name = "const-hex" name = "const-hex"
version = "1.9.1" version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c37be52ef5e3b394db27a2341010685ad5103c72ac15ce2e9420a7e8f93f342c" checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures",
"hex", "hex",
"proptest",
"serde", "serde",
] ]
@ -1752,7 +1753,7 @@ dependencies = [
"ethabi", "ethabi",
"generic-array", "generic-array",
"k256", "k256",
"num_enum 0.7.0", "num_enum 0.7.1",
"once_cell", "once_cell",
"open-fastrlp", "open-fastrlp",
"rand 0.8.5", "rand 0.8.5",
@ -3290,11 +3291,11 @@ dependencies = [
[[package]] [[package]]
name = "num_enum" name = "num_enum"
version = "0.7.0" version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb" checksum = "683751d591e6d81200c39fb0d1032608b77724f34114db54f571ff1317b337c0"
dependencies = [ dependencies = [
"num_enum_derive 0.7.0", "num_enum_derive 0.7.1",
] ]
[[package]] [[package]]
@ -3311,11 +3312,11 @@ dependencies = [
[[package]] [[package]]
name = "num_enum_derive" name = "num_enum_derive"
version = "0.7.0" version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597" checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e"
dependencies = [ dependencies = [
"proc-macro-crate 1.3.1", "proc-macro-crate 2.0.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.38", "syn 2.0.38",
@ -3870,6 +3871,15 @@ dependencies = [
"toml_edit 0.19.15", "toml_edit 0.19.15",
] ]
[[package]]
name = "proc-macro-crate"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8"
dependencies = [
"toml_edit 0.20.7",
]
[[package]] [[package]]
name = "proc-macro-error" name = "proc-macro-error"
version = "1.0.4" version = "1.0.4"
@ -3909,6 +3919,22 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "proptest"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c003ac8c77cb07bb74f5f198bce836a689bcd5a42574612bf14d17bfd08c20e"
dependencies = [
"bitflags 2.4.1",
"lazy_static",
"num-traits",
"rand 0.8.5",
"rand_chacha 0.3.1",
"rand_xorshift",
"regex-syntax 0.7.5",
"unarray",
]
[[package]] [[package]]
name = "prost" name = "prost"
version = "0.12.1" version = "0.12.1"
@ -4076,6 +4102,15 @@ dependencies = [
"rand_core 0.5.1", "rand_core 0.5.1",
] ]
[[package]]
name = "rand_xorshift"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f"
dependencies = [
"rand_core 0.6.4",
]
[[package]] [[package]]
name = "ratatui" name = "ratatui"
version = "0.20.1" version = "0.20.1"
@ -4195,15 +4230,6 @@ dependencies = [
"bitflags 1.3.2", "bitflags 1.3.2",
] ]
[[package]]
name = "redox_syscall"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [
"bitflags 1.3.2",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.4.1" version = "0.4.1"
@ -4491,9 +4517,9 @@ dependencies = [
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.20" version = "0.38.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0" checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"
dependencies = [ dependencies = [
"bitflags 2.4.1", "bitflags 2.4.1",
"errno", "errno",
@ -5741,13 +5767,13 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.8.0" version = "3.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand 2.0.1", "fastrand 2.0.1",
"redox_syscall 0.3.5", "redox_syscall 0.4.1",
"rustix", "rustix",
"windows-sys", "windows-sys",
] ]
@ -6027,14 +6053,14 @@ dependencies = [
[[package]] [[package]]
name = "toml" name = "toml"
version = "0.8.5" version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3efaf127c78d5339cc547cce4e4d973bd5e4f56e949a06d091c082ebeef2f800" checksum = "8ff9e3abce27ee2c9a37f9ad37238c1bdd4e789c84ba37df76aa4d528f5072cc"
dependencies = [ dependencies = [
"serde", "serde",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
"toml_edit 0.20.5", "toml_edit 0.20.7",
] ]
[[package]] [[package]]
@ -6061,9 +6087,9 @@ dependencies = [
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.20.5" version = "0.20.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "782bf6c2ddf761c1e7855405e8975472acf76f7f36d0d4328bd3b7a2fae12a85" checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81"
dependencies = [ dependencies = [
"indexmap 2.0.2", "indexmap 2.0.2",
"serde", "serde",
@ -6309,6 +6335,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "unarray"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
[[package]] [[package]]
name = "unicase" name = "unicase"
version = "2.7.0" version = "2.7.0"
@ -6656,7 +6688,7 @@ dependencies = [
"time", "time",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"toml 0.8.5", "toml 0.8.6",
"tower-http", "tower-http",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
@ -6864,18 +6896,18 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
[[package]] [[package]]
name = "zerocopy" name = "zerocopy"
version = "0.7.15" version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81ba595b9f2772fbee2312de30eeb80ec773b4cb2f1e8098db024afadda6c06f" checksum = "ede7d7c7970ca2215b8c1ccf4d4f354c4733201dfaaba72d44ae5b37472e4901"
dependencies = [ dependencies = [
"zerocopy-derive", "zerocopy-derive",
] ]
[[package]] [[package]]
name = "zerocopy-derive" name = "zerocopy-derive"
version = "0.7.15" version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "772666c41fb6dceaf520b564b962d738a8e1a83b41bd48945f50837aed78bb1d" checksum = "4b27b1bb92570f989aac0ab7e9cbfbacdd65973f7ee920d9f0e71ebac878fd0b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View File

@ -86,7 +86,7 @@ strum = { version = "0.25.0", features = ["derive"] }
time = { version = "0.3" } time = { version = "0.3" }
tokio = { version = "1.33.0", features = ["full", "tracing"] } tokio = { version = "1.33.0", features = ["full", "tracing"] }
tokio-stream = { version = "0.1.14", features = ["sync"] } tokio-stream = { version = "0.1.14", features = ["sync"] }
toml = "0.8.5" toml = "0.8.6"
tower-http = { version = "0.4.4", features = ["cors", "normalize-path", "sensitive-headers", "trace"] } tower-http = { version = "0.4.4", features = ["cors", "normalize-path", "sensitive-headers", "trace"] }
tracing = "0.1" tracing = "0.1"
ulid = { version = "1.1.0", features = ["rand", "uuid", "serde"] } ulid = { version = "1.1.0", features = ["rand", "uuid", "serde"] }

View File

@ -46,9 +46,11 @@ pub fn BlockNumber_to_U64(block_num: BlockNumber, latest_block: U64) -> (U64, bo
pub struct BlockNumAndHash(U64, H256); pub struct BlockNumAndHash(U64, H256);
impl BlockNumAndHash { impl BlockNumAndHash {
pub fn num(&self) -> &U64 { #[inline]
&self.0 pub fn num(&self) -> U64 {
self.0
} }
#[inline]
pub fn hash(&self) -> &H256 { pub fn hash(&self) -> &H256 {
&self.1 &self.1
} }
@ -103,7 +105,7 @@ pub async fn clean_block_number<'a>(
if block_hash == *head_block.hash() { if block_hash == *head_block.hash() {
(head_block.into(), false) (head_block.into(), false)
} else if let Some(app) = app { } else if let Some(app) = app {
// TODO: query for the block // TODO: make a jsonrpc query here? cache rates will be better but it adds a network request
let block = app let block = app
.balanced_rpcs .balanced_rpcs
.blocks_by_hash .blocks_by_hash
@ -137,7 +139,7 @@ pub async fn clean_block_number<'a>(
if block_hash == *head_block.hash() { if block_hash == *head_block.hash() {
(head_block.number(), false) (head_block.number(), false)
} else if let Some(app) = app { } else if let Some(app) = app {
// TODO: what should this max_wait be? // TODO: make a jsonrpc query here? cache rates will be better but it adds a network request
let block = app let block = app
.balanced_rpcs .balanced_rpcs
.blocks_by_hash .blocks_by_hash
@ -172,7 +174,7 @@ pub async fn clean_block_number<'a>(
if block_num == head_block_num { if block_num == head_block_num {
(head_block.into(), changed) (head_block.into(), changed)
} else if let Some(app) = app { } else if let Some(app) = app {
// TODO: we used to make a query here, but thats causing problems with recursion now. come back to this // TODO: make a jsonrpc query here? cache rates will be better but it adds a network request
let block_hash = app let block_hash = app
.balanced_rpcs .balanced_rpcs
.blocks_by_number .blocks_by_number
@ -180,6 +182,7 @@ pub async fn clean_block_number<'a>(
.await .await
.context("fetching block hash from number")?; .context("fetching block hash from number")?;
// TODO: make a jsonrpc query here? cache rates will be better but it adds a network request
let block = app let block = app
.balanced_rpcs .balanced_rpcs
.blocks_by_hash .blocks_by_hash
@ -210,6 +213,21 @@ pub async fn clean_block_number<'a>(
} }
} }
#[derive(Debug, From, Hash, Eq, PartialEq)]
pub enum BlockNumOrHash {
Num(U64),
And(BlockNumAndHash),
}
impl BlockNumOrHash {
pub fn num(&self) -> U64 {
match self {
Self::Num(x) => *x,
Self::And(x) => x.num(),
}
}
}
/// TODO: change this to also return the hash needed? /// TODO: change this to also return the hash needed?
/// this replaces any "latest" identifiers in the JsonRpcRequest with the current block number which feels like the data is structured wrong /// this replaces any "latest" identifiers in the JsonRpcRequest with the current block number which feels like the data is structured wrong
#[derive(Debug, Default, Hash, Eq, PartialEq)] #[derive(Debug, Default, Hash, Eq, PartialEq)]
@ -221,8 +239,9 @@ pub enum CacheMode {
cache_errors: bool, cache_errors: bool,
}, },
Range { Range {
from_block: BlockNumAndHash, from_block: BlockNumOrHash,
to_block: BlockNumAndHash, to_block: BlockNumOrHash,
cache_block: BlockNumAndHash,
/// cache jsonrpc errors (server errors are never cached) /// cache jsonrpc errors (server errors are never cached)
cache_errors: bool, cache_errors: bool,
}, },
@ -285,12 +304,12 @@ impl CacheMode {
} }
if let Some(head_block) = head_block { if let Some(head_block) = head_block {
CacheMode::Standard { Self::Standard {
block: head_block.into(), block: head_block.into(),
cache_errors: true, cache_errors: true,
} }
} else { } else {
CacheMode::Never Self::Never
} }
} }
@ -333,9 +352,9 @@ impl CacheMode {
match request.method.as_ref() { match request.method.as_ref() {
"debug_traceTransaction" => { "debug_traceTransaction" => {
// TODO: make sure re-orgs work properly! // TODO: make sure re-orgs work properly!
Ok(CacheMode::SuccessForever) Ok(Self::SuccessForever)
} }
"eth_gasPrice" => Ok(CacheMode::Standard { "eth_gasPrice" => Ok(Self::Standard {
block: head_block.into(), block: head_block.into(),
cache_errors: false, cache_errors: false,
}), }),
@ -343,23 +362,25 @@ impl CacheMode {
// TODO: double check that any node can serve this // TODO: double check that any node can serve this
// TODO: can a block change? like what if it gets orphaned? // TODO: can a block change? like what if it gets orphaned?
// TODO: make sure re-orgs work properly! // TODO: make sure re-orgs work properly!
Ok(CacheMode::SuccessForever) Ok(Self::SuccessForever)
} }
"eth_getBlockByNumber" => { "eth_getBlockByNumber" => {
// TODO: double check that any node can serve this // TODO: double check that any node can serve this
// TODO: CacheSuccessForever if the block is old enough // TODO: CacheSuccessForever if the block is old enough
// TODO: make sure re-orgs work properly! // TODO: make sure re-orgs work properly!
Ok(CacheMode::Standard { Ok(Self::Standard {
block: head_block.into(), block: head_block.into(),
cache_errors: true, cache_errors: true,
}) })
} }
"eth_getBlockTransactionCountByHash" => { "eth_getBlockTransactionCountByHash" => {
// TODO: double check that any node can serve this // TODO: double check that any node can serve this
Ok(CacheMode::SuccessForever) Ok(Self::SuccessForever)
} }
"eth_getLogs" => { "eth_getLogs" => {
/* //
// if we fail to get to_block, then use head_block
// TODO: think about this more // TODO: think about this more
// TODO: jsonrpc has a specific code for this // TODO: jsonrpc has a specific code for this
let obj = params let obj = params
@ -371,7 +392,7 @@ impl CacheMode {
})?; })?;
if obj.contains_key("blockHash") { if obj.contains_key("blockHash") {
Ok(CacheMode::CacheSuccessForever) Ok(Self::SuccessForever)
} else { } else {
let from_block = if let Some(x) = obj.get_mut("fromBlock") { let from_block = if let Some(x) = obj.get_mut("fromBlock") {
// TODO: use .take instead of clone // TODO: use .take instead of clone
@ -387,11 +408,9 @@ impl CacheMode {
*x = json!(block_num); *x = json!(block_num);
} }
let block_hash = rpcs.block_hash(&block_num).await?; BlockNumOrHash::Num(block_num)
BlockNumAndHash(block_num, block_hash)
} else { } else {
BlockNumAndHash(U64::zero(), H256::zero()) BlockNumOrHash::Num(U64::zero())
}; };
let to_block = if let Some(x) = obj.get_mut("toBlock") { let to_block = if let Some(x) = obj.get_mut("toBlock") {
@ -399,67 +418,82 @@ impl CacheMode {
// what if its a hash? // what if its a hash?
let block_num: BlockNumber = serde_json::from_value(x.clone())?; let block_num: BlockNumber = serde_json::from_value(x.clone())?;
let (block_num, change) = // sometimes people request `from_block=future, to_block=latest`. latest becomes head and then
BlockNumber_to_U64(block_num, head_block.number()); // TODO: if this is in the future, this cache key won't be very likely to be used again
// TODO: delay here until the app has this block?
let latest_block = head_block.number().max(from_block.num());
let (block_num, change) = BlockNumber_to_U64(block_num, latest_block);
if change { if change {
trace!("changing toBlock in eth_getLogs. {} -> {}", x, block_num); trace!("changing toBlock in eth_getLogs. {} -> {}", x, block_num);
*x = json!(block_num); *x = json!(block_num);
} }
let block_hash = rpcs.block_hash(&block_num).await?; if let Some(app) = app {
// TODO: make a jsonrpc query here? cache rates will be better but it adds a network request
BlockNumAndHash(block_num, block_hash) if let Some(block_hash) =
app.balanced_rpcs.blocks_by_number.get(&block_num).await
{
BlockNumOrHash::And(BlockNumAndHash(block_num, block_hash))
} else {
BlockNumOrHash::Num(block_num)
}
} else {
BlockNumOrHash::Num(block_num)
}
} else { } else {
head_block.into() BlockNumOrHash::And(head_block.into())
}; };
Ok(CacheMode::CacheRange { let cache_block = if let BlockNumOrHash::And(x) = &to_block {
x.clone()
} else {
BlockNumAndHash::from(head_block)
};
Ok(Self::Range {
from_block, from_block,
to_block, to_block,
cache_block,
cache_errors: true, cache_errors: true,
}) })
} }
*/
Ok(CacheMode::Standard {
block: head_block.into(),
cache_errors: true,
})
} }
"eth_getTransactionByBlockHashAndIndex" => { "eth_getTransactionByBlockHashAndIndex" => {
// TODO: check a Cache of recent hashes // TODO: check a Cache of recent hashes
// try full nodes first. retry will use archive // try full nodes first. retry will use archive
Ok(CacheMode::SuccessForever) Ok(Self::SuccessForever)
} }
"eth_getTransactionByHash" => Ok(CacheMode::Never), "eth_getTransactionByHash" => Ok(Self::Never),
"eth_getTransactionReceipt" => Ok(CacheMode::Never), "eth_getTransactionReceipt" => Ok(Self::Never),
"eth_getUncleByBlockHashAndIndex" => { "eth_getUncleByBlockHashAndIndex" => {
// TODO: check a Cache of recent hashes // TODO: check a Cache of recent hashes
// try full nodes first. retry will use archive // try full nodes first. retry will use archive
// TODO: what happens if this block is uncled later? // TODO: what happens if this block is uncled later?
Ok(CacheMode::SuccessForever) Ok(Self::SuccessForever)
} }
"eth_getUncleCountByBlockHash" => { "eth_getUncleCountByBlockHash" => {
// TODO: check a Cache of recent hashes // TODO: check a Cache of recent hashes
// try full nodes first. retry will use archive // try full nodes first. retry will use archive
// TODO: what happens if this block is uncled later? // TODO: what happens if this block is uncled later?
Ok(CacheMode::SuccessForever) Ok(Self::SuccessForever)
} }
"eth_maxPriorityFeePerGas" => { "eth_maxPriorityFeePerGas" => {
// TODO: this might be too aggressive. i think it can change before a block is mined // TODO: this might be too aggressive. i think it can change before a block is mined
Ok(CacheMode::Standard { Ok(Self::Standard {
block: head_block.into(), block: head_block.into(),
cache_errors: false, cache_errors: false,
}) })
} }
"eth_sendRawTransaction" => Ok(CacheMode::Never), "eth_sendRawTransaction" => Ok(Self::Never),
"net_listening" => Ok(CacheMode::SuccessForever), "net_listening" => Ok(Self::SuccessForever),
"net_version" => Ok(CacheMode::SuccessForever), "net_version" => Ok(Self::SuccessForever),
method => match get_block_param_id(method) { method => match get_block_param_id(method) {
Some(block_param_id) => { Some(block_param_id) => {
let block = clean_block_number(params, block_param_id, head_block, app).await?; let block = clean_block_number(params, block_param_id, head_block, app).await?;
Ok(CacheMode::Standard { Ok(Self::Standard {
block, block,
cache_errors: true, cache_errors: true,
}) })
@ -480,7 +514,7 @@ impl CacheMode {
} }
#[inline] #[inline]
pub fn from_block(&self) -> Option<&BlockNumAndHash> { pub fn from_block(&self) -> Option<&BlockNumOrHash> {
match self { match self {
Self::SuccessForever => None, Self::SuccessForever => None,
Self::Never => None, Self::Never => None,
@ -494,13 +528,14 @@ impl CacheMode {
!matches!(self, Self::Never) !matches!(self, Self::Never)
} }
/// get the to_block used **for caching**. This may be the to_block in the request, or it might be the current head block.
#[inline] #[inline]
pub fn to_block(&self) -> Option<&BlockNumAndHash> { pub fn to_block(&self) -> Option<&BlockNumAndHash> {
match self { match self {
Self::SuccessForever => None, Self::SuccessForever => None,
Self::Never => None, Self::Never => None,
Self::Standard { block, .. } => Some(block), Self::Standard { block, .. } => Some(block),
Self::Range { to_block, .. } => Some(to_block), Self::Range { cache_block, .. } => Some(cache_block),
} }
} }
} }

View File

@ -498,7 +498,7 @@ impl ValidatedRequest {
#[inline] #[inline]
pub fn max_block_needed(&self) -> Option<U64> { pub fn max_block_needed(&self) -> Option<U64> {
self.cache_mode.to_block().map(|x| *x.num()) self.cache_mode.to_block().map(|x| x.num())
} }
#[inline] #[inline]
@ -506,7 +506,7 @@ impl ValidatedRequest {
if self.archive_request.load(atomic::Ordering::Relaxed) { if self.archive_request.load(atomic::Ordering::Relaxed) {
Some(U64::zero()) Some(U64::zero())
} else { } else {
self.cache_mode.from_block().map(|x| *x.num()) self.cache_mode.from_block().map(|x| x.num())
} }
} }

View File

@ -1,5 +1,5 @@
use crate::{ use crate::{
block_number::{BlockNumAndHash, CacheMode}, block_number::{BlockNumAndHash, BlockNumOrHash, CacheMode},
errors::{Web3ProxyError, Web3ProxyResult}, errors::{Web3ProxyError, Web3ProxyResult},
frontend::authorization::RequestOrMethod, frontend::authorization::RequestOrMethod,
jsonrpc::{self, JsonRpcErrorData, ResponsePayload}, jsonrpc::{self, JsonRpcErrorData, ResponsePayload},
@ -19,23 +19,28 @@ use std::{
#[derive(Clone, Debug, Eq, From)] #[derive(Clone, Debug, Eq, From)]
pub struct JsonRpcQueryCacheKey<'a> { pub struct JsonRpcQueryCacheKey<'a> {
/// hashed params so that /// hashed params and block info so that we don't have to clone a potentially big thing
/// this is probably a premature optimization
hash: u64, hash: u64,
from_block: Option<&'a BlockNumAndHash>, from_block: Option<&'a BlockNumOrHash>,
to_block: Option<&'a BlockNumAndHash>, to_block: Option<&'a BlockNumAndHash>,
cache_jsonrpc_errors: bool, cache_jsonrpc_errors: bool,
} }
impl JsonRpcQueryCacheKey<'_> { impl JsonRpcQueryCacheKey<'_> {
#[inline]
pub fn hash(&self) -> u64 { pub fn hash(&self) -> u64 {
self.hash self.hash
} }
pub fn from_block_num(&self) -> Option<&U64> { #[inline]
self.from_block.as_ref().map(|x| x.num()) pub fn from_block_num(&self) -> Option<U64> {
self.from_block.map(|x| x.num())
} }
pub fn to_block_num(&self) -> Option<&U64> { #[inline]
self.to_block.as_ref().map(|x| x.num()) pub fn to_block_num(&self) -> Option<U64> {
self.to_block.map(|x| x.num())
} }
#[inline]
pub fn cache_errors(&self) -> bool { pub fn cache_errors(&self) -> bool {
self.cache_jsonrpc_errors self.cache_jsonrpc_errors
} }
@ -102,6 +107,7 @@ pub enum ForwardedResponse<T> {
// TODO: impl for other inner result types? // TODO: impl for other inner result types?
impl<R> ForwardedResponse<R> { impl<R> ForwardedResponse<R> {
#[inline]
pub fn num_bytes(&self) -> u64 { pub fn num_bytes(&self) -> u64 {
match self { match self {
Self::Result { num_bytes, .. } => *num_bytes, Self::Result { num_bytes, .. } => *num_bytes,
@ -109,6 +115,7 @@ impl<R> ForwardedResponse<R> {
} }
} }
#[inline]
pub fn is_error(&self) -> bool { pub fn is_error(&self) -> bool {
match self { match self {
Self::Result { .. } => false, Self::Result { .. } => false,
@ -118,12 +125,14 @@ impl<R> ForwardedResponse<R> {
} }
impl<R> ForwardedResponse<Option<R>> { impl<R> ForwardedResponse<Option<R>> {
#[inline]
pub fn is_null(&self) -> bool { pub fn is_null(&self) -> bool {
matches!(self, Self::Result { value: None, .. }) matches!(self, Self::Result { value: None, .. })
} }
} }
impl ForwardedResponse<Arc<RawValue>> { impl ForwardedResponse<Arc<RawValue>> {
#[inline]
pub fn is_null(&self) -> bool { pub fn is_null(&self) -> bool {
match self { match self {
Self::Result { value, .. } => value.get() == "null", Self::Result { value, .. } => value.get() == "null",