From 31395c99341910498920e867053f8d535b098b38 Mon Sep 17 00:00:00 2001 From: Bryan Stitt Date: Mon, 7 Nov 2022 22:10:19 +0000 Subject: [PATCH] rpc_key_id in the redirect. weights in the /status page --- TODO.md | 2 ++ config/example.toml | 16 ++++++++-------- web3_proxy/src/app.rs | 4 ++-- .../src/bin/web3_proxy_cli/check_config.rs | 2 +- web3_proxy/src/frontend/rpc_proxy_ws.rs | 6 +++++- web3_proxy/src/rpcs/connection.rs | 4 +++- web3_proxy/src/rpcs/connections.rs | 3 +++ 7 files changed, 24 insertions(+), 13 deletions(-) diff --git a/TODO.md b/TODO.md index b0c7a7c2..8add0811 100644 --- a/TODO.md +++ b/TODO.md @@ -226,6 +226,8 @@ These are roughly in order of completition - [x] fix test not shutting down - [x] proper authentication on rpc_key_id - we have bearer token auth for user_id, but rpc_key_id needs more code +- [x] use rpc_key_id instead of user_id in the redirect +- [x] /status should include the server weights - [-] add configurable size limits to all the Caches - instead of configuring each cache with MB sizes, have one value for total memory footprint and then percentages for each cache diff --git a/config/example.toml b/config/example.toml index 299c9b0d..aada359e 100644 --- a/config/example.toml +++ b/config/example.toml @@ -3,26 +3,26 @@ chain_id = 1 # TODO: how do we find the optimal db_max_connections? too high actually ends up being slower db_max_connections = 99 -db_url = "mysql://root:dev_web3_proxy@dev-db:3306/dev_web3_proxy" +db_url = "mysql://MYSQL_USER:MYSQL_PASSWORD@MYSQL_DOMAIN:MYSQL_PORT/MYSQL_DB" min_sum_soft_limit = 2_000 min_synced_rpcs = 2 # TODO: how do we find the optimal redis_max_connections? too high actually ends up being slower volatile_redis_max_connections = 300 -volatile_redis_url = "redis://dev-vredis:6379/" +volatile_redis_url = "redis://REDIS_DOMAIN:REDIS_PORT/" -redirect_public_url = "https://llamanodes.com/free-rpc-stats" -redirect_user_url = "https://llamanodes.com/user-rpc-stats/{{user_id}}" +redirect_public_url = "https://llamanodes.com/public-rpc" +redirect_user_url = "https://llamanodes.com/dashboard/keys?key={{rpc_key_id}}" -sentry_url = "https://YOURKEYA.ingest.sentry.io/YOURKEYB" +sentry_url = "https://SENTRY_KEY_A.ingest.sentry.io/SENTRY_KEY_B" # 0 = block all public requests -public_max_concurrent_requests = 5 +public_max_concurrent_requests = 3 # 0 = block all public requests -public_requests_per_period = 0 +public_requests_per_period = 200 -# 1GB of cache +# 10GB of cache response_cache_max_bytes = 10_000_000_000 [app.allowed_origin_requests_per_period] diff --git a/web3_proxy/src/app.rs b/web3_proxy/src/app.rs index 47e9ba2a..24cb78bc 100644 --- a/web3_proxy/src/app.rs +++ b/web3_proxy/src/app.rs @@ -195,8 +195,8 @@ impl Web3ProxyApp { // safety checks on the config if let Some(redirect) = &top_config.app.redirect_user_url { assert!( - redirect.contains("{{user_id}}"), - "redirect_user_url user url must contain \"{{user_id}}\"" + redirect.contains("{{rpc_key_id}}"), + "redirect_user_url user url must contain \"{{rpc_key_id}}\"" ); } diff --git a/web3_proxy/src/bin/web3_proxy_cli/check_config.rs b/web3_proxy/src/bin/web3_proxy_cli/check_config.rs index b5a43169..24233035 100644 --- a/web3_proxy/src/bin/web3_proxy_cli/check_config.rs +++ b/web3_proxy/src/bin/web3_proxy_cli/check_config.rs @@ -66,7 +66,7 @@ impl CheckConfigSubCommand { } if top_config.app.redirect_user_url.is_none() { - warn!("app.redirect_public_url is None. Registered users will get an error page instead of a redirect") + warn!("app.redirect_user_url is None. Registered users will get an error page instead of a redirect") } Ok(()) diff --git a/web3_proxy/src/frontend/rpc_proxy_ws.rs b/web3_proxy/src/frontend/rpc_proxy_ws.rs index 7574b67f..4291bd11 100644 --- a/web3_proxy/src/frontend/rpc_proxy_ws.rs +++ b/web3_proxy/src/frontend/rpc_proxy_ws.rs @@ -111,6 +111,7 @@ pub async fn websocket_handler_with_key( proxy_web3_socket(app, authorized_request, socket).instrument(request_span) })), None => { + // if no websocket upgrade, this is probably a user loading the url with their browser if let Some(redirect) = &app.config.redirect_user_url { // TODO: store this on the app and use register_template? let reg = Handlebars::new(); @@ -119,7 +120,10 @@ pub async fn websocket_handler_with_key( // TODO: query to get the user's address. expose that instead of user_id if let AuthorizedRequest::User(_, authorized_key) = authorized_request.as_ref() { let user_url = reg - .render_template(redirect, &json!({ "user_id": authorized_key.user_id })) + .render_template( + redirect, + &json!({ "rpc_key_id": authorized_key.rpc_key_id }), + ) .expect("templating should always work"); // this is not a websocket. redirect to a page for this user diff --git a/web3_proxy/src/rpcs/connection.rs b/web3_proxy/src/rpcs/connection.rs index f7ed6eca..23e76721 100644 --- a/web3_proxy/src/rpcs/connection.rs +++ b/web3_proxy/src/rpcs/connection.rs @@ -896,7 +896,7 @@ impl Serialize for Web3Connection { S: Serializer, { // 3 is the number of fields in the struct. - let mut state = serializer.serialize_struct("Web3Connection", 6)?; + let mut state = serializer.serialize_struct("Web3Connection", 7)?; // the url is excluded because it likely includes private information. just show the name state.serialize_field("name", &self.name)?; @@ -908,6 +908,8 @@ impl Serialize for Web3Connection { state.serialize_field("block_data_limit", &block_data_limit)?; } + state.serialize_field("weight", &self.weight)?; + state.serialize_field("soft_limit", &self.soft_limit)?; state.serialize_field( diff --git a/web3_proxy/src/rpcs/connections.rs b/web3_proxy/src/rpcs/connections.rs index b2091d55..dd9b9ea6 100644 --- a/web3_proxy/src/rpcs/connections.rs +++ b/web3_proxy/src/rpcs/connections.rs @@ -413,6 +413,9 @@ impl Web3Connections { let utilization = active_requests as f32 / soft_limit as f32; + // TODO: utilization isn't enough we need to sort on some combination of utilization and if a server is archive or not + // TODO: if a server's utilization is high and it has a low weight, it will keep getting requests. this isn't really what we want + // TODO: double check this sorts how we want (rpc.clone(), (weight, utilization, Reverse(soft_limit))) })