diff --git a/docs/curl login.md b/docs/curl login.md new file mode 100644 index 00000000..8563d01b --- /dev/null +++ b/docs/curl login.md @@ -0,0 +1,10 @@ +# log in with curl + +1. curl http://127.0.0.1:8544/user/login/$ADDRESS +2. Sign the text with a site like https://www.myetherwallet.com/wallet/sign +3. POST the signed data: + + curl -X POST http://127.0.0.1:8544/user/login -H 'Content-Type: application/json' -d + '{ "address": "0x9eb9e3dc2543dc9ff4058e2a2da43a855403f1fd", "msg": "0x6c6c616d616e6f6465732e636f6d2077616e747320796f7520746f207369676e20696e207769746820796f757220457468657265756d206163636f756e743a0a3078396562396533646332353433646339464634303538653241324441343341383535343033463166440a0af09fa699f09fa699f09fa699f09fa699f09fa6990a0a5552493a2068747470733a2f2f6c6c616d616e6f6465732e636f6d2f0a56657273696f6e3a20310a436861696e2049443a20310a4e6f6e63653a203031474d37373330375344324448333854454d3957545156454a0a4973737565642041743a20323032322d31322d31345430323a32333a31372e3735333736335a0a45787069726174696f6e2054696d653a20323032322d31322d31345430323a34333a31372e3735333736335a", "sig": "16bac055345279723193737c6c67cf995e821fd7c038d31fd6f671102088c7b85ab4b13069fd2ed02da186cf549530e315d8d042d721bf81289b3ffdbe8cf9ce1c", "version": "3", "signer": "MEW" }' + +4. The response will include a bearer token. Use it with curl ... -H 'Authorization: Bearer $TOKEN' diff --git a/docs/faster perf.txt b/docs/faster perf.txt new file mode 100644 index 00000000..4a6f2073 --- /dev/null +++ b/docs/faster perf.txt @@ -0,0 +1,8 @@ +sudo apt install bison flex +wget https://eighty-twenty.org/files/0001-tools-perf-Use-long-running-addr2line-per-dso.patch +git clone https://github.com/torvalds/linux.git +cd linux +git checkout v5.15 +git apply ../0001-tools-perf-Use-long-running-addr2line-per-dso.patch +cd tools/perf +make prefix=$HOME/.local VERSION=5.15 install-bin diff --git a/docs/http routes.txt b/docs/http routes.txt new file mode 100644 index 00000000..e6ab9a25 --- /dev/null +++ b/docs/http routes.txt @@ -0,0 +1,231 @@ +@@ -1,144 +0,0 @@ + +GET / + This entrypoint handles two things. + If connecting with a browser, it redirects to the public stat page on llamanodes.com. + If connecting with a websocket, it is rate limited by IP and routes to the Web3 RPC. + +POST / + This entrypoint handles two things. + If connecting with a browser, it redirects to the public stat page on llamanodes.com. + If connecting with a websocket, it is rate limited by IP and routes to the Web3 RPC. + +GET /rpc/:rpc_key + This entrypoint handles two things. + If connecting with a browser, it redirects to the key's stat page on llamanodes.com. + If connecting with a websocket, it is rate limited by key and routes to the Web3 RPC. + +POST /rpc/:rpc_key + This entrypoint handles two things. + If connecting with a browser, it redirects to the key's stat page on llamanodes.com. + If connecting with a websocket, it is rate limited by key and routes to the Web3 RPC. + +GET /debug/:rpc_key + Similar to GET /rpc/:rpc_key but includes additional debugging information. + +POST /debug/:rpc_key + Similar to POST /rpc/:rpc_key but includes additional debugging information. + +GET /health + If servers are synced, this gives a 200 "OK". + If no servers are synced, it gives a 502 ":(" + +GET /fastest + Similar to POST /fastest, but for websocket connections. + +POST /fastest + Routes the request to the fastest server. + +POST /fastest/:rpc_key + Routes the authenticated request to the fastest server. + +POST /versus + This is an experimental endpoint for testing Web3 RPC performance. + +GET /versus + Similar to POST /versus, but for websocket connections. + +POST /versus/:rpc_key + This is an authenticated version of the /versus endpoint. + +GET /versus/:rpc_key + Similar to POST /versus/:rpc_key, but for websocket connections. + +GET /fastest/:rpc_key + Similar to POST /fastest/:rpc_key, but for websocket connections. + +GET /user/login/:user_address + Displays a "Sign in With Ethereum" message to be signed by the address's private key. + Once signed, continue to `POST /user/login` + +GET /user/login/:user_address/:message_eip + Similar to `GET /user/login/:user_address` but gives the message in different formats depending on the eip. + Wallets have varying support. This shouldn't be needed by most users. + The message_eip should be hidden behind a small gear icon near the login button. + Once signed, continue to `POST /user/login` + + Supported: + EIP191 as bytes + EIP191 as a hash + EIP4361 (the default) + + Support coming soon: + EIP1271 for contract signing + +POST /user/login?invite_code=SOMETHING_SECRET + Verifies the user's signed message. + + The post should have JSON data containing "sig" (the signature) and "msg" (the original message). + + Optionally requires an invite_code. + The invite code is only needed for new users. Once registered, it is not necessary. + + If the invite code and signature are valid, this returns JSON data containing "rpc_keys", "bearer_token" and the "user". + + "rpc_keys" contains the key and settings for all of the user's keys. + If the user is new, an "rpc_key" will be created for them. + + The "bearer_token" is required by some endpoints. Include it in the "AUTHORIZATION" header in this format: "bearer :bearer_token". + The token is good for 4 weeks and the 4 week time will reset whenever the token is used. + + The "user" just has an address at first, but you can prompt them to add an email address. See `POST /user` + +GET /user + Checks the "AUTHORIZATION" header for a valid bearer token. + If valid, display's the user's data as JSON. + + + +POST /user + POST the data in the same format that `GET /user` gives it. + If you do not want to update a field, do not include it in the POSTed JSON. + If you want to delete a field, include the data's key and set the value to an empty string. + + Checks the "AUTHORIZATION" header for a valid bearer token. + If valid, updates the user's data and returns the updated data as JSON. + +GET /user/balance + Not yet implemented. + + Checks the "AUTHORIZATION" header for a valid bearer token. + If valid, displays data about the user's balance and payments as JSON. + +POST /user/balance/:txid + Not yet implemented. Rate limited by IP. + + Checks the ":txid" for a transaction that updates a user's balance. + The backend will be watching for these transactions, so this should not be needed in the common case. + However, log susbcriptions are not perfect and so it might sometimes be needed. + +GET /user/keys + Checks the "AUTHORIZATION" header for a valid bearer token. + If valid, displays data about the user's keys as JSON. + +GET /status + Gives information about the system's status. + +GET /status/backups_needed + Indicates if backups are needed for the system. + +GET /user/subuser + Modifies (adds or removes) a specific subuser to a certain rpc_key. + Takes in "rpc_key", "subuser_address", "new_status" (one of "upsert", "remove"), "new_role" (one of "owner", "admin", "collaborator") as query-parameters + +GET /user/subusers + Retrieves all the subusers of a given user's rpc key, including their roles and addresses. + Takes in "rpc_key" as a query-parameter + +GET /subuser/rpc_keys + Retrieves RPC keys for the subuser (i.e. all RPC-keys that were shared with me, being the subuser) + +GET /user/deposits + Retrieves the user's deposit history. + +GET /user/balance/:tx_hash + Accepts a tx_hash and updates the user's balance according to this transaction. + Any authorized user can call this endpoint for any other user's transaction. + +GET /user/referral + Fetches a user's referral link. + +GET /admin/increase_balance + Increases the balance for a user. This is an administrative endpoint. + Query parameters are: + - "user_address" + - "note" + - "amount" (Decimal) + Can only be called by admins + +GET /admin/modify_role + Changes the role of a user. This is an administrative endpoint. + Query parameters are: + - "user_address" + - "user_tier_title" + Can only be called by admins + +GET /admin/imitate-login/:admin_address/:user_address + Allows an admin to imitate a login as another user. + Query parameters are: + - "admin_address" + - "user_address" + This creates a login-message, you can use this message and login with the /admin/imitate-login/:admin_address/:user_address/:message_eip to imitate the user + +POST /admin/imitate-login + Verifies the admin's imitation login request. + (Similar to the login flow) + +POST /admin/imitate-logout + Allows an admin to imitate a logout operation. + +POST or PUT /user/keys + Checks the "AUTHORIZATION" header for a valid bearer token. + If valid, allows the user to create a new key or change options on their keys. + + The POSTed JSON can have these fields: + key_id: Option, + description: Option, + private_txs: Option, + active: Option, + allowed_ips: Option, + allowed_origins: Option, + allowed_referers: Option, + allowed_user_agents: Option, + + The PUTed JSON has the same fields as the POSTed JSON, except for there is no `key_id` + + If you do not want to update a field, do not include it in the POSTed JSON. + If you want to delete a string field, include the data's key and set the value to an empty string. + + `allowed_ips`, `allowed_origins`, `allowed_referers`, and `allowed_user_agents` can have multiple values by separating them with commas. + `allowed_ips` must be in CIDR Notation (ex: "10.1.1.0/24" for a network, "10.1.1.10/32" for a single address). + The spec technically allows for bytes in `allowed_origins` or `allowed_referers`, but our code currently only supports strings. If a customer needs bytes, then we can code support for them. + + `private_txs` are not currently recommended. If high gas is not supplied then they will likely never be included. Improvements to this are in the works + + Soon, the POST data will also have a `log_revert_trace: Option`. This will by the percent chance to log any calls that "revert" to the database. Large dapps probably want this to be a small percent, but development keys will probably want 100%. This will not be enabled until automatic pruning is coded. + +GET `/user/revert_logs` + Checks the "AUTHORIZATION" header for a valid bearer token. + If valid, fetches paginated revert logs for the user. + More documentation will be written here once revert logging is enabled. + +GET /user/stats/aggregate + Checks the "AUTHORIZATION" header for a valid bearer token. + If valid, fetches paginated aggregated stats for the user. + Pages are limited to 200 entries. The backend config can change this page size if necessary. + Can be filtered by: + `chain_id` - set to 0 for all. 0 is the default. + `query_start` - The start date in unix epoch time. + `query_window_seconds` - How many seconds to aggregate the stats over. + `page` - The page to request. Defaults to 0. + +GET /user/stats/detailed + Checks the "AUTHORIZATION" header for a valid bearer token. + If valid, fetches paginated stats for the user with more detail. The request method is included. For user privacy, we intentionally do not include the request's calldata. + Can be filtered the same as `GET /user/stats/aggregate` + Soon will also be filterable by "method" + +POST /user/logout + Checks the "AUTHORIZATION" header for a valid bearer token. + If valid, deletes the bearer token from the proxy. + The user will need to `POST /user/login` to get a new bearer token. diff --git a/docs/tracing notes.txt b/docs/tracing notes.txt new file mode 100644 index 00000000..84aa85cd --- /dev/null +++ b/docs/tracing notes.txt @@ -0,0 +1,15 @@ +Hello, I'm pretty new to tracing so my vocabulary might be wrong. I've got my app using tracing to log to stdout. I have a bunch of fields including user_id and ip_addr that make telling where logs are from nice and easy. + +Now there is one part of my code where I want to save a log to a database. I'm not sure of the best/correct way to do this. I can get the current span with tracing::Span::current(), but AFAICT that doesn't have a way to get to the values. I think I need to write my own Subscriber or Visitor (or both) and then tell tracing to use it only in this one part of the code. Am I on the right track? Is there a place in the docs that explains something similar? + +https://burgers.io/custom-logging-in-rust-using-tracing + +if you are doing it learn how to write a subscriber then you should write a custom layer. If you are simply trying to work on your main project there are several subscribers that already do this work for you. + +look at opentelemetry_otlp .. this will let you connect opentelemetry collector to your tracing using tracing_opentelemetry + +I'd suggest using the Registry subscriber because it can take multiple layers ... and use a filtered_layer to filter out the messages (look at env_filter, it can take the filtering params from an environment variable or a config string) and then have your collector be the second layer. e.... Registery can take in a vector of layers that are also-in-turn multi-layered. +let me see if i can pull up an example +On the https://docs.rs/tracing-subscriber/latest/tracing_subscriber/layer/ page about half-way down there is an example of boxed layers + +you basically end up composing different layers that output to different trace stores and also configure each using per-layer filtering (see https://docs.rs/tracing-subscriber/latest/tracing_subscriber/layer/#per-layer-filtering) diff --git a/web3_proxy/src/frontend/users/subuser.rs b/web3_proxy/src/frontend/users/subuser.rs index ee4b40c6..94425458 100644 --- a/web3_proxy/src/frontend/users/subuser.rs +++ b/web3_proxy/src/frontend/users/subuser.rs @@ -11,6 +11,7 @@ use axum::{ }; use axum_macros::debug_handler; use entities::sea_orm_active_enums::Role; +use entities::user::Relation::UserTier; use entities::{balance, rpc_key, secondary_user, user, user_tier}; use ethers::types::Address; use hashbrown::HashMap; @@ -223,7 +224,7 @@ pub async fn modify_subuser( .remove("new_role") // TODO: map_err so this becomes a 500. routing must be bad .ok_or(Web3ProxyError::BadRequest( - "You have not provided the new_stats key in the request".to_string(), + "You have not provided the new_role key in the request".to_string(), ))? .as_str() {