Skip to content

Kerem/backup #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 24 commits into
base: kerem/rebuild
Choose a base branch
from
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
3,635 changes: 295 additions & 3,340 deletions Cargo.lock

Large diffs are not rendered by default.

36 changes: 27 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ members = [
"crates/rpc-gateway-cache",
"crates/rpc-gateway-config",
"crates/rpc-gateway-core",
"crates/rpc-gateway-eth",
"crates/rpc-gateway-rpc",
]
resolver = "3"

Expand All @@ -23,28 +25,44 @@ repository = "https://github.com/whats-good/rpc-gateway"

[workspace.dependencies]
arc-swap = "1.7.0"
async-trait = "0.1.88"
clap = { version = "4.4", features = ["derive"] }
clap = { version = "4.5.37", features = ["derive"] }
duration-str = "0.17.0"
moka = { version = "0.12.10", features = ["future"] }
nonempty = "0.11.0"
rand = "0.9.1"
futures = "0.3.31"
reqwest = { version = "0.12.15", features = ["json"] }
simd-json = { version = "0.15.1", features = ["serde"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_yaml = "0.9"
metrics = "0.24.2"
tokio = { version = "1.44.2", features = ["full"] }
tokio-util = { version = "0.7.15", features = ["rt"] }
tracing = "0.1"
tracing-appender = { version = "0.2.1" }
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
url = "2.5"

alloy-chains = "0.2.0"
alloy-primitives = "1.0.0"
alloy-dyn-abi = "0.8.25"
alloy-eips = "0.12.6"
alloy-primitives = { version = "1.1.0", default-features = false, features = [
"serde",
] }
alloy-eips = "0.15.7"
alloy-rpc-types = "0.15.7"
alloy-serde = "0.15.7"

rpc-gateway-config = { path = "crates/rpc-gateway-config" }
rpc-gateway-cache = { path = "crates/rpc-gateway-cache" }
rpc-gateway-eth = { path = "crates/rpc-gateway-eth" }
rpc-gateway-rpc = { path = "crates/rpc-gateway-rpc" }

[profile.release]
opt-level = 3
lto = "fat"
panic = "abort"

[profile.dev]
debug = true
split-debuginfo = "packed"
opt-level = 0
debug-assertions = true
overflow-checks = true
incremental = true
codegen-units = 256
13 changes: 12 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,12 @@ dev: ## Start development server with file watching. Usage: make dev CONFIG=path
@echo "----------------------------------------"
@echo "Starting server..."
@mkdir -p logs
watchexec -e rs -r cargo run --bin rpc-gateway -- -c $(if $(CONFIG),$(CONFIG),$(PWD)/example.config.yml)
MALLOC_CONF="prof:true,prof_active:true,lg_prof_interval:24,lg_prof_sample:17" watchexec -e rs -r cargo run --bin rpc-gateway -- -c $(if $(CONFIG),$(CONFIG),$(PWD)/example.config.yml)

.PHONY: udeps
udeps: ## Find unused dependencies.
@echo "Running udeps..."
cargo +nightly udeps --all-targets --all-features --workspace

loadtest:
@echo "Running load test..."
Expand Down Expand Up @@ -181,6 +186,12 @@ lint: ## Run all linting checks.
@echo "Running linting checks..."
cargo clippy --workspace

.PHONY: flatten-rust
flatten-rust: ## Flatten all Rust source files into a single file for LLM analysis.
@echo "Flattening Rust source files..."
./scripts/flatten_rust.py
@echo "Flattened Rust files saved to flattened_rust.txt"

##@ help
# Show help
.PHONY: help
Expand Down
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,17 @@ make test
make lint
```

## License

This project is licensed under the MIT License - see the LICENSE file for details.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Honorable Mentions

This project wouldn't be possible without the amazing work of the following projects:

- [Alloy](https://github.com/alloy-rs/alloy)
- [Foundry](https://github.com/foundry-rs/foundry)application development

## License

This project is licensed under the MIT License - see the LICENSE file for details.
2 changes: 0 additions & 2 deletions crates/loadtest/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ repository.workspace = true
[dependencies]
goose = "0.18.0"
tokio.workspace = true
alloy-primitives.workspace = true
serde_json.workspace = true
simd-json.workspace = true
rand.workspace = true

[lints]
Expand Down
10 changes: 5 additions & 5 deletions crates/loadtest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ async fn eth_block_by_number_random(user: &mut GooseUser) -> TransactionResult {
let random_number = rng.random_range(0..100000);
format!("0x{:x}", random_number)
};
let request = simd_json::json!({
let request = serde_json::json!({
"jsonrpc": "2.0",
"method": "eth_getBlockByNumber",
"params": [random_number_hex, false],
Expand All @@ -43,7 +43,7 @@ async fn eth_block_by_number_random(user: &mut GooseUser) -> TransactionResult {

/// Get the current block number
async fn eth_block_number(user: &mut GooseUser) -> TransactionResult {
let request = simd_json::json!({
let request = serde_json::json!({
"jsonrpc": "2.0",
"method": "eth_blockNumber",
"params": [],
Expand All @@ -55,7 +55,7 @@ async fn eth_block_number(user: &mut GooseUser) -> TransactionResult {
}

async fn eth_get_block_by_number(user: &mut GooseUser) -> TransactionResult {
let request = simd_json::json!({
let request = serde_json::json!({
"jsonrpc": "2.0",
"method": "eth_getBlockByNumber",
"params": ["latest", false],
Expand All @@ -70,7 +70,7 @@ async fn eth_get_block_by_number(user: &mut GooseUser) -> TransactionResult {
async fn eth_get_balance(user: &mut GooseUser) -> TransactionResult {
// Using a random address for testing
let address = "0x742d35Cc6634C0532925a3b844Bc454e4438f44e";
let request = simd_json::json!({
let request = serde_json::json!({
"jsonrpc": "2.0",
"method": "eth_getBalance",
"params": [address, "latest"],
Expand All @@ -82,7 +82,7 @@ async fn eth_get_balance(user: &mut GooseUser) -> TransactionResult {
}

async fn unknown_method(user: &mut GooseUser) -> TransactionResult {
let request = simd_json::json!({
let request = serde_json::json!({
"jsonrpc": "2.0",
"method": "unknown_method",
"params": [],
Expand Down
15 changes: 2 additions & 13 deletions crates/rpc-gateway-cache/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,16 @@ license.workspace = true
repository.workspace = true

[dependencies]
alloy-chains.workspace = true
alloy-dyn-abi.workspace = true
alloy-eips.workspace = true
alloy-primitives.workspace = true
anvil-core = { git = "https://github.com/whats-good/foundry", package = "anvil-core", rev = "b2bdf5ee58387021fe2048d47ea696bffaf44ffd" }
anvil-rpc = { git = "https://github.com/whats-good/foundry", package = "anvil-rpc", rev = "b2bdf5ee58387021fe2048d47ea696bffaf44ffd" }
arc-swap.workspace = true
futures.workspace = true
metrics.workspace = true
moka.workspace = true
rand.workspace = true
redis = { version = "0.30.0", features = ["tokio-comp", "cluster-async"] }
bb8 = { version = "0.9.0" }
bb8-redis = "0.22.0"
moka = { version = "0.12.10", features = ["future"] }
rpc-gateway-config.workspace = true
rpc-gateway-eth.workspace = true
serde_json.workspace = true
serde.workspace = true
simd-json.workspace = true
tokio.workspace = true
tracing.workspace = true
url.workspace = true

[lints]
workspace = true
6 changes: 3 additions & 3 deletions crates/rpc-gateway-cache/src/cache.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use anvil_core::eth::EthRequest;
use rpc_gateway_config::{CacheConfig, ChainConfig};
use rpc_gateway_eth::eth::EthRequest;
use std::{sync::Arc, time::Duration};
use tracing::{error, warn};

use crate::{local_cache::LocalCache, redis::RedisCache, reqres::ReqRes, ttl::TTLManager};
use crate::{local_cache::LocalCache, redis::RedisCache, ttl::TTLManager};

// TODO: this should not be async
pub async fn from_config(
Expand Down Expand Up @@ -65,7 +65,7 @@ impl RpcCache {
self.ttl_manager.get_ttl(req)
}

pub async fn get(&self, req: &EthRequest) -> Option<ReqRes> {
pub async fn get(&self, req: &EthRequest) -> Option<serde_json::Value> {
match &self.inner {
RpcCacheInner::Local(local_cache) => local_cache.get(req).await,
RpcCacheInner::Redis(redis_cache) => redis_cache.get(req).await,
Expand Down
4 changes: 3 additions & 1 deletion crates/rpc-gateway-cache/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]

pub mod cache;
pub mod ttl;

mod local_cache;
mod redis;
mod reqres;
16 changes: 5 additions & 11 deletions crates/rpc-gateway-cache/src/local_cache.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
use std::time::{Duration, Instant};

use anvil_core::eth::EthRequest;
use moka::{Expiry, future::Cache};

use crate::reqres::ReqRes;
use rpc_gateway_eth::eth::EthRequest;

/// Represents a cache entry
#[derive(Debug, Clone)]
pub struct CacheEntry {
/// The actual value stored in the cache
pub value: ReqRes,
pub value: serde_json::Value,
/// Duration after which this entry should expire
pub ttl: Duration,
}

impl CacheEntry {
/// Creates a new cache entry with the given value and TTL
pub fn new(value: ReqRes, ttl: Duration) -> Self {
pub fn new(value: serde_json::Value, ttl: Duration) -> Self {
Self { value, ttl }
}
}
Expand Down Expand Up @@ -73,18 +71,14 @@ impl LocalCache {
// TODO: may avoid saving the entire request as the key.
}

pub async fn get(&self, req: &EthRequest) -> Option<ReqRes> {
pub async fn get(&self, req: &EthRequest) -> Option<serde_json::Value> {
let key = self.get_key(req);
self.cache.get(&key).await.map(|entry| entry.value)
}

pub async fn insert(&self, req: &EthRequest, response: &serde_json::Value, ttl: Duration) {
let key = self.get_key(req);
let reqres = ReqRes {
req: req.clone(),
res: response.clone(),
};
let entry = CacheEntry::new(reqres, ttl);
let entry = CacheEntry::new(response.clone(), ttl);
self.cache.insert(key, entry).await;
}
}
Loading