From ddfd1dbff10004d665c3054f1530b0deb28a86b9 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 22 May 2023 20:07:17 -0400 Subject: [PATCH 1/2] Added admin balance increase, and also test (#72) * added admin balance increase, and also test * slightly hacky, but does do an update expression * added note column to entities * removed redundant printlns * flattened items * removed user tier logic from admin increase balance completely. admin will have to manually increase the user tier --- .../src/admin_increase_balance_receipt.rs | 49 ++++++ entities/src/mod.rs | 1 + entities/src/prelude.rs | 1 + migration/src/lib.rs | 6 +- .../src/m20230514_114803_admin_add_credits.rs | 97 ++++++++++++ scripts/manual-tests/45-admin-add-balance.sh | 44 ++++++ web3_proxy/src/frontend/admin.rs | 146 +++++++++++++++++- web3_proxy/src/frontend/mod.rs | 4 + 8 files changed, 343 insertions(+), 5 deletions(-) create mode 100644 entities/src/admin_increase_balance_receipt.rs create mode 100644 migration/src/m20230514_114803_admin_add_credits.rs create mode 100644 scripts/manual-tests/45-admin-add-balance.sh diff --git a/entities/src/admin_increase_balance_receipt.rs b/entities/src/admin_increase_balance_receipt.rs new file mode 100644 index 00000000..d3d3cf27 --- /dev/null +++ b/entities/src/admin_increase_balance_receipt.rs @@ -0,0 +1,49 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.10.6 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)] +#[sea_orm(table_name = "admin_increase_balance_receipt")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(column_type = "Decimal(Some((20, 10)))")] + pub amount: Decimal, + pub admin_id: u64, + pub deposit_to_user_id: u64, + pub note: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::admin::Entity", + from = "Column::AdminId", + to = "super::admin::Column::Id", + on_update = "NoAction", + on_delete = "NoAction" + )] + Admin, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::DepositToUserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "NoAction" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Admin.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/entities/src/mod.rs b/entities/src/mod.rs index 91a8a460..00510fae 100644 --- a/entities/src/mod.rs +++ b/entities/src/mod.rs @@ -3,6 +3,7 @@ pub mod prelude; pub mod admin; +pub mod admin_increase_balance_receipt; pub mod admin_trail; pub mod balance; pub mod increase_on_chain_balance_receipt; diff --git a/entities/src/prelude.rs b/entities/src/prelude.rs index 9d5f4cc0..20b764f3 100644 --- a/entities/src/prelude.rs +++ b/entities/src/prelude.rs @@ -1,6 +1,7 @@ //! `SeaORM` Entity. Generated by sea-orm-codegen 0.10.7 pub use super::admin::Entity as Admin; +pub use super::admin_increase_balance_receipt::Entity as AdminIncreaseBalanceReceipt; pub use super::admin_trail::Entity as AdminTrail; pub use super::balance::Entity as Balance; pub use super::increase_on_chain_balance_receipt::Entity as IncreaseOnChainBalanceReceipt; diff --git a/migration/src/lib.rs b/migration/src/lib.rs index ae9adaf7..91c45391 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -27,6 +27,7 @@ mod m20230412_171916_modify_secondary_user_add_primary_user; mod m20230422_172555_premium_downgrade_logic; mod m20230511_161214_remove_columns_statsv2_origin_and_method; mod m20230512_220213_allow_null_rpc_key_id_in_stats_v2; +mod m20230514_114803_admin_add_credits; pub struct Migrator; @@ -51,16 +52,17 @@ impl MigratorTrait for Migrator { Box::new(m20230125_204810_stats_v2::Migration), Box::new(m20230130_124740_read_only_login_logic::Migration), Box::new(m20230130_165144_prepare_admin_imitation_pre_login::Migration), - Box::new(m20230215_152254_admin_trail::Migration), - Box::new(m20230307_002623_migrate_rpc_accounting_to_rpc_accounting_v2::Migration), Box::new(m20230205_130035_create_balance::Migration), Box::new(m20230205_133755_create_referrals::Migration), Box::new(m20230214_134254_increase_balance_transactions::Migration), + Box::new(m20230215_152254_admin_trail::Migration), Box::new(m20230221_230953_track_spend::Migration), + Box::new(m20230307_002623_migrate_rpc_accounting_to_rpc_accounting_v2::Migration), Box::new(m20230412_171916_modify_secondary_user_add_primary_user::Migration), Box::new(m20230422_172555_premium_downgrade_logic::Migration), Box::new(m20230511_161214_remove_columns_statsv2_origin_and_method::Migration), Box::new(m20230512_220213_allow_null_rpc_key_id_in_stats_v2::Migration), + Box::new(m20230514_114803_admin_add_credits::Migration), ] } } diff --git a/migration/src/m20230514_114803_admin_add_credits.rs b/migration/src/m20230514_114803_admin_add_credits.rs new file mode 100644 index 00000000..0344d5d6 --- /dev/null +++ b/migration/src/m20230514_114803_admin_add_credits.rs @@ -0,0 +1,97 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_table( + Table::create() + .table(AdminIncreaseBalanceReceipt::Table) + .if_not_exists() + .col( + ColumnDef::new(AdminIncreaseBalanceReceipt::Id) + .integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col( + ColumnDef::new(AdminIncreaseBalanceReceipt::Amount) + .decimal_len(20, 10) + .not_null(), + ) + .col( + ColumnDef::new(AdminIncreaseBalanceReceipt::AdminId) + .big_unsigned() + .not_null(), + ) + .foreign_key( + ForeignKey::create() + .name("fk-admin_id") + .from( + AdminIncreaseBalanceReceipt::Table, + AdminIncreaseBalanceReceipt::AdminId, + ) + .to(Admin::Table, Admin::Id), + ) + .col( + ColumnDef::new(AdminIncreaseBalanceReceipt::DepositToUserId) + .big_unsigned() + .not_null(), + ) + .foreign_key( + ForeignKey::create() + .name("fk-admin_deposits_to_user_id") + .from( + AdminIncreaseBalanceReceipt::Table, + AdminIncreaseBalanceReceipt::DepositToUserId, + ) + .to(User::Table, User::Id), + ) + .col( + ColumnDef::new(AdminIncreaseBalanceReceipt::Note) + .string() + .not_null(), + ) + .to_owned(), + ) + .await + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_table( + Table::drop() + .table(AdminIncreaseBalanceReceipt::Table) + .to_owned(), + ) + .await + } +} + +#[derive(Iden)] +enum Admin { + Table, + Id, +} + +/// Learn more at https://docs.rs/sea-query#iden +#[derive(Iden)] +enum User { + Table, + Id, +} + +/// Learn more at https://docs.rs/sea-query#iden +#[derive(Iden)] +enum AdminIncreaseBalanceReceipt { + Table, + Id, + Amount, + AdminId, + DepositToUserId, + Note, +} diff --git a/scripts/manual-tests/45-admin-add-balance.sh b/scripts/manual-tests/45-admin-add-balance.sh new file mode 100644 index 00000000..61b194f8 --- /dev/null +++ b/scripts/manual-tests/45-admin-add-balance.sh @@ -0,0 +1,44 @@ + +# Create / Login user1 +curl -X GET "http://127.0.0.1:8544/user/login/0xeb3e928a2e54be013ef8241d4c9eaf4dfae94d5a" +curl -X POST http://127.0.0.1:8544/user/login \ + -H 'Content-Type: application/json' \ + -d '{ + "address": "0xeb3e928a2e54be013ef8241d4c9eaf4dfae94d5a", + "msg": "0x6c6c616d616e6f6465732e636f6d2077616e747320796f7520746f207369676e20696e207769746820796f757220457468657265756d206163636f756e743a0a3078654233453932384132453534424530313345463832343164344339456146344466414539344435610a0af09fa699f09fa699f09fa699f09fa699f09fa6990a0a5552493a2068747470733a2f2f6c6c616d616e6f6465732e636f6d2f0a56657273696f6e3a20310a436861696e2049443a20310a4e6f6e63653a203031483044573642334a48355a4b384a4e3947504d594e4d4b370a4973737565642041743a20323032332d30352d31345431393a33353a35352e3736323632395a0a45787069726174696f6e2054696d653a20323032332d30352d31345431393a35353a35352e3736323632395a", + "sig": "f88b42d638246f8e51637c753052cab3a13b2a138faf3107c921ce2f0027d6506b9adcd3a7b72af830cdf50d20e6e9cb3f9f456dd1be47f6543990ea050909791c", + "version": "3", + "signer": "MEW" + }' + +# 01H0DW6VFCP365B9TXVQVVMHHY +# 01H0DVZNDJWQ7YG8RBHXQHJ301 + +# Make user1 an admin +cargo run change_admin_status 0xeB3E928A2E54BE013EF8241d4C9EaF4DfAE94D5a true + +# Create/Login user2 +curl -X GET "http://127.0.0.1:8544/user/login/0x762390ae7a3c4D987062a398C1eA8767029AB08E" + +curl -X POST http://127.0.0.1:8544/user/login \ + -H 'Content-Type: application/json' \ + -d '{ + "address": "0x762390ae7a3c4d987062a398c1ea8767029ab08e", + "msg": "0x6c6c616d616e6f6465732e636f6d2077616e747320796f7520746f207369676e20696e207769746820796f757220457468657265756d206163636f756e743a0a3078373632333930616537613363344439383730363261333938433165413837363730323941423038450a0af09fa699f09fa699f09fa699f09fa699f09fa6990a0a5552493a2068747470733a2f2f6c6c616d616e6f6465732e636f6d2f0a56657273696f6e3a20310a436861696e2049443a20310a4e6f6e63653a20303148304457384233304e534447594e484d33514d4a31434e530a4973737565642041743a20323032332d30352d31345431393a33373a30312e3238303338355a0a45787069726174696f6e2054696d653a20323032332d30352d31345431393a35373a30312e3238303338355a", + "sig": "c545235557b7952a789dffa2af153af5cf663dcc05449bcc4b651b04cda57de05bcef55c0f5cbf6aa2432369582eb6a40927d14ad0a2d15f48fa45f32fbf273f1c", + "version": "3", + "signer": "MEW" + }' + +# 01H0DWPXRQA7XX2VFSNR02CG1N +# 01H0DWPXQQ951Y3R90QMF6MYGE + +curl \ +-H "Authorization: Bearer 01H0DWPXRQA7XX2VFSNR02CG1N" \ +-X GET "127.0.0.1:8544/user/balance" + + +# Admin add balance +curl \ +-H "Authorization: Bearer 01H0DW6VFCP365B9TXVQVVMHHY" \ +-X GET "127.0.0.1:8544/admin/increase_balance?user_address=0x762390ae7a3c4D987062a398C1eA8767029AB08E&amount=100.0" diff --git a/web3_proxy/src/frontend/admin.rs b/web3_proxy/src/frontend/admin.rs index c3ddf453..e2527b93 100644 --- a/web3_proxy/src/frontend/admin.rs +++ b/web3_proxy/src/frontend/admin.rs @@ -5,8 +5,11 @@ use super::errors::Web3ProxyResponse; use crate::admin_queries::query_admin_modify_usertier; use crate::app::Web3ProxyApp; use crate::frontend::errors::{Web3ProxyError, Web3ProxyErrorContext}; +use crate::http_params::get_user_id_from_params; use crate::user_token::UserBearerToken; use crate::PostLogin; +use anyhow::Context; +use axum::body::HttpBody; use axum::{ extract::{Path, Query}, headers::{authorization::Bearer, Authorization}, @@ -16,15 +19,20 @@ use axum::{ use axum_client_ip::InsecureClientIp; use axum_macros::debug_handler; use chrono::{TimeZone, Utc}; -use entities::{admin_trail, login, pending_login, rpc_key, user}; +use entities::{ + admin, admin_increase_balance_receipt, admin_trail, balance, login, pending_login, rpc_key, + user, user_tier, +}; use ethers::{prelude::Address, types::Bytes}; use hashbrown::HashMap; use http::StatusCode; use log::{debug, info, warn}; -use migration::sea_orm::prelude::Uuid; +use migration::sea_orm::prelude::{Decimal, Uuid}; use migration::sea_orm::{ - self, ActiveModelTrait, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter, + self, ActiveModelTrait, ActiveValue, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter, + TransactionTrait, Update, }; +use migration::{ConnectionTrait, Expr, OnConflict}; use serde_json::json; use siwe::{Message, VerificationOpts}; use std::ops::Add; @@ -33,6 +41,138 @@ use std::sync::Arc; use time::{Duration, OffsetDateTime}; use ulid::Ulid; +/// `GET /admin/increase_balance` -- As an admin, modify a user's user-tier +/// +/// - user_address that is to credited balance +/// - user_role_tier that is supposed to be adapted +#[debug_handler] +pub async fn admin_increase_balance( + Extension(app): Extension>, + TypedHeader(Authorization(bearer)): TypedHeader>, + Query(params): Query>, +) -> Web3ProxyResponse { + let (caller, _) = app.bearer_is_authorized(bearer).await?; + let caller_id = caller.id; + + // Establish connections + let db_conn = app + .db_conn() + .context("query_admin_modify_user needs a db")?; + + // Check if the caller is an admin (if not, return early) + let admin_entry: admin::Model = admin::Entity::find() + .filter(admin::Column::UserId.eq(caller_id)) + .one(&db_conn) + .await? + .ok_or(Web3ProxyError::AccessDenied)?; + + // Get the user from params + let user_address: Address = params + .get("user_address") + .ok_or_else(|| { + Web3ProxyError::BadRequest("Unable to find user_address key in request".to_string()) + })? + .parse::
() + .map_err(|_| { + Web3ProxyError::BadRequest("Unable to parse user_address as an Address".to_string()) + })?; + let user_address_bytes: Vec = user_address.clone().to_fixed_bytes().into(); + let note: String = params + .get("note") + .ok_or_else(|| { + Web3ProxyError::BadRequest("Unable to find 'note' key in request".to_string()) + })? + .parse::() + .map_err(|_| { + Web3ProxyError::BadRequest("Unable to parse 'note' as a String".to_string()) + })?; + // Get the amount from params + // Decimal::from_str + let amount: Decimal = params + .get("amount") + .ok_or_else(|| { + Web3ProxyError::BadRequest("Unable to get the amount key from the request".to_string()) + }) + .map(|x| Decimal::from_str(x))? + .or_else(|err| { + Err(Web3ProxyError::BadRequest(format!( + "Unable to parse amount from the request {:?}", + err + ))) + })?; + + let user_entry: user::Model = user::Entity::find() + .filter(user::Column::Address.eq(user_address_bytes.clone())) + .one(&db_conn) + .await? + .ok_or(Web3ProxyError::BadRequest( + "No user with this id found".to_string(), + ))?; + + let increase_balance_receipt = admin_increase_balance_receipt::ActiveModel { + amount: sea_orm::Set(amount), + admin_id: sea_orm::Set(admin_entry.id), + deposit_to_user_id: sea_orm::Set(user_entry.id), + note: sea_orm::Set(note), + ..Default::default() + }; + increase_balance_receipt.save(&db_conn).await?; + + let mut out = HashMap::new(); + out.insert( + "user", + serde_json::Value::String(format!("{:?}", user_address)), + ); + out.insert("amount", serde_json::Value::String(amount.to_string())); + + // Get the balance row + let balance_entry: balance::Model = balance::Entity::find() + .filter(balance::Column::UserId.eq(user_entry.id)) + .one(&db_conn) + .await? + .context("User does not have a balance row")?; + + // Finally make the user premium if balance is above 10$ + let premium_user_tier = user_tier::Entity::find() + .filter(user_tier::Column::Title.eq("Premium")) + .one(&db_conn) + .await? + .context("Premium tier was not found!")?; + + let balance_entry = balance_entry.into_active_model(); + balance::Entity::insert(balance_entry) + .on_conflict( + OnConflict::new() + .values([ + // ( + // balance::Column::Id, + // Expr::col(balance::Column::Id).add(self.frontend_requests), + // ), + ( + balance::Column::AvailableBalance, + Expr::col(balance::Column::AvailableBalance).add(amount), + ), + // ( + // balance::Column::Used, + // Expr::col(balance::Column::UsedBalance).add(self.backend_retries), + // ), + // ( + // balance::Column::UserId, + // Expr::col(balance::Column::UserId).add(self.no_servers), + // ), + ]) + .to_owned(), + ) + .exec(&db_conn) + .await?; + // TODO: Downgrade otherwise, right now not functioning properly + + // Then read and save in one transaction + let response = (StatusCode::OK, Json(out)).into_response(); + + Ok(response) +} + /// `GET /admin/modify_role` -- As an admin, modify a user's user-tier /// /// - user_address that is to be modified diff --git a/web3_proxy/src/frontend/mod.rs b/web3_proxy/src/frontend/mod.rs index e1496960..107360c4 100644 --- a/web3_proxy/src/frontend/mod.rs +++ b/web3_proxy/src/frontend/mod.rs @@ -199,6 +199,10 @@ pub async fn serve( "/user/logout", post(users::authentication::user_logout_post), ) + .route( + "/admin/increase_balance", + get(admin::admin_increase_balance), + ) .route("/admin/modify_role", get(admin::admin_change_user_roles)) .route( "/admin/imitate-login/:admin_address/:user_address", From 27333a0028f04df6743fa5f12ea16a34d980b233 Mon Sep 17 00:00:00 2001 From: David Date: Mon, 22 May 2023 20:08:35 -0400 Subject: [PATCH 2/2] David/devel/debug graph (#82) * now should also group by archive_needed (turns out this was wanted) * influxdb query also groups by archive_needed now * updated error_response * updated error_response --- scripts/generate-requests-and-stats.sh | 2 +- scripts/manual-tests/42-simple-balance.sh | 14 +++---- web3_proxy/src/stats/influxdb_queries.rs | 47 +++++++++++------------ 3 files changed, 30 insertions(+), 33 deletions(-) diff --git a/scripts/generate-requests-and-stats.sh b/scripts/generate-requests-and-stats.sh index ecae4466..a05e55e7 100644 --- a/scripts/generate-requests-and-stats.sh +++ b/scripts/generate-requests-and-stats.sh @@ -5,4 +5,4 @@ # https://github.com/INFURA/versus # ./ethspam | ./versus --stop-after 100 "http://localhost:8544/" # Pipe into the endpoint ..., add a bearer token and all that -./ethspam http://127.0.0.1:8544 | ./versus --stop-after 100 http://localhost:8544 +./ethspam http://127.0.0.1:8544/rpc/01H0ZZJDNNEW49FRFS4D9SPR8B | ./versus --concurrency=4 --stop-after 100 http://localhost:8544/rpc/01H0ZZJDNNEW49FRFS4D9SPR8B diff --git a/scripts/manual-tests/42-simple-balance.sh b/scripts/manual-tests/42-simple-balance.sh index ce6e32da..724d4809 100644 --- a/scripts/manual-tests/42-simple-balance.sh +++ b/scripts/manual-tests/42-simple-balance.sh @@ -24,14 +24,14 @@ curl -X POST http://127.0.0.1:8544/user/login \ -H 'Content-Type: application/json' \ -d '{ "address": "0xeb3e928a2e54be013ef8241d4c9eaf4dfae94d5a", - "msg": "0x6c6c616d616e6f6465732e636f6d2077616e747320796f7520746f207369676e20696e207769746820796f757220457468657265756d206163636f756e743a0a3078654233453932384132453534424530313345463832343164344339456146344466414539344435610a0af09fa699f09fa699f09fa699f09fa699f09fa6990a0a5552493a2068747470733a2f2f6c6c616d616e6f6465732e636f6d2f0a56657273696f6e3a20310a436861696e2049443a20310a4e6f6e63653a203031475a4b384b4847305259474737514e5132475037464444470a4973737565642041743a20323032332d30352d30345431313a33333a32312e3533363734355a0a45787069726174696f6e2054696d653a20323032332d30352d30345431313a35333a32312e3533363734355a", - "sig": "cebd9effff15f4517e53522dbe91798d59dc0df0299faaec25d3f6443fa121f847e4311d5ca7386e75b87d6d45df92b8ced58c822117519c666ab1a6b2fc7bd21b", + "msg": "0x6c6c616d616e6f6465732e636f6d2077616e747320796f7520746f207369676e20696e207769746820796f757220457468657265756d206163636f756e743a0a3078654233453932384132453534424530313345463832343164344339456146344466414539344435610a0af09fa699f09fa699f09fa699f09fa699f09fa6990a0a5552493a2068747470733a2f2f6c6c616d616e6f6465732e636f6d2f0a56657273696f6e3a20310a436861696e2049443a20310a4e6f6e63653a20303148305a5a48434356324b32324738544850535758485131480a4973737565642041743a20323032332d30352d32315432303a32303a34332e3033353539315a0a45787069726174696f6e2054696d653a20323032332d30352d32315432303a34303a34332e3033353539315a", + "sig": "7591251840bf75d2ab7c895bc566a49d2f4c3ad6bb14d7256258a59e52055fc94c11f8f3836f5311b52fc18aca40867cd85802636645e1d757494800631cad381c", "version": "3", "signer": "MEW" }' -# bearer token is: 01GZK8MHHGQWK4VPGF97HS91MB -# scret key is: 01GZK65YNV0P0WN2SCXYTW3R9S +# bearer token is: 01H0ZZJDQ2F02MAXZR5K1X5NCP +# scret key is: 01H0ZZJDNNEW49FRFS4D9SPR8B # 01GZH2PS89EJJY6V8JFCVTQ4BX # 01GZH2PS7CTHA3TAZ4HXCTX6KQ @@ -42,7 +42,7 @@ curl -X POST http://127.0.0.1:8544/user/login \ # Check the balance of the user # Balance seems to be returning properly (0, in this test case) curl \ --H "Authorization: Bearer 01GZK8MHHGQWK4VPGF97HS91MB" \ +-H "Authorization: Bearer 01H0ZZJDQ2F02MAXZR5K1X5NCP" \ -X GET "127.0.0.1:8544/user/balance" @@ -73,10 +73,10 @@ curl \ ## Check if calling an RPC endpoint logs the stats ## This one does already even it seems -for i in {1..100} +for i in {1..300} do curl \ - -X POST "127.0.0.1:8544/rpc/01GZK65YNV0P0WN2SCXYTW3R9S" \ + -X POST "127.0.0.1:8544/rpc/01H0ZZJDNNEW49FRFS4D9SPR8B" \ -H "Content-Type: application/json" \ --data '{"method":"eth_blockNumber","params":[],"id":1,"jsonrpc":"2.0"}' done diff --git a/web3_proxy/src/stats/influxdb_queries.rs b/web3_proxy/src/stats/influxdb_queries.rs index 368df1f1..69d1110c 100644 --- a/web3_proxy/src/stats/influxdb_queries.rs +++ b/web3_proxy/src/stats/influxdb_queries.rs @@ -73,7 +73,9 @@ pub async fn query_user_stats<'a>( let mut join_candidates: Vec = vec![ "_time".to_string(), "_measurement".to_string(), + "archive_needed".to_string(), "chain_id".to_string(), + "error_response".to_string(), ]; // Include a hashmap to go from rpc_secret_key_id to the rpc_secret_key @@ -184,35 +186,18 @@ pub async fn query_user_stats<'a>( {filter_chain_id} {drop_method} - // cumsum = base base |> aggregateWindow(every: {query_window_seconds}s, fn: sum, createEmpty: false) |> pivot(rowKey: ["_time"], columnKey: ["_field"], valueColumn: "_value") |> drop(columns: ["balance"]) - |> map(fn: (r) => ({{ r with "archive_needed": if r.archive_needed == "true" then r.frontend_requests else 0}})) - |> map(fn: (r) => ({{ r with "error_response": if r.error_response == "true" then r.frontend_requests else 0}})) - |> group(columns: ["_time", "_measurement", "chain_id", "method", "rpc_secret_key_id"]) + |> group(columns: ["_time", "_measurement", "archive_needed", "chain_id", "error_response", "method", "rpc_secret_key_id"]) |> sort(columns: ["frontend_requests"]) |> map(fn:(r) => ({{ r with "sum_credits_used": float(v: r["sum_credits_used"]) }})) - |> cumulativeSum(columns: ["archive_needed", "error_response", "backend_requests", "cache_hits", "cache_misses", "frontend_requests", "sum_credits_used", "sum_request_bytes", "sum_response_bytes", "sum_response_millis"]) + |> cumulativeSum(columns: ["backend_requests", "cache_hits", "cache_misses", "frontend_requests", "sum_credits_used", "sum_request_bytes", "sum_response_bytes", "sum_response_millis"]) |> sort(columns: ["frontend_requests"], desc: true) |> limit(n: 1) |> group() - |> sort(columns: ["_time", "_measurement", "chain_id", "method", "rpc_secret_key_id"], desc: true) - - // balance = base - // |> toFloat() - // |> aggregateWindow(every: {query_window_seconds}s, fn: mean, createEmpty: false) - // |> pivot(rowKey: ["_time"], columnKey: ["_field"], valueColumn: "_value") - // |> group(columns: ["_time", "_measurement", "chain_id", "method", "rpc_secret_key_id"]) - // |> mean(column: "balance") - // |> group() - // |> sort(columns: ["_time", "_measurement", "chain_id", "method", "rpc_secret_key_id"], desc: true) - - // join( - // tables: {{cumsum, balance}}, - // on: {join_candidates} - // ) + |> sort(columns: ["_time", "_measurement", "archive_needed", "chain_id", "error_response", "method", "rpc_secret_key_id"], desc: true) "#); info!("Raw query to db is: {:?}", query); @@ -438,22 +423,34 @@ pub async fn query_user_stats<'a>( } } else if key == "archive_needed" { match value { - influxdb2_structmap::value::Value::Long(inner) => { + influxdb2_structmap::value::Value::String(inner) => { out.insert( "archive_needed".to_owned(), - serde_json::Value::Number(inner.into()), + if inner == "true" { + serde_json::Value::Bool(true) + } else if inner == "false" { + serde_json::Value::Bool(false) + } else { + serde_json::Value::String("error".to_owned()) + }, ); } _ => { - error!("archive_needed should always be a Long!"); + error!("archive_needed should always be a String!"); } } } else if key == "error_response" { match value { - influxdb2_structmap::value::Value::Long(inner) => { + influxdb2_structmap::value::Value::String(inner) => { out.insert( "error_response".to_owned(), - serde_json::Value::Number(inner.into()), + if inner == "true" { + serde_json::Value::Bool(true) + } else if inner == "false" { + serde_json::Value::Bool(false) + } else { + serde_json::Value::String("error".to_owned()) + }, ); } _ => {