rpc_key_id in the redirect. weights in the /status page

This commit is contained in:
Bryan Stitt 2022-11-07 22:10:19 +00:00
parent fc8beb52b0
commit 31395c9934
7 changed files with 24 additions and 13 deletions

View File

@ -226,6 +226,8 @@ These are roughly in order of completition
- [x] fix test not shutting down - [x] fix test not shutting down
- [x] proper authentication on rpc_key_id - [x] proper authentication on rpc_key_id
- we have bearer token auth for user_id, but rpc_key_id needs more code - 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 - [-] 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 - instead of configuring each cache with MB sizes, have one value for total memory footprint and then percentages for each cache

View File

@ -3,26 +3,26 @@ chain_id = 1
# TODO: how do we find the optimal db_max_connections? too high actually ends up being slower # TODO: how do we find the optimal db_max_connections? too high actually ends up being slower
db_max_connections = 99 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_sum_soft_limit = 2_000
min_synced_rpcs = 2 min_synced_rpcs = 2
# TODO: how do we find the optimal redis_max_connections? too high actually ends up being slower # TODO: how do we find the optimal redis_max_connections? too high actually ends up being slower
volatile_redis_max_connections = 300 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_public_url = "https://llamanodes.com/public-rpc"
redirect_user_url = "https://llamanodes.com/user-rpc-stats/{{user_id}}" 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 # 0 = block all public requests
public_max_concurrent_requests = 5 public_max_concurrent_requests = 3
# 0 = block all public requests # 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 response_cache_max_bytes = 10_000_000_000
[app.allowed_origin_requests_per_period] [app.allowed_origin_requests_per_period]

View File

@ -195,8 +195,8 @@ impl Web3ProxyApp {
// safety checks on the config // safety checks on the config
if let Some(redirect) = &top_config.app.redirect_user_url { if let Some(redirect) = &top_config.app.redirect_user_url {
assert!( assert!(
redirect.contains("{{user_id}}"), redirect.contains("{{rpc_key_id}}"),
"redirect_user_url user url must contain \"{{user_id}}\"" "redirect_user_url user url must contain \"{{rpc_key_id}}\""
); );
} }

View File

@ -66,7 +66,7 @@ impl CheckConfigSubCommand {
} }
if top_config.app.redirect_user_url.is_none() { 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(()) Ok(())

View File

@ -111,6 +111,7 @@ pub async fn websocket_handler_with_key(
proxy_web3_socket(app, authorized_request, socket).instrument(request_span) proxy_web3_socket(app, authorized_request, socket).instrument(request_span)
})), })),
None => { 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 { if let Some(redirect) = &app.config.redirect_user_url {
// TODO: store this on the app and use register_template? // TODO: store this on the app and use register_template?
let reg = Handlebars::new(); 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 // TODO: query to get the user's address. expose that instead of user_id
if let AuthorizedRequest::User(_, authorized_key) = authorized_request.as_ref() { if let AuthorizedRequest::User(_, authorized_key) = authorized_request.as_ref() {
let user_url = reg 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"); .expect("templating should always work");
// this is not a websocket. redirect to a page for this user // this is not a websocket. redirect to a page for this user

View File

@ -896,7 +896,7 @@ impl Serialize for Web3Connection {
S: Serializer, S: Serializer,
{ {
// 3 is the number of fields in the struct. // 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 // the url is excluded because it likely includes private information. just show the name
state.serialize_field("name", &self.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("block_data_limit", &block_data_limit)?;
} }
state.serialize_field("weight", &self.weight)?;
state.serialize_field("soft_limit", &self.soft_limit)?; state.serialize_field("soft_limit", &self.soft_limit)?;
state.serialize_field( state.serialize_field(

View File

@ -413,6 +413,9 @@ impl Web3Connections {
let utilization = active_requests as f32 / soft_limit as f32; 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 // TODO: double check this sorts how we want
(rpc.clone(), (weight, utilization, Reverse(soft_limit))) (rpc.clone(), (weight, utilization, Reverse(soft_limit)))
}) })