split command line into separte module
This commit is contained in:
parent
e0d7d11398
commit
ab6d3a1d9b
|
@ -4348,17 +4348,6 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proctitle"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "924cd8a0de90723d63fed19c5035ea129913a0bc998b37686a67f1eaf6a2aab5"
|
|
||||||
dependencies = [
|
|
||||||
"lazy_static",
|
|
||||||
"libc",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prost"
|
name = "prost"
|
||||||
version = "0.11.9"
|
version = "0.11.9"
|
||||||
|
@ -7219,7 +7208,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web3_proxy"
|
name = "web3_proxy"
|
||||||
version = "1.42.1"
|
version = "1.42.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"arc-swap",
|
"arc-swap",
|
||||||
|
@ -7268,8 +7257,6 @@ dependencies = [
|
||||||
"pagerduty-rs",
|
"pagerduty-rs",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
"payment-contracts",
|
"payment-contracts",
|
||||||
"prettytable",
|
|
||||||
"proctitle",
|
|
||||||
"rdkafka",
|
"rdkafka",
|
||||||
"redis-rate-limiter",
|
"redis-rate-limiter",
|
||||||
"regex",
|
"regex",
|
||||||
|
@ -7300,6 +7287,22 @@ dependencies = [
|
||||||
"uuid 1.4.1",
|
"uuid 1.4.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web3_proxy_cli"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"env_logger",
|
||||||
|
"parking_lot",
|
||||||
|
"prettytable",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"test-log",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
|
"web3_proxy",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki"
|
name = "webpki"
|
||||||
version = "0.22.0"
|
version = "0.22.0"
|
||||||
|
|
|
@ -8,6 +8,7 @@ members = [
|
||||||
"rate-counter",
|
"rate-counter",
|
||||||
"redis-rate-limiter",
|
"redis-rate-limiter",
|
||||||
"web3_proxy",
|
"web3_proxy",
|
||||||
|
"web3_proxy_cli",
|
||||||
]
|
]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ RUN --mount=type=cache,target=/root/.cargo/git \
|
||||||
FROM rust as rust_with_env
|
FROM rust as rust_with_env
|
||||||
|
|
||||||
# changing our features doesn't change any of the steps above
|
# changing our features doesn't change any of the steps above
|
||||||
ENV WEB3_PROXY_FEATURES "deadlock_detection,rdkafka-src"
|
ENV WEB3_PROXY_FEATURES "rdkafka-src"
|
||||||
|
|
||||||
# copy the app
|
# copy the app
|
||||||
COPY . .
|
COPY . .
|
||||||
|
@ -130,7 +130,7 @@ RUN --mount=type=cache,target=/root/.cargo/git \
|
||||||
--frozen \
|
--frozen \
|
||||||
--no-default-features \
|
--no-default-features \
|
||||||
--offline \
|
--offline \
|
||||||
--path ./web3_proxy \
|
--path ./web3_proxy_cli \
|
||||||
--root /usr/local \
|
--root /usr/local \
|
||||||
; \
|
; \
|
||||||
/usr/local/bin/web3_proxy_cli --help | grep 'Usage: web3_proxy_cli'
|
/usr/local/bin/web3_proxy_cli --help | grep 'Usage: web3_proxy_cli'
|
||||||
|
|
|
@ -50,7 +50,7 @@ RUST_LOG=web3_proxy=trace,info cargo nextest run
|
||||||
Run more tests:
|
Run more tests:
|
||||||
|
|
||||||
```
|
```
|
||||||
RUST_LOG=web3_proxy=trace,info cargo nextest run --features tests-needing-docker
|
RUST_LOG=web3_proxy=trace,info cargo nextest run --features tests-needing-docker,tests_utils
|
||||||
```
|
```
|
||||||
|
|
||||||
## Mysql
|
## Mysql
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
[package]
|
[package]
|
||||||
name = "web3_proxy"
|
name = "web3_proxy"
|
||||||
version = "1.42.1"
|
version = "1.42.2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
default-run = "web3_proxy_cli"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["deadlock_detection"]
|
default = []
|
||||||
deadlock_detection = ["parking_lot/deadlock_detection"]
|
|
||||||
mimalloc = ["dep:mimalloc"]
|
mimalloc = ["dep:mimalloc"]
|
||||||
tokio-console = ["dep:tokio-console", "dep:console-subscriber"]
|
|
||||||
rdkafka-src = ["rdkafka/cmake-build", "rdkafka/libz", "rdkafka/ssl-vendored", "rdkafka/zstd-pkg-config"]
|
rdkafka-src = ["rdkafka/cmake-build", "rdkafka/libz", "rdkafka/ssl-vendored", "rdkafka/zstd-pkg-config"]
|
||||||
tests-needing-docker = []
|
tests-needing-docker = []
|
||||||
|
tokio-console = ["dep:tokio-console", "dep:console-subscriber"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
deferred-rate-limiter = { path = "../deferred-rate-limiter" }
|
deferred-rate-limiter = { path = "../deferred-rate-limiter" }
|
||||||
|
@ -74,8 +73,6 @@ once_cell = { version = "1.18.0" }
|
||||||
ordered-float = {version = "3.7.0" }
|
ordered-float = {version = "3.7.0" }
|
||||||
pagerduty-rs = { version = "0.1.6", default-features = false, features = ["async", "rustls", "sync"] }
|
pagerduty-rs = { version = "0.1.6", default-features = false, features = ["async", "rustls", "sync"] }
|
||||||
parking_lot = { version = "0.12.1", features = ["arc_lock", "nightly"] }
|
parking_lot = { version = "0.12.1", features = ["arc_lock", "nightly"] }
|
||||||
prettytable = "0.10.0"
|
|
||||||
proctitle = "0.1.1"
|
|
||||||
rdkafka = { version = "0.33.2", features = ["tracing"] }
|
rdkafka = { version = "0.33.2", features = ["tracing"] }
|
||||||
regex = "1.9.1"
|
regex = "1.9.1"
|
||||||
reqwest = { version = "0.11.18", default-features = false, features = ["deflate", "gzip", "json", "tokio-rustls"] }
|
reqwest = { version = "0.11.18", default-features = false, features = ["deflate", "gzip", "json", "tokio-rustls"] }
|
||||||
|
@ -97,7 +94,6 @@ toml = "0.7.6"
|
||||||
tower = { version = "0.4.13", features = ["timeout", "tracing"] }
|
tower = { version = "0.4.13", features = ["timeout", "tracing"] }
|
||||||
tower-http = { version = "0.4.3", features = ["cors", "normalize-path", "sensitive-headers", "trace"] }
|
tower-http = { version = "0.4.3", features = ["cors", "normalize-path", "sensitive-headers", "trace"] }
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
||||||
ulid = { version = "1.0.0", features = ["rand", "uuid", "serde"] }
|
ulid = { version = "1.0.0", features = ["rand", "uuid", "serde"] }
|
||||||
url = { version = "2.4.0" }
|
url = { version = "2.4.0" }
|
||||||
uuid = { version = "1.4.1", default-features = false, features = ["fast-rng", "v4", "zerocopy"] }
|
uuid = { version = "1.4.1", default-features = false, features = ["fast-rng", "v4", "zerocopy"] }
|
||||||
|
|
|
@ -16,6 +16,7 @@ pub mod globals;
|
||||||
pub mod http_params;
|
pub mod http_params;
|
||||||
pub mod jsonrpc;
|
pub mod jsonrpc;
|
||||||
pub mod pagerduty;
|
pub mod pagerduty;
|
||||||
|
pub mod prelude;
|
||||||
pub mod premium;
|
pub mod premium;
|
||||||
pub mod prometheus;
|
pub mod prometheus;
|
||||||
pub mod referral_code;
|
pub mod referral_code;
|
||||||
|
@ -23,5 +24,5 @@ pub mod relational_db;
|
||||||
pub mod response_cache;
|
pub mod response_cache;
|
||||||
pub mod rpcs;
|
pub mod rpcs;
|
||||||
pub mod stats;
|
pub mod stats;
|
||||||
pub mod sub_commands;
|
pub mod test_utils;
|
||||||
pub mod user_token;
|
pub mod user_token;
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
pub use anyhow;
|
||||||
|
pub use argh;
|
||||||
|
pub use chrono;
|
||||||
|
pub use entities;
|
||||||
|
pub use ethers;
|
||||||
|
pub use ethers::prelude::rand;
|
||||||
|
pub use fdlimit;
|
||||||
|
pub use futures;
|
||||||
|
pub use glob;
|
||||||
|
pub use hashbrown;
|
||||||
|
pub use http;
|
||||||
|
pub use influxdb2;
|
||||||
|
pub use migration;
|
||||||
|
pub use migration::sea_orm;
|
||||||
|
pub use moka;
|
||||||
|
pub use num;
|
||||||
|
pub use ordered_float;
|
||||||
|
pub use pagerduty_rs;
|
||||||
|
pub use parking_lot;
|
||||||
|
pub use rdkafka;
|
||||||
|
pub use reqwest;
|
||||||
|
pub use rmp_serde;
|
||||||
|
pub use rust_decimal;
|
||||||
|
pub use sentry;
|
||||||
|
pub use sentry_tracing;
|
||||||
|
pub use serde;
|
||||||
|
pub use serde_inline_default;
|
||||||
|
pub use serde_json;
|
||||||
|
pub use tokio;
|
||||||
|
pub use toml;
|
||||||
|
pub use tracing;
|
||||||
|
pub use ulid;
|
||||||
|
pub use url;
|
||||||
|
pub use uuid;
|
|
@ -617,3 +617,73 @@ impl RpcQueryStats {
|
||||||
Ok(x)
|
Ok(x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::test_utils::TestInflux;
|
||||||
|
use crate::{caches::UserBalanceCache, stats::StatBuffer};
|
||||||
|
use moka::future::Cache;
|
||||||
|
use tokio::sync::{broadcast, mpsc};
|
||||||
|
|
||||||
|
#[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
||||||
|
#[test_log::test(tokio::test)]
|
||||||
|
async fn test_two_buffers() {
|
||||||
|
let i = TestInflux::spawn().await;
|
||||||
|
|
||||||
|
let billing_period_seconds = 86400 * 7;
|
||||||
|
let chain_id = 999_001_999;
|
||||||
|
let db_save_interval_seconds = 60;
|
||||||
|
let influxdb_bucket = Some(i.bucket.clone());
|
||||||
|
let influxdb_client = Some(i.client.clone());
|
||||||
|
let rpc_secret_key_cache = Cache::builder().build();
|
||||||
|
let tsdb_save_interval_seconds = 30;
|
||||||
|
let user_balance_cache: UserBalanceCache = Cache::builder().build().into();
|
||||||
|
|
||||||
|
let (shutdown_sender, shutdown_receiver_1) = broadcast::channel(1);
|
||||||
|
let shutdown_receiver_2 = shutdown_sender.subscribe();
|
||||||
|
|
||||||
|
let (flush_sender_1, flush_receiver_1) = mpsc::channel(1);
|
||||||
|
let (flush_sender_2, flush_receiver_2) = mpsc::channel(1);
|
||||||
|
|
||||||
|
let buffer_1 = StatBuffer::try_spawn(
|
||||||
|
billing_period_seconds,
|
||||||
|
chain_id,
|
||||||
|
db_save_interval_seconds,
|
||||||
|
influxdb_bucket.clone(),
|
||||||
|
influxdb_client.clone(),
|
||||||
|
rpc_secret_key_cache.clone(),
|
||||||
|
user_balance_cache.clone(),
|
||||||
|
shutdown_receiver_1,
|
||||||
|
tsdb_save_interval_seconds,
|
||||||
|
flush_sender_1,
|
||||||
|
flush_receiver_1,
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let buffer_2 = StatBuffer::try_spawn(
|
||||||
|
billing_period_seconds,
|
||||||
|
chain_id,
|
||||||
|
db_save_interval_seconds,
|
||||||
|
influxdb_bucket,
|
||||||
|
influxdb_client,
|
||||||
|
rpc_secret_key_cache,
|
||||||
|
user_balance_cache,
|
||||||
|
shutdown_receiver_2,
|
||||||
|
tsdb_save_interval_seconds,
|
||||||
|
flush_sender_2,
|
||||||
|
flush_receiver_2,
|
||||||
|
2,
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// TODO: send things to the buffers
|
||||||
|
|
||||||
|
shutdown_sender.send(()).unwrap();
|
||||||
|
|
||||||
|
buffer_1.background_handle.await.unwrap().unwrap();
|
||||||
|
buffer_2.background_handle.await.unwrap().unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// TODO: option to spawn in a dedicated thread?
|
// TODO: option to spawn in a dedicated thread?
|
||||||
// TODO: option to subscribe to another anvil and copy blocks
|
// TODO: option to subscribe to another anvil and copy blocks
|
||||||
|
|
||||||
|
use crate::rpcs::provider::EthersHttpProvider;
|
||||||
use ethers::{
|
use ethers::{
|
||||||
signers::LocalWallet,
|
signers::LocalWallet,
|
||||||
utils::{Anvil, AnvilInstance},
|
utils::{Anvil, AnvilInstance},
|
||||||
};
|
};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
use web3_proxy::rpcs::provider::EthersHttpProvider;
|
|
||||||
|
|
||||||
/// on drop, the anvil instance will be shut down
|
/// on drop, the anvil instance will be shut down
|
||||||
pub struct TestAnvil {
|
pub struct TestAnvil {
|
||||||
|
@ -15,7 +15,6 @@ pub struct TestAnvil {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestAnvil {
|
impl TestAnvil {
|
||||||
#[allow(unused)]
|
|
||||||
pub async fn spawn(chain_id: u64) -> Self {
|
pub async fn spawn(chain_id: u64) -> Self {
|
||||||
info!(?chain_id);
|
info!(?chain_id);
|
||||||
|
|
||||||
|
@ -30,7 +29,6 @@ impl TestAnvil {
|
||||||
Self { instance, provider }
|
Self { instance, provider }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub fn wallet(&self, id: usize) -> LocalWallet {
|
pub fn wallet(&self, id: usize) -> LocalWallet {
|
||||||
self.instance.keys()[id].clone().into()
|
self.instance.keys()[id].clone().into()
|
||||||
}
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
use crate::rpcs::provider::EthersHttpProvider;
|
||||||
|
use ulid::Ulid;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
pub async fn create_provider_for_user(url: &Url, user_secret_key: &Ulid) -> EthersHttpProvider {
|
||||||
|
// Then generate a provider
|
||||||
|
let proxy_endpoint = format!("{}rpc/{}", url, user_secret_key);
|
||||||
|
|
||||||
|
EthersHttpProvider::try_from(proxy_endpoint).unwrap()
|
||||||
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
use ethers::prelude::rand::{self, distributions::Alphanumeric, Rng};
|
use crate::prelude::influxdb2::Client;
|
||||||
use influxdb2::Client;
|
use crate::prelude::rand::{self, distributions::Alphanumeric, Rng};
|
||||||
use std::process::Command as SyncCommand;
|
use crate::prelude::tokio::{
|
||||||
use std::time::Duration;
|
|
||||||
use tokio::{
|
|
||||||
net::TcpStream,
|
net::TcpStream,
|
||||||
process::Command as AsyncCommand,
|
process::Command as AsyncCommand,
|
||||||
time::{sleep, Instant},
|
time::{sleep, Instant},
|
||||||
};
|
};
|
||||||
|
use std::process::Command as SyncCommand;
|
||||||
|
use std::time::Duration;
|
||||||
use tracing::{info, trace};
|
use tracing::{info, trace};
|
||||||
|
|
||||||
/// on drop, the mysql docker container will be shut down
|
/// on drop, the mysql docker container will be shut down
|
||||||
|
@ -21,7 +21,6 @@ pub struct TestInflux {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestInflux {
|
impl TestInflux {
|
||||||
#[allow(unused)]
|
|
||||||
pub async fn spawn() -> Self {
|
pub async fn spawn() -> Self {
|
||||||
let random: String = rand::thread_rng()
|
let random: String = rand::thread_rng()
|
||||||
.sample_iter(&Alphanumeric)
|
.sample_iter(&Alphanumeric)
|
||||||
|
@ -136,7 +135,7 @@ impl TestInflux {
|
||||||
|
|
||||||
// create the TestInflux as soon as the url is known
|
// create the TestInflux as soon as the url is known
|
||||||
// when this is dropped, the docker container will be stopped
|
// when this is dropped, the docker container will be stopped
|
||||||
let mut test_influx = Self {
|
let test_influx = Self {
|
||||||
host: influx_host,
|
host: influx_host,
|
||||||
org: org.to_string(),
|
org: org.to_string(),
|
||||||
token: admin_token.to_string(),
|
token: admin_token.to_string(),
|
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
pub mod anvil;
|
||||||
|
pub mod create_provider_with_rpc_key;
|
||||||
|
pub mod influx;
|
||||||
|
pub mod mysql;
|
||||||
|
|
||||||
|
pub use self::anvil::TestAnvil;
|
||||||
|
pub use self::influx::TestInflux;
|
||||||
|
pub use self::mysql::TestMysql;
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::relational_db::{connect_db, get_migrated_db};
|
||||||
use ethers::prelude::rand::{self, distributions::Alphanumeric, Rng};
|
use ethers::prelude::rand::{self, distributions::Alphanumeric, Rng};
|
||||||
use migration::sea_orm::DatabaseConnection;
|
use migration::sea_orm::DatabaseConnection;
|
||||||
use std::process::Command as SyncCommand;
|
use std::process::Command as SyncCommand;
|
||||||
|
@ -8,7 +9,6 @@ use tokio::{
|
||||||
time::{sleep, Instant},
|
time::{sleep, Instant},
|
||||||
};
|
};
|
||||||
use tracing::{info, trace, warn};
|
use tracing::{info, trace, warn};
|
||||||
use web3_proxy::relational_db::{connect_db, get_migrated_db};
|
|
||||||
|
|
||||||
/// on drop, the mysql docker container will be shut down
|
/// on drop, the mysql docker container will be shut down
|
||||||
pub struct TestMysql {
|
pub struct TestMysql {
|
||||||
|
@ -17,7 +17,6 @@ pub struct TestMysql {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestMysql {
|
impl TestMysql {
|
||||||
#[allow(unused)]
|
|
||||||
pub async fn spawn() -> Self {
|
pub async fn spawn() -> Self {
|
||||||
let password: String = rand::thread_rng()
|
let password: String = rand::thread_rng()
|
||||||
.sample_iter(&Alphanumeric)
|
.sample_iter(&Alphanumeric)
|
|
@ -1,68 +0,0 @@
|
||||||
mod common;
|
|
||||||
|
|
||||||
use crate::common::influx::TestInflux;
|
|
||||||
use moka::future::Cache;
|
|
||||||
use tokio::sync::{broadcast, mpsc};
|
|
||||||
use web3_proxy::{caches::UserBalanceCache, stats::StatBuffer};
|
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
|
||||||
#[test_log::test(tokio::test)]
|
|
||||||
async fn test_two_buffers() {
|
|
||||||
let i = TestInflux::spawn().await;
|
|
||||||
|
|
||||||
let billing_period_seconds = 86400 * 7;
|
|
||||||
let chain_id = 999_001_999;
|
|
||||||
let db_save_interval_seconds = 60;
|
|
||||||
let influxdb_bucket = Some(i.bucket.clone());
|
|
||||||
let influxdb_client = Some(i.client.clone());
|
|
||||||
let rpc_secret_key_cache = Cache::builder().build();
|
|
||||||
let tsdb_save_interval_seconds = 30;
|
|
||||||
let user_balance_cache: UserBalanceCache = Cache::builder().build().into();
|
|
||||||
|
|
||||||
let (shutdown_sender, shutdown_receiver_1) = broadcast::channel(1);
|
|
||||||
let shutdown_receiver_2 = shutdown_sender.subscribe();
|
|
||||||
|
|
||||||
let (flush_sender_1, flush_receiver_1) = mpsc::channel(1);
|
|
||||||
let (flush_sender_2, flush_receiver_2) = mpsc::channel(1);
|
|
||||||
|
|
||||||
let buffer_1 = StatBuffer::try_spawn(
|
|
||||||
billing_period_seconds,
|
|
||||||
chain_id,
|
|
||||||
db_save_interval_seconds,
|
|
||||||
influxdb_bucket.clone(),
|
|
||||||
influxdb_client.clone(),
|
|
||||||
rpc_secret_key_cache.clone(),
|
|
||||||
user_balance_cache.clone(),
|
|
||||||
shutdown_receiver_1,
|
|
||||||
tsdb_save_interval_seconds,
|
|
||||||
flush_sender_1,
|
|
||||||
flush_receiver_1,
|
|
||||||
1,
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let buffer_2 = StatBuffer::try_spawn(
|
|
||||||
billing_period_seconds,
|
|
||||||
chain_id,
|
|
||||||
db_save_interval_seconds,
|
|
||||||
influxdb_bucket,
|
|
||||||
influxdb_client,
|
|
||||||
rpc_secret_key_cache,
|
|
||||||
user_balance_cache,
|
|
||||||
shutdown_receiver_2,
|
|
||||||
tsdb_save_interval_seconds,
|
|
||||||
flush_sender_2,
|
|
||||||
flush_receiver_2,
|
|
||||||
2,
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// TODO: send things to the buffers
|
|
||||||
|
|
||||||
shutdown_sender.send(()).unwrap();
|
|
||||||
|
|
||||||
buffer_1.background_handle.await.unwrap().unwrap();
|
|
||||||
buffer_2.background_handle.await.unwrap().unwrap();
|
|
||||||
}
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
[package]
|
||||||
|
name = "web3_proxy_cli"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
default-run = "web3_proxy_cli"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
|
||||||
|
deadlock_detection = ["parking_lot/deadlock_detection"]
|
||||||
|
mimalloc = ["web3_proxy/mimalloc"]
|
||||||
|
rdkafka-src = ["web3_proxy/rdkafka-src"]
|
||||||
|
tests-needing-docker = ["web3_proxy/tests-needing-docker"]
|
||||||
|
tokio-console = ["web3_proxy/tokio-console"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
web3_proxy = { path = "../web3_proxy" }
|
||||||
|
|
||||||
|
parking_lot = { version = "0.12.1", features = ["arc_lock", "nightly"] }
|
||||||
|
prettytable = "0.10.0"
|
||||||
|
serde = { version = "1.0.180" }
|
||||||
|
serde_json = { version = "1.0.104", default-features = false, features = ["raw_value"] }
|
||||||
|
tracing = "0.1"
|
||||||
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
env_logger = "0.10"
|
||||||
|
test-log = "0.2.12"
|
||||||
|
tokio = { version = "1.29.1", features = ["full", "test-util"] }
|
||||||
|
tracing = {version = "0.1", default-features = false}
|
||||||
|
tracing-subscriber = {version = "0.3", default-features = false, features = ["env-filter", "fmt"]}
|
|
@ -1,6 +1,9 @@
|
||||||
/// subscribe to a websocket rpc
|
/// subscribe to a websocket rpc
|
||||||
use ethers::prelude::*;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use web3_proxy::prelude::anyhow;
|
||||||
|
use web3_proxy::prelude::ethers::prelude::*;
|
||||||
|
use web3_proxy::prelude::fdlimit;
|
||||||
|
use web3_proxy::prelude::tokio;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
|
@ -1,6 +1,9 @@
|
||||||
/// poll an http rpc
|
/// poll an http rpc
|
||||||
use ethers::prelude::*;
|
|
||||||
use std::{str::FromStr, time::Duration};
|
use std::{str::FromStr, time::Duration};
|
||||||
|
use web3_proxy::prelude::anyhow;
|
||||||
|
use web3_proxy::prelude::ethers::prelude::*;
|
||||||
|
use web3_proxy::prelude::fdlimit;
|
||||||
|
use web3_proxy::prelude::tokio;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
|
@ -1,3 +1,5 @@
|
||||||
|
use web3_proxy::prelude::anyhow;
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
// get curve-api and rpc endpoints from cli flags
|
// get curve-api and rpc endpoints from cli flags
|
||||||
// do simple checks for proxy version, blockNum, a simple balance call
|
// do simple checks for proxy version, blockNum, a simple balance call
|
|
@ -1,18 +1,19 @@
|
||||||
// TODO: support websockets
|
// TODO: support websockets
|
||||||
|
|
||||||
use anyhow::Context;
|
|
||||||
use argh::FromArgs;
|
|
||||||
use chrono::Utc;
|
|
||||||
use ethers::types::U64;
|
|
||||||
use ethers::types::{Block, TxHash};
|
|
||||||
use reqwest::Client;
|
|
||||||
use serde::Deserialize;
|
|
||||||
use serde_json::json;
|
|
||||||
use std::sync::atomic::{AtomicU32, Ordering};
|
use std::sync::atomic::{AtomicU32, Ordering};
|
||||||
use tokio::time::sleep;
|
use tracing::{info, warn};
|
||||||
use tokio::time::Duration;
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
use tracing::info;
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
use tracing::warn;
|
use web3_proxy::prelude::chrono::Utc;
|
||||||
|
use web3_proxy::prelude::ethers::types::{Block, TxHash, U64};
|
||||||
|
use web3_proxy::prelude::fdlimit;
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
|
use web3_proxy::prelude::reqwest::Client;
|
||||||
|
use web3_proxy::prelude::serde::Deserialize;
|
||||||
|
use web3_proxy::prelude::serde_json::json;
|
||||||
|
use web3_proxy::prelude::tokio;
|
||||||
|
use web3_proxy::prelude::tokio::time::sleep;
|
||||||
|
use web3_proxy::prelude::tokio::time::Duration;
|
||||||
|
|
||||||
#[derive(Debug, FromArgs)]
|
#[derive(Debug, FromArgs)]
|
||||||
/// Command line interface for admins to interact with web3_proxy
|
/// Command line interface for admins to interact with web3_proxy
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod sub_commands;
|
||||||
|
pub mod test_utils;
|
|
@ -1,3 +1,5 @@
|
||||||
|
use web3_proxy::prelude::*;
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use argh::FromArgs;
|
use argh::FromArgs;
|
||||||
use ethers::types::U256;
|
use ethers::types::U256;
|
||||||
|
@ -14,12 +16,12 @@ use tokio::runtime;
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
use tracing_subscriber::{prelude::*, EnvFilter};
|
use tracing_subscriber::{prelude::*, EnvFilter};
|
||||||
use web3_proxy::pagerduty::panic_handler;
|
use web3_proxy::pagerduty::panic_handler;
|
||||||
use web3_proxy::sub_commands;
|
|
||||||
use web3_proxy::{
|
use web3_proxy::{
|
||||||
app::APP_USER_AGENT,
|
app::APP_USER_AGENT,
|
||||||
config::TopConfig,
|
config::TopConfig,
|
||||||
relational_db::{connect_db, get_migrated_db},
|
relational_db::{connect_db, get_migrated_db},
|
||||||
};
|
};
|
||||||
|
use web3_proxy_cli::sub_commands;
|
||||||
|
|
||||||
#[cfg(feature = "mimalloc")]
|
#[cfg(feature = "mimalloc")]
|
||||||
use mimalloc::MiMalloc;
|
use mimalloc::MiMalloc;
|
||||||
|
@ -177,9 +179,6 @@ fn main() -> anyhow::Result<()> {
|
||||||
|
|
||||||
let mut top_config: TopConfig = toml::from_str(&top_config)?;
|
let mut top_config: TopConfig = toml::from_str(&top_config)?;
|
||||||
|
|
||||||
// TODO: this doesn't seem to do anything
|
|
||||||
proctitle::set_title(format!("web3_proxy-{}", top_config.app.chain_id));
|
|
||||||
|
|
||||||
if cli_config.db_url.is_none() {
|
if cli_config.db_url.is_none() {
|
||||||
cli_config.db_url = top_config.app.db_url.clone();
|
cli_config.db_url = top_config.app.db_url.clone();
|
||||||
}
|
}
|
|
@ -1,12 +1,12 @@
|
||||||
use anyhow::Context;
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
use argh::FromArgs;
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
use entities::{admin, login, user};
|
use web3_proxy::prelude::entities::{admin, login, user};
|
||||||
use ethers::types::Address;
|
use web3_proxy::prelude::ethers::types::Address;
|
||||||
use migration::sea_orm::{
|
use web3_proxy::prelude::migration::sea_orm::{
|
||||||
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, ModelTrait, QueryFilter,
|
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, ModelTrait, QueryFilter,
|
||||||
};
|
};
|
||||||
use serde_json::json;
|
use web3_proxy::prelude::serde_json::json;
|
||||||
use tracing::{debug, info};
|
use web3_proxy::prelude::tracing::{debug, info};
|
||||||
|
|
||||||
/// change a user's admin status. eiter they are an admin, or they aren't
|
/// change a user's admin status. eiter they are an admin, or they aren't
|
||||||
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
|
@ -1,13 +1,13 @@
|
||||||
use anyhow::Context;
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
use argh::FromArgs;
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
use entities::user;
|
use web3_proxy::prelude::entities::user;
|
||||||
use ethers::types::Address;
|
use web3_proxy::prelude::ethers::types::Address;
|
||||||
use migration::sea_orm::{
|
use web3_proxy::prelude::migration::sea_orm::{
|
||||||
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
||||||
QueryFilter,
|
QueryFilter,
|
||||||
};
|
};
|
||||||
use serde_json::json;
|
use web3_proxy::prelude::serde_json::json;
|
||||||
use tracing::{debug, info};
|
use web3_proxy::prelude::tracing::{debug, info};
|
||||||
|
|
||||||
/// change a user's address.
|
/// change a user's address.
|
||||||
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
|
@ -1,12 +1,12 @@
|
||||||
use anyhow::Context;
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
use argh::FromArgs;
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
use entities::user_tier;
|
use web3_proxy::prelude::entities::user_tier;
|
||||||
use migration::sea_orm::{
|
use web3_proxy::prelude::migration::sea_orm::{
|
||||||
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
||||||
QueryFilter,
|
QueryFilter,
|
||||||
};
|
};
|
||||||
use serde_json::json;
|
use web3_proxy::prelude::serde_json::json;
|
||||||
use tracing::{debug, info};
|
use web3_proxy::prelude::tracing::{debug, info};
|
||||||
|
|
||||||
/// change a user's tier.
|
/// change a user's tier.
|
||||||
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
|
@ -1,13 +1,13 @@
|
||||||
use anyhow::Context;
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
use argh::FromArgs;
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
use entities::{user, user_tier};
|
use web3_proxy::prelude::entities::{user, user_tier};
|
||||||
use ethers::types::Address;
|
use web3_proxy::prelude::ethers::types::Address;
|
||||||
use migration::sea_orm::{
|
use web3_proxy::prelude::migration::sea_orm::{
|
||||||
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
||||||
QueryFilter,
|
QueryFilter,
|
||||||
};
|
};
|
||||||
use serde_json::json;
|
use web3_proxy::prelude::serde_json::json;
|
||||||
use tracing::{debug, info};
|
use web3_proxy::prelude::tracing::{debug, info};
|
||||||
|
|
||||||
/// change a user's tier.
|
/// change a user's tier.
|
||||||
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
|
@ -1,14 +1,14 @@
|
||||||
use crate::frontend::authorization::RpcSecretKey;
|
use web3_proxy::frontend::authorization::RpcSecretKey;
|
||||||
use anyhow::Context;
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
use argh::FromArgs;
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
use entities::{rpc_key, user, user_tier};
|
use web3_proxy::prelude::entities::{rpc_key, user, user_tier};
|
||||||
use migration::sea_orm::{
|
use web3_proxy::prelude::migration::sea_orm::{
|
||||||
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
||||||
QueryFilter,
|
QueryFilter,
|
||||||
};
|
};
|
||||||
use serde_json::json;
|
use web3_proxy::prelude::serde_json::json;
|
||||||
use tracing::{debug, info};
|
use web3_proxy::prelude::tracing::{debug, info};
|
||||||
use uuid::Uuid;
|
use web3_proxy::prelude::uuid::Uuid;
|
||||||
|
|
||||||
/// change a user's tier.
|
/// change a user's tier.
|
||||||
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
|
@ -1,7 +1,9 @@
|
||||||
use crate::config::TopConfig;
|
|
||||||
use argh::FromArgs;
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use tracing::{error, info, warn};
|
use web3_proxy::config::TopConfig;
|
||||||
|
use web3_proxy::prelude::anyhow;
|
||||||
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
|
use web3_proxy::prelude::toml;
|
||||||
|
use web3_proxy::prelude::tracing::{error, info, warn};
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
||||||
/// Check the config for any problems.
|
/// Check the config for any problems.
|
||||||
|
@ -93,6 +95,7 @@ impl CheckConfigSubCommand {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use web3_proxy::prelude::tokio;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use argh::FromArgs;
|
|
||||||
use entities::user;
|
|
||||||
use migration::sea_orm::{self, EntityTrait, PaginatorTrait};
|
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
use web3_proxy::prelude::anyhow;
|
||||||
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
|
use web3_proxy::prelude::entities::user;
|
||||||
|
use web3_proxy::prelude::migration::sea_orm::{self, EntityTrait, PaginatorTrait};
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
||||||
/// Create a new user and api key
|
/// Create a new user and api key
|
|
@ -1,12 +1,14 @@
|
||||||
use crate::frontend::authorization::RpcSecretKey;
|
use web3_proxy::frontend::authorization::RpcSecretKey;
|
||||||
use anyhow::Context;
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
use argh::FromArgs;
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
use entities::{rpc_key, user};
|
use web3_proxy::prelude::entities::{rpc_key, user};
|
||||||
use ethers::prelude::Address;
|
use web3_proxy::prelude::ethers::prelude::Address;
|
||||||
use migration::sea_orm::{self, ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter};
|
use web3_proxy::prelude::migration::sea_orm::{
|
||||||
use tracing::info;
|
self, ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter,
|
||||||
use ulid::Ulid;
|
};
|
||||||
use uuid::Uuid;
|
use web3_proxy::prelude::tracing::info;
|
||||||
|
use web3_proxy::prelude::ulid::Ulid;
|
||||||
|
use web3_proxy::prelude::uuid::Uuid;
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
||||||
/// Create a new user and api key
|
/// Create a new user and api key
|
|
@ -1,12 +1,12 @@
|
||||||
use crate::frontend::authorization::RpcSecretKey;
|
|
||||||
use anyhow::Context;
|
|
||||||
use argh::FromArgs;
|
|
||||||
use entities::{rpc_key, user};
|
|
||||||
use ethers::prelude::Address;
|
|
||||||
use migration::sea_orm::{self, ActiveModelTrait, TransactionTrait};
|
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
use ulid::Ulid;
|
use web3_proxy::frontend::authorization::RpcSecretKey;
|
||||||
use uuid::Uuid;
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
|
use web3_proxy::prelude::entities::{rpc_key, user};
|
||||||
|
use web3_proxy::prelude::ethers::prelude::Address;
|
||||||
|
use web3_proxy::prelude::migration::sea_orm::{self, ActiveModelTrait, TransactionTrait};
|
||||||
|
use web3_proxy::prelude::ulid::Ulid;
|
||||||
|
use web3_proxy::prelude::uuid::Uuid;
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
||||||
/// Create a new user and api key
|
/// Create a new user and api key
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::relational_db::{drop_migration_lock, migrate_db};
|
use web3_proxy::prelude::anyhow;
|
||||||
use argh::FromArgs;
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
use migration::sea_orm::DatabaseConnection;
|
use web3_proxy::prelude::migration::sea_orm::DatabaseConnection;
|
||||||
|
use web3_proxy::relational_db::{drop_migration_lock, migrate_db};
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
||||||
/// In case of emergency, break glass.
|
/// In case of emergency, break glass.
|
|
@ -1,4 +1,4 @@
|
||||||
use argh::FromArgs;
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Debug)]
|
#[derive(FromArgs, PartialEq, Debug)]
|
||||||
/// An example subcommand. Copy paste this into a new file.
|
/// An example subcommand. Copy paste this into a new file.
|
|
@ -2,18 +2,18 @@
|
||||||
// that's easier than refactoring right now.
|
// that's easier than refactoring right now.
|
||||||
// it could be cleaned up, but this is a script that runs once so isn't worth spending tons of time on.
|
// it could be cleaned up, but this is a script that runs once so isn't worth spending tons of time on.
|
||||||
|
|
||||||
use crate::balance::Balance;
|
use web3_proxy::balance::Balance;
|
||||||
use anyhow::Context;
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
use argh::FromArgs;
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
use entities::{admin_increase_balance_receipt, user, user_tier};
|
use web3_proxy::prelude::entities::{admin_increase_balance_receipt, user, user_tier};
|
||||||
use ethers::types::Address;
|
use web3_proxy::prelude::ethers::types::Address;
|
||||||
use migration::sea_orm::{
|
use web3_proxy::prelude::migration::sea_orm::{
|
||||||
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
||||||
QueryFilter, TransactionTrait,
|
QueryFilter, TransactionTrait,
|
||||||
};
|
};
|
||||||
use rust_decimal::Decimal;
|
use web3_proxy::prelude::rust_decimal::Decimal;
|
||||||
use serde_json::json;
|
use web3_proxy::prelude::serde_json::json;
|
||||||
use tracing::info;
|
use web3_proxy::prelude::tracing::info;
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Debug)]
|
#[derive(FromArgs, PartialEq, Debug)]
|
||||||
/// Grant credits to all the users in a tier (and change their tier to premium).
|
/// Grant credits to all the users in a tier (and change their tier to premium).
|
|
@ -2,16 +2,16 @@
|
||||||
// that's easier than refactoring right now.
|
// that's easier than refactoring right now.
|
||||||
// it could be cleaned up, but this is a script that runs once so isn't worth spending tons of time on.
|
// it could be cleaned up, but this is a script that runs once so isn't worth spending tons of time on.
|
||||||
|
|
||||||
use anyhow::Context;
|
use tracing::info;
|
||||||
use argh::FromArgs;
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
use entities::{admin_increase_balance_receipt, user, user_tier};
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
use futures::TryStreamExt;
|
use web3_proxy::prelude::entities::{admin_increase_balance_receipt, user, user_tier};
|
||||||
use migration::sea_orm::{
|
use web3_proxy::prelude::futures::TryStreamExt;
|
||||||
|
use web3_proxy::prelude::migration::sea_orm::{
|
||||||
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
||||||
PaginatorTrait, QueryFilter, QueryOrder, TransactionTrait,
|
PaginatorTrait, QueryFilter, QueryOrder, TransactionTrait,
|
||||||
};
|
};
|
||||||
use rust_decimal::Decimal;
|
use web3_proxy::prelude::rust_decimal::Decimal;
|
||||||
use tracing::info;
|
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Debug)]
|
#[derive(FromArgs, PartialEq, Debug)]
|
||||||
/// Grant credits to all the users in a tier (and change their tier to premium).
|
/// Grant credits to all the users in a tier (and change their tier to premium).
|
|
@ -1,26 +1,28 @@
|
||||||
use crate::app::BILLING_PERIOD_SECONDS;
|
|
||||||
use crate::config::TopConfig;
|
|
||||||
use crate::frontend::authorization::{Authorization, RequestMetadata, RpcSecretKey};
|
|
||||||
use crate::rpcs::one::Web3Rpc;
|
|
||||||
use crate::stats::StatBuffer;
|
|
||||||
use anyhow::Context;
|
|
||||||
use argh::FromArgs;
|
|
||||||
use entities::{rpc_accounting, rpc_key};
|
|
||||||
use futures::stream::FuturesUnordered;
|
|
||||||
use futures::StreamExt;
|
|
||||||
use migration::sea_orm::QueryOrder;
|
|
||||||
use migration::sea_orm::{
|
|
||||||
ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter, QuerySelect, UpdateResult,
|
|
||||||
};
|
|
||||||
use migration::{Expr, Value};
|
|
||||||
use moka::future::Cache;
|
|
||||||
use parking_lot::Mutex;
|
|
||||||
use std::num::NonZeroU64;
|
use std::num::NonZeroU64;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::{broadcast, mpsc};
|
|
||||||
use tokio::time::Instant;
|
|
||||||
use tracing::{error, info};
|
use tracing::{error, info};
|
||||||
use ulid::Ulid;
|
use web3_proxy::app::BILLING_PERIOD_SECONDS;
|
||||||
|
use web3_proxy::config::TopConfig;
|
||||||
|
use web3_proxy::frontend::authorization::{Authorization, RequestMetadata, RpcSecretKey};
|
||||||
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
|
use web3_proxy::prelude::chrono;
|
||||||
|
use web3_proxy::prelude::entities::{rpc_accounting, rpc_key};
|
||||||
|
use web3_proxy::prelude::futures::stream::FuturesUnordered;
|
||||||
|
use web3_proxy::prelude::futures::StreamExt;
|
||||||
|
use web3_proxy::prelude::influxdb2;
|
||||||
|
use web3_proxy::prelude::migration::sea_orm::{
|
||||||
|
ColumnTrait, DatabaseConnection, EntityTrait, QueryFilter, QueryOrder, QuerySelect,
|
||||||
|
UpdateResult,
|
||||||
|
};
|
||||||
|
use web3_proxy::prelude::migration::{Expr, Value};
|
||||||
|
use web3_proxy::prelude::moka::future::Cache;
|
||||||
|
use web3_proxy::prelude::parking_lot::Mutex;
|
||||||
|
use web3_proxy::prelude::tokio::sync::{broadcast, mpsc};
|
||||||
|
use web3_proxy::prelude::tokio::time::Instant;
|
||||||
|
use web3_proxy::prelude::ulid::Ulid;
|
||||||
|
use web3_proxy::rpcs::one::Web3Rpc;
|
||||||
|
use web3_proxy::stats::StatBuffer;
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
||||||
/// Migrate towards influxdb and rpc_accounting_v2 from rpc_accounting
|
/// Migrate towards influxdb and rpc_accounting_v2 from rpc_accounting
|
|
@ -1,11 +1,15 @@
|
||||||
use crate::{
|
use tracing::{error, info};
|
||||||
|
use web3_proxy::prelude::anyhow;
|
||||||
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
|
use web3_proxy::prelude::pagerduty_rs;
|
||||||
|
use web3_proxy::prelude::pagerduty_rs::{
|
||||||
|
eventsv2async::EventsV2 as PagerdutyAsyncEventsV2, types::Event,
|
||||||
|
};
|
||||||
|
use web3_proxy::prelude::serde_json::json;
|
||||||
|
use web3_proxy::{
|
||||||
config::TopConfig,
|
config::TopConfig,
|
||||||
pagerduty::{pagerduty_alert, pagerduty_alert_for_config},
|
pagerduty::{pagerduty_alert, pagerduty_alert_for_config},
|
||||||
};
|
};
|
||||||
use argh::FromArgs;
|
|
||||||
use pagerduty_rs::{eventsv2async::EventsV2 as PagerdutyAsyncEventsV2, types::Event};
|
|
||||||
use serde_json::json;
|
|
||||||
use tracing::{error, info};
|
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
||||||
/// Quickly create a pagerduty alert
|
/// Quickly create a pagerduty alert
|
|
@ -1,8 +1,11 @@
|
||||||
use argh::FromArgs;
|
|
||||||
use ethers::types::U64;
|
|
||||||
use ordered_float::OrderedFloat;
|
|
||||||
use prettytable::{row, Table};
|
use prettytable::{row, Table};
|
||||||
use std::{cmp::Reverse, str::FromStr};
|
use std::{cmp::Reverse, str::FromStr};
|
||||||
|
use web3_proxy::prelude::anyhow;
|
||||||
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
|
use web3_proxy::prelude::ethers::types::U64;
|
||||||
|
use web3_proxy::prelude::ordered_float::OrderedFloat;
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
|
use web3_proxy::prelude::serde_json;
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Debug)]
|
#[derive(FromArgs, PartialEq, Debug)]
|
||||||
/// show what nodes are used most often
|
/// show what nodes are used most often
|
|
@ -1,22 +1,25 @@
|
||||||
use crate::app::{flatten_handle, flatten_handles, Web3ProxyApp};
|
|
||||||
use crate::compute_units::default_usd_per_cu;
|
|
||||||
use crate::config::TopConfig;
|
|
||||||
use crate::globals::global_db_conn;
|
|
||||||
use crate::stats::FlushedStats;
|
|
||||||
use crate::{frontend, prometheus};
|
|
||||||
use argh::FromArgs;
|
|
||||||
use futures::StreamExt;
|
|
||||||
use num::Zero;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::atomic::AtomicU16;
|
use std::sync::atomic::AtomicU16;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::{fs, thread};
|
use std::{fs, thread};
|
||||||
use tokio::signal::unix::SignalKind;
|
|
||||||
use tokio::sync::{broadcast, mpsc, oneshot};
|
|
||||||
use tokio::time::{sleep_until, Instant};
|
|
||||||
use tokio::{select, signal};
|
|
||||||
use tracing::{error, info, trace, warn};
|
use tracing::{error, info, trace, warn};
|
||||||
|
use web3_proxy::app::{flatten_handle, flatten_handles, Web3ProxyApp};
|
||||||
|
use web3_proxy::compute_units::default_usd_per_cu;
|
||||||
|
use web3_proxy::config::TopConfig;
|
||||||
|
use web3_proxy::globals::global_db_conn;
|
||||||
|
use web3_proxy::prelude::anyhow;
|
||||||
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
|
use web3_proxy::prelude::futures::StreamExt;
|
||||||
|
use web3_proxy::prelude::num::Zero;
|
||||||
|
use web3_proxy::prelude::tokio;
|
||||||
|
use web3_proxy::prelude::tokio::signal::unix::SignalKind;
|
||||||
|
use web3_proxy::prelude::tokio::sync::{broadcast, mpsc, oneshot};
|
||||||
|
use web3_proxy::prelude::tokio::time::{sleep_until, Instant};
|
||||||
|
use web3_proxy::prelude::tokio::{select, signal};
|
||||||
|
use web3_proxy::prelude::toml;
|
||||||
|
use web3_proxy::stats::FlushedStats;
|
||||||
|
use web3_proxy::{frontend, prometheus};
|
||||||
|
|
||||||
/// start the main proxy daemon
|
/// start the main proxy daemon
|
||||||
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
|
@ -1,9 +1,12 @@
|
||||||
// select all requests for a timeline. sum bandwidth and request count. give `cost / byte` and `cost / request`.
|
// select all requests for a timeline. sum bandwidth and request count. give `cost / byte` and `cost / request`.
|
||||||
use anyhow::Context;
|
use serde::Serialize;
|
||||||
use argh::FromArgs;
|
use serde_json::json;
|
||||||
use entities::{rpc_accounting, rpc_key, user};
|
use tracing::info;
|
||||||
use ethers::types::Address;
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
use migration::{
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
|
use web3_proxy::prelude::entities::{rpc_accounting, rpc_key, user};
|
||||||
|
use web3_proxy::prelude::ethers::types::Address;
|
||||||
|
use web3_proxy::prelude::migration::{
|
||||||
sea_orm::{
|
sea_orm::{
|
||||||
self,
|
self,
|
||||||
prelude::{DateTimeUtc, Decimal},
|
prelude::{DateTimeUtc, Decimal},
|
||||||
|
@ -11,9 +14,6 @@ use migration::{
|
||||||
},
|
},
|
||||||
Condition,
|
Condition,
|
||||||
};
|
};
|
||||||
use serde::Serialize;
|
|
||||||
use serde_json::json;
|
|
||||||
use tracing::info;
|
|
||||||
|
|
||||||
/// count requests
|
/// count requests
|
||||||
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
|
@ -1,16 +1,19 @@
|
||||||
use crate::{config::TopConfig, frontend::authorization::RpcSecretKey, relational_db::connect_db};
|
use std::num::NonZeroU64;
|
||||||
use anyhow::Context;
|
use tracing::info;
|
||||||
use argh::FromArgs;
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
use entities::rpc_key;
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
use futures::TryStreamExt;
|
use web3_proxy::prelude::entities::rpc_key;
|
||||||
use migration::sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
|
use web3_proxy::prelude::futures::TryStreamExt;
|
||||||
use rdkafka::{
|
use web3_proxy::prelude::migration::sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
|
||||||
|
use web3_proxy::prelude::rdkafka::{
|
||||||
consumer::{Consumer, StreamConsumer},
|
consumer::{Consumer, StreamConsumer},
|
||||||
ClientConfig, Message,
|
ClientConfig, Message,
|
||||||
};
|
};
|
||||||
use std::num::NonZeroU64;
|
use web3_proxy::prelude::rmp_serde;
|
||||||
use tracing::info;
|
use web3_proxy::prelude::uuid::Uuid;
|
||||||
use uuid::Uuid;
|
use web3_proxy::{
|
||||||
|
config::TopConfig, frontend::authorization::RpcSecretKey, relational_db::connect_db,
|
||||||
|
};
|
||||||
|
|
||||||
/// Second subcommand.
|
/// Second subcommand.
|
||||||
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
|
@ -1,13 +1,15 @@
|
||||||
use crate::jsonrpc::JsonRpcErrorData;
|
|
||||||
use anyhow::{anyhow, Context};
|
|
||||||
use chrono::{DateTime, Utc};
|
|
||||||
use ethers::types::{Block, TxHash, H256};
|
|
||||||
use futures::{stream::FuturesUnordered, StreamExt};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use serde_json::json;
|
|
||||||
use tracing::{debug, warn};
|
|
||||||
|
|
||||||
use super::{SentrydErrorBuilder, SentrydResult};
|
use super::{SentrydErrorBuilder, SentrydResult};
|
||||||
|
use tracing::{debug, warn};
|
||||||
|
use web3_proxy::jsonrpc::JsonRpcErrorData;
|
||||||
|
use web3_proxy::prelude::anyhow;
|
||||||
|
use web3_proxy::prelude::anyhow::{anyhow, Context};
|
||||||
|
use web3_proxy::prelude::chrono::{DateTime, Utc};
|
||||||
|
use web3_proxy::prelude::ethers::types::{Block, TxHash, H256};
|
||||||
|
use web3_proxy::prelude::futures::{stream::FuturesUnordered, StreamExt};
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
|
use web3_proxy::prelude::serde::{Deserialize, Serialize};
|
||||||
|
use web3_proxy::prelude::serde_json::json;
|
||||||
|
use web3_proxy::prelude::tokio;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
struct JsonRpcResponse<V> {
|
struct JsonRpcResponse<V> {
|
|
@ -1,19 +1,24 @@
|
||||||
mod compare;
|
mod compare;
|
||||||
mod simple;
|
mod simple;
|
||||||
|
|
||||||
use crate::{config::TopConfig, pagerduty::pagerduty_alert};
|
use std::time::Duration;
|
||||||
use anyhow::Context;
|
use tracing::{debug, error, info, warn, Level};
|
||||||
use argh::FromArgs;
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
use futures::{
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
|
use web3_proxy::prelude::futures::{
|
||||||
stream::{FuturesUnordered, StreamExt},
|
stream::{FuturesUnordered, StreamExt},
|
||||||
Future,
|
Future,
|
||||||
};
|
};
|
||||||
use pagerduty_rs::{eventsv2async::EventsV2 as PagerdutyAsyncEventsV2, types::Event};
|
use web3_proxy::prelude::pagerduty_rs;
|
||||||
use serde_json::json;
|
use web3_proxy::prelude::pagerduty_rs::{
|
||||||
use std::time::Duration;
|
eventsv2async::EventsV2 as PagerdutyAsyncEventsV2, types::Event,
|
||||||
use tokio::sync::mpsc;
|
};
|
||||||
use tokio::time::{interval, MissedTickBehavior};
|
use web3_proxy::prelude::serde_json;
|
||||||
use tracing::{debug, error, info, warn, Level};
|
use web3_proxy::prelude::serde_json::json;
|
||||||
|
use web3_proxy::prelude::tokio;
|
||||||
|
use web3_proxy::prelude::tokio::sync::mpsc;
|
||||||
|
use web3_proxy::prelude::tokio::time::{interval, MissedTickBehavior};
|
||||||
|
use web3_proxy::{config::TopConfig, pagerduty::pagerduty_alert};
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
#[derive(FromArgs, PartialEq, Debug, Eq)]
|
||||||
/// Loop healthchecks and send pager duty alerts if any fail
|
/// Loop healthchecks and send pager duty alerts if any fail
|
|
@ -1,9 +1,10 @@
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use super::{SentrydErrorBuilder, SentrydResult};
|
use super::{SentrydErrorBuilder, SentrydResult};
|
||||||
use anyhow::Context;
|
|
||||||
use tokio::time::Instant;
|
|
||||||
use tracing::{debug, trace};
|
use tracing::{debug, trace};
|
||||||
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
|
use web3_proxy::prelude::tokio::time::Instant;
|
||||||
|
|
||||||
/// GET the url and return an error if it wasn't a success
|
/// GET the url and return an error if it wasn't a success
|
||||||
pub async fn main(
|
pub async fn main(
|
|
@ -1,14 +1,14 @@
|
||||||
use crate::frontend::authorization::RpcSecretKey;
|
use tracing::{debug, info};
|
||||||
use anyhow::Context;
|
use web3_proxy::frontend::authorization::RpcSecretKey;
|
||||||
use argh::FromArgs;
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
use entities::{rpc_key, user};
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
use ethers::types::Address;
|
use web3_proxy::prelude::entities::{rpc_key, user};
|
||||||
use migration::sea_orm::{
|
use web3_proxy::prelude::ethers::types::Address;
|
||||||
|
use web3_proxy::prelude::sea_orm::{
|
||||||
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
||||||
QueryFilter,
|
QueryFilter,
|
||||||
};
|
};
|
||||||
use sea_orm::prelude::Uuid;
|
use web3_proxy::prelude::uuid::Uuid;
|
||||||
use tracing::{debug, info};
|
|
||||||
|
|
||||||
/// change a key's owner.
|
/// change a key's owner.
|
||||||
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
|
@ -5,6 +5,8 @@ use std::fs::{self, create_dir_all};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
|
use web3_proxy::prelude::*;
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
||||||
/// Export users from the database.
|
/// Export users from the database.
|
||||||
#[argh(subcommand, name = "user_export")]
|
#[argh(subcommand, name = "user_export")]
|
|
@ -1,16 +1,16 @@
|
||||||
use anyhow::Context;
|
|
||||||
use argh::FromArgs;
|
|
||||||
use entities::{rpc_key, user};
|
|
||||||
use glob::glob;
|
|
||||||
use hashbrown::HashMap;
|
|
||||||
use migration::sea_orm::ActiveValue::NotSet;
|
|
||||||
use migration::sea_orm::{
|
|
||||||
ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel, QueryFilter,
|
|
||||||
Set,
|
|
||||||
};
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::{fs::File, io::BufReader};
|
use std::{fs::File, io::BufReader};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
use web3_proxy::prelude::anyhow::{self, Context};
|
||||||
|
use web3_proxy::prelude::argh::{self, FromArgs};
|
||||||
|
use web3_proxy::prelude::entities::{rpc_key, user};
|
||||||
|
use web3_proxy::prelude::glob::glob;
|
||||||
|
use web3_proxy::prelude::hashbrown::HashMap;
|
||||||
|
use web3_proxy::prelude::migration::sea_orm::ActiveValue::NotSet;
|
||||||
|
use web3_proxy::prelude::migration::sea_orm::{
|
||||||
|
ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel, QueryFilter,
|
||||||
|
Set,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
||||||
/// Import users from another database.
|
/// Import users from another database.
|
|
@ -1,6 +1,7 @@
|
||||||
use super::TestApp;
|
use super::TestApp;
|
||||||
use tracing::trace;
|
use tracing::trace;
|
||||||
use web3_proxy::frontend::users::authentication::LoginPostResponse;
|
use web3_proxy::frontend::users::authentication::LoginPostResponse;
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
|
|
||||||
/// Helper function to increase the balance of a user, from an admin
|
/// Helper function to increase the balance of a user, from an admin
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
|
@ -1,9 +1,10 @@
|
||||||
use super::TestApp;
|
use super::TestApp;
|
||||||
use ethers::prelude::{LocalWallet, Signer};
|
|
||||||
use migration::sea_orm::prelude::Decimal;
|
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
use web3_proxy::frontend::admin::AdminIncreaseBalancePost;
|
use web3_proxy::frontend::admin::AdminIncreaseBalancePost;
|
||||||
use web3_proxy::frontend::users::authentication::LoginPostResponse;
|
use web3_proxy::frontend::users::authentication::LoginPostResponse;
|
||||||
|
use web3_proxy::prelude::ethers::prelude::{LocalWallet, Signer};
|
||||||
|
use web3_proxy::prelude::migration::sea_orm::prelude::Decimal;
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
|
|
||||||
/// Helper function to increase the balance of a user, from an admin
|
/// Helper function to increase the balance of a user, from an admin
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
|
@ -1,11 +1,4 @@
|
||||||
use super::{anvil::TestAnvil, mysql::TestMysql};
|
use crate::sub_commands::ProxydSubCommand;
|
||||||
use crate::common::influx::TestInflux;
|
|
||||||
use ethers::{
|
|
||||||
prelude::{Http, Provider},
|
|
||||||
types::Address,
|
|
||||||
};
|
|
||||||
use hashbrown::HashMap;
|
|
||||||
use serde_json::json;
|
|
||||||
use std::{
|
use std::{
|
||||||
env,
|
env,
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
|
@ -13,7 +6,15 @@ use std::{
|
||||||
thread,
|
thread,
|
||||||
};
|
};
|
||||||
use std::{sync::Arc, time::Duration};
|
use std::{sync::Arc, time::Duration};
|
||||||
use tokio::{
|
use tracing::info;
|
||||||
|
use web3_proxy::prelude::anyhow;
|
||||||
|
use web3_proxy::prelude::ethers::{
|
||||||
|
prelude::{Http, Provider},
|
||||||
|
types::Address,
|
||||||
|
};
|
||||||
|
use web3_proxy::prelude::hashbrown::HashMap;
|
||||||
|
use web3_proxy::prelude::serde_json::json;
|
||||||
|
use web3_proxy::prelude::tokio::{
|
||||||
runtime::Builder,
|
runtime::Builder,
|
||||||
sync::{
|
sync::{
|
||||||
broadcast::{self, error::SendError},
|
broadcast::{self, error::SendError},
|
||||||
|
@ -21,11 +22,10 @@ use tokio::{
|
||||||
},
|
},
|
||||||
time::{sleep, Instant},
|
time::{sleep, Instant},
|
||||||
};
|
};
|
||||||
use tracing::info;
|
use web3_proxy::test_utils::{TestAnvil, TestInflux, TestMysql};
|
||||||
use web3_proxy::{
|
use web3_proxy::{
|
||||||
config::{AppConfig, TopConfig, Web3RpcConfig},
|
config::{AppConfig, TopConfig, Web3RpcConfig},
|
||||||
stats::FlushedStats,
|
stats::FlushedStats,
|
||||||
sub_commands::ProxydSubCommand,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct TestApp {
|
pub struct TestApp {
|
||||||
|
@ -44,7 +44,6 @@ pub struct TestApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestApp {
|
impl TestApp {
|
||||||
#[allow(unused)]
|
|
||||||
pub async fn spawn(
|
pub async fn spawn(
|
||||||
anvil: &TestAnvil,
|
anvil: &TestAnvil,
|
||||||
db: Option<&TestMysql>,
|
db: Option<&TestMysql>,
|
||||||
|
@ -171,7 +170,6 @@ impl TestApp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub async fn flush_stats(&self) -> anyhow::Result<FlushedStats> {
|
pub async fn flush_stats(&self) -> anyhow::Result<FlushedStats> {
|
||||||
let (tx, rx) = oneshot::channel();
|
let (tx, rx) = oneshot::channel();
|
||||||
|
|
||||||
|
@ -186,12 +184,11 @@ impl TestApp {
|
||||||
self.shutdown_sender.send(())
|
self.shutdown_sender.send(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
|
||||||
pub fn wait_for_stop(mut self) {
|
pub fn wait_for_stop(mut self) {
|
||||||
let _ = self.stop();
|
let _ = self.stop();
|
||||||
|
|
||||||
if let Some(handle) = self.proxy_handle.take() {
|
if let Some(handle) = self.proxy_handle.take() {
|
||||||
handle.join().unwrap();
|
handle.join().unwrap().unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,12 +1,11 @@
|
||||||
use super::TestApp;
|
use super::{TestApp, TestMysql};
|
||||||
use ethers::prelude::{LocalWallet, Signer};
|
use crate::sub_commands::ChangeAdminStatusSubCommand;
|
||||||
use ethers::types::Signature;
|
|
||||||
use http::StatusCode;
|
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
use web3_proxy::frontend::users::authentication::{LoginPostResponse, PostLogin};
|
use web3_proxy::frontend::users::authentication::{LoginPostResponse, PostLogin};
|
||||||
use web3_proxy::sub_commands::ChangeAdminStatusSubCommand;
|
use web3_proxy::prelude::ethers::prelude::{LocalWallet, Signer};
|
||||||
|
use web3_proxy::prelude::ethers::types::Signature;
|
||||||
use super::mysql::TestMysql;
|
use web3_proxy::prelude::http::StatusCode;
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
|
|
||||||
/// Helper function to create admin
|
/// Helper function to create admin
|
||||||
|
|
||||||
|
@ -86,9 +85,13 @@ pub async fn create_user_as_admin(
|
||||||
x.proxy_provider.url(),
|
x.proxy_provider.url(),
|
||||||
admin_wallet.address()
|
admin_wallet.address()
|
||||||
);
|
);
|
||||||
let admin_login_message = r.get(admin_login_get_url).send().await.unwrap()
|
let admin_login_message = r
|
||||||
.error_for_status()
|
.get(admin_login_get_url)
|
||||||
.unwrap();
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.error_for_status()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(admin_login_message.status(), StatusCode::OK);
|
assert_eq!(admin_login_message.status(), StatusCode::OK);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use ulid::Ulid;
|
use web3_proxy::prelude::ulid::Ulid;
|
||||||
use url::Url;
|
use web3_proxy::prelude::url::Url;
|
||||||
use web3_proxy::rpcs::provider::EthersHttpProvider;
|
use web3_proxy::rpcs::provider::EthersHttpProvider;
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
|
@ -1,15 +1,16 @@
|
||||||
use super::TestApp;
|
use super::TestApp;
|
||||||
use entities::{user, user_tier};
|
|
||||||
use ethers::prelude::{LocalWallet, Signer};
|
|
||||||
use ethers::types::Signature;
|
|
||||||
use http::StatusCode;
|
|
||||||
use migration::sea_orm::{
|
|
||||||
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
|
||||||
QueryFilter,
|
|
||||||
};
|
|
||||||
use tracing::{info, trace};
|
use tracing::{info, trace};
|
||||||
use web3_proxy::errors::Web3ProxyResult;
|
use web3_proxy::errors::Web3ProxyResult;
|
||||||
use web3_proxy::frontend::users::authentication::{LoginPostResponse, PostLogin};
|
use web3_proxy::frontend::users::authentication::{LoginPostResponse, PostLogin};
|
||||||
|
use web3_proxy::prelude::entities::{user, user_tier};
|
||||||
|
use web3_proxy::prelude::ethers::prelude::{LocalWallet, Signer};
|
||||||
|
use web3_proxy::prelude::ethers::types::Signature;
|
||||||
|
use web3_proxy::prelude::http::StatusCode;
|
||||||
|
use web3_proxy::prelude::migration::sea_orm::{
|
||||||
|
self, ActiveModelTrait, ColumnTrait, DatabaseConnection, EntityTrait, IntoActiveModel,
|
||||||
|
QueryFilter,
|
||||||
|
};
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
|
|
||||||
/// Helper function to create an "ordinary" user
|
/// Helper function to create an "ordinary" user
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
|
@ -1,18 +1,15 @@
|
||||||
pub mod admin_deposits;
|
pub mod admin_deposits;
|
||||||
pub mod admin_increases_balance;
|
pub mod admin_increases_balance;
|
||||||
pub mod anvil;
|
|
||||||
pub mod app;
|
pub mod app;
|
||||||
pub mod create_admin;
|
pub mod create_admin;
|
||||||
pub mod create_provider_with_rpc_key;
|
pub mod create_provider_with_rpc_key;
|
||||||
pub mod create_user;
|
pub mod create_user;
|
||||||
pub mod influx;
|
|
||||||
pub mod mysql;
|
|
||||||
pub mod referral;
|
pub mod referral;
|
||||||
pub mod rpc_key;
|
pub mod rpc_key;
|
||||||
pub mod stats_accounting;
|
pub mod stats_accounting;
|
||||||
pub mod user_balance;
|
pub mod user_balance;
|
||||||
|
|
||||||
pub use self::anvil::TestAnvil;
|
|
||||||
pub use self::app::TestApp;
|
pub use self::app::TestApp;
|
||||||
pub use self::influx::TestInflux;
|
pub use web3_proxy::test_utils::anvil::TestAnvil;
|
||||||
pub use self::mysql::TestMysql;
|
pub use web3_proxy::test_utils::influx::TestInflux;
|
||||||
|
pub use web3_proxy::test_utils::mysql::TestMysql;
|
|
@ -4,10 +4,10 @@
|
||||||
/// - getting code for referral (shared and used)
|
/// - getting code for referral (shared and used)
|
||||||
use super::TestApp;
|
use super::TestApp;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
use ulid::Ulid;
|
|
||||||
use web3_proxy::frontend::users::authentication::LoginPostResponse;
|
use web3_proxy::frontend::users::authentication::LoginPostResponse;
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
use serde::{Deserialize, Serialize};
|
use web3_proxy::prelude::serde::{Deserialize, Serialize};
|
||||||
|
use web3_proxy::prelude::ulid::Ulid;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct UserSharedReferralInfo {
|
pub struct UserSharedReferralInfo {
|
|
@ -1,8 +1,9 @@
|
||||||
use super::TestApp;
|
use super::TestApp;
|
||||||
use serde::Deserialize;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
use ulid::Ulid;
|
use web3_proxy::prelude::reqwest;
|
||||||
|
use web3_proxy::prelude::serde::Deserialize;
|
||||||
|
use web3_proxy::prelude::ulid::Ulid;
|
||||||
use web3_proxy::{
|
use web3_proxy::{
|
||||||
errors::Web3ProxyResult,
|
errors::Web3ProxyResult,
|
||||||
frontend::users::authentication::LoginPostResponse,
|
frontend::users::authentication::LoginPostResponse,
|
|
@ -1,8 +1,9 @@
|
||||||
use super::TestApp;
|
use super::TestApp;
|
||||||
use serde_json::json;
|
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
use tracing::{info, trace};
|
use tracing::{info, trace};
|
||||||
use web3_proxy::frontend::users::authentication::LoginPostResponse;
|
use web3_proxy::frontend::users::authentication::LoginPostResponse;
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
|
use web3_proxy::prelude::serde_json::json;
|
||||||
|
|
||||||
/// Get the user stats accounting
|
/// Get the user stats accounting
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use super::TestApp;
|
use super::TestApp;
|
||||||
use serde_json::json;
|
|
||||||
use tracing::{info, trace};
|
use tracing::{info, trace};
|
||||||
use web3_proxy::balance::Balance;
|
use web3_proxy::balance::Balance;
|
||||||
use web3_proxy::frontend::users::authentication::LoginPostResponse;
|
use web3_proxy::frontend::users::authentication::LoginPostResponse;
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
|
use web3_proxy::prelude::serde_json::json;
|
||||||
|
|
||||||
/// Helper function to get the user's balance
|
/// Helper function to get the user's balance
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
|
@ -1,17 +1,15 @@
|
||||||
mod common;
|
|
||||||
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::common::admin_increases_balance::admin_increase_balance;
|
|
||||||
use crate::common::anvil::TestAnvil;
|
|
||||||
use crate::common::create_admin::create_user_as_admin;
|
|
||||||
use crate::common::create_user::create_user;
|
|
||||||
use crate::common::mysql::TestMysql;
|
|
||||||
use crate::common::user_balance::user_get_balance;
|
|
||||||
use crate::common::TestApp;
|
|
||||||
use migration::sea_orm::prelude::Decimal;
|
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
use web3_proxy::prelude::migration::sea_orm::prelude::Decimal;
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
|
use web3_proxy::test_utils::mysql::TestMysql;
|
||||||
|
use web3_proxy::test_utils::TestAnvil;
|
||||||
|
use web3_proxy_cli::test_utils::admin_increases_balance::admin_increase_balance;
|
||||||
|
use web3_proxy_cli::test_utils::create_admin::create_user_as_admin;
|
||||||
|
use web3_proxy_cli::test_utils::create_user::create_user;
|
||||||
|
use web3_proxy_cli::test_utils::user_balance::user_get_balance;
|
||||||
|
use web3_proxy_cli::test_utils::TestApp;
|
||||||
|
|
||||||
// #[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
// #[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
||||||
#[ignore = "under construction"]
|
#[ignore = "under construction"]
|
|
@ -1,22 +1,24 @@
|
||||||
mod common;
|
|
||||||
|
|
||||||
use crate::common::create_provider_with_rpc_key::create_provider_for_user;
|
|
||||||
use crate::common::influx::TestInflux;
|
|
||||||
use crate::common::rpc_key::user_get_first_rpc_key;
|
|
||||||
use crate::common::stats_accounting::{user_get_influx_stats_aggregated, user_get_mysql_stats};
|
|
||||||
use crate::common::user_balance::user_get_balance;
|
|
||||||
use crate::common::{
|
|
||||||
admin_increases_balance::admin_increase_balance, anvil::TestAnvil,
|
|
||||||
create_admin::create_user_as_admin, create_user::create_user, mysql::TestMysql, TestApp,
|
|
||||||
};
|
|
||||||
use futures::future::try_join_all;
|
|
||||||
use rust_decimal::Decimal;
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::time::sleep;
|
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
|
use web3_proxy::prelude::futures::future::try_join_all;
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
|
use web3_proxy::prelude::rust_decimal::Decimal;
|
||||||
|
use web3_proxy::prelude::tokio::time::sleep;
|
||||||
use web3_proxy::rpcs::blockchain::ArcBlock;
|
use web3_proxy::rpcs::blockchain::ArcBlock;
|
||||||
|
use web3_proxy::test_utils::TestInflux;
|
||||||
|
use web3_proxy::test_utils::{TestAnvil, TestMysql};
|
||||||
|
use web3_proxy_cli::test_utils::create_provider_with_rpc_key::create_provider_for_user;
|
||||||
|
use web3_proxy_cli::test_utils::rpc_key::user_get_first_rpc_key;
|
||||||
|
use web3_proxy_cli::test_utils::stats_accounting::{
|
||||||
|
user_get_influx_stats_aggregated, user_get_mysql_stats,
|
||||||
|
};
|
||||||
|
use web3_proxy_cli::test_utils::user_balance::user_get_balance;
|
||||||
|
use web3_proxy_cli::test_utils::{
|
||||||
|
admin_increases_balance::admin_increase_balance, create_admin::create_user_as_admin,
|
||||||
|
create_user::create_user, TestApp,
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
#[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
||||||
#[test_log::test(tokio::test)]
|
#[test_log::test(tokio::test)]
|
|
@ -1,14 +1,13 @@
|
||||||
mod common;
|
|
||||||
|
|
||||||
use crate::common::{anvil::TestAnvil, mysql::TestMysql, TestApp};
|
|
||||||
use ethers::prelude::U256;
|
|
||||||
use http::StatusCode;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::{
|
use tokio::{
|
||||||
task::yield_now,
|
task::yield_now,
|
||||||
time::{sleep, Instant},
|
time::{sleep, Instant},
|
||||||
};
|
};
|
||||||
|
use web3_proxy::prelude::ethers::prelude::U256;
|
||||||
|
use web3_proxy::prelude::http::StatusCode;
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
use web3_proxy::rpcs::blockchain::ArcBlock;
|
use web3_proxy::rpcs::blockchain::ArcBlock;
|
||||||
|
use web3_proxy_cli::test_utils::{TestAnvil, TestApp, TestMysql};
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
#[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
||||||
#[test_log::test(tokio::test)]
|
#[test_log::test(tokio::test)]
|
|
@ -1,22 +1,22 @@
|
||||||
mod common;
|
|
||||||
|
|
||||||
use crate::common::create_provider_with_rpc_key::create_provider_for_user;
|
|
||||||
use crate::common::influx::TestInflux;
|
|
||||||
use crate::common::rpc_key::user_get_first_rpc_key;
|
|
||||||
use crate::common::stats_accounting::{user_get_influx_stats_aggregated, user_get_mysql_stats};
|
|
||||||
use crate::common::user_balance::user_get_balance;
|
|
||||||
use crate::common::{
|
|
||||||
admin_increases_balance::admin_increase_balance, anvil::TestAnvil,
|
|
||||||
create_admin::create_user_as_admin, create_user::create_user, mysql::TestMysql, TestApp,
|
|
||||||
};
|
|
||||||
use futures::future::try_join_all;
|
|
||||||
use rust_decimal::Decimal;
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::time::sleep;
|
|
||||||
use tracing::{info, warn};
|
use tracing::{info, warn};
|
||||||
|
use web3_proxy::prelude::futures::future::try_join_all;
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
|
use web3_proxy::prelude::rust_decimal::Decimal;
|
||||||
|
use web3_proxy::prelude::tokio::time::sleep;
|
||||||
use web3_proxy::rpcs::blockchain::ArcBlock;
|
use web3_proxy::rpcs::blockchain::ArcBlock;
|
||||||
|
use web3_proxy_cli::test_utils::create_provider_with_rpc_key::create_provider_for_user;
|
||||||
|
use web3_proxy_cli::test_utils::rpc_key::user_get_first_rpc_key;
|
||||||
|
use web3_proxy_cli::test_utils::stats_accounting::{
|
||||||
|
user_get_influx_stats_aggregated, user_get_mysql_stats,
|
||||||
|
};
|
||||||
|
use web3_proxy_cli::test_utils::user_balance::user_get_balance;
|
||||||
|
use web3_proxy_cli::test_utils::{
|
||||||
|
admin_increases_balance::admin_increase_balance, create_admin::create_user_as_admin,
|
||||||
|
create_user::create_user, TestAnvil, TestApp, TestInflux, TestMysql,
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
#[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
||||||
#[test_log::test(tokio::test)]
|
#[test_log::test(tokio::test)]
|
|
@ -1,6 +1,11 @@
|
||||||
mod common;
|
use std::time::Duration;
|
||||||
|
use tracing::info;
|
||||||
use crate::common::{
|
use web3_proxy::balance::Balance;
|
||||||
|
use web3_proxy::prelude::ethers::prelude::U64;
|
||||||
|
use web3_proxy::prelude::migration::sea_orm::prelude::Decimal;
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
|
use web3_proxy::prelude::tokio::time::sleep;
|
||||||
|
use web3_proxy_cli::test_utils::{
|
||||||
admin_increases_balance::admin_increase_balance,
|
admin_increases_balance::admin_increase_balance,
|
||||||
create_admin::create_user_as_admin,
|
create_admin::create_user_as_admin,
|
||||||
create_user::{create_user, set_user_tier},
|
create_user::{create_user, set_user_tier},
|
||||||
|
@ -8,12 +13,6 @@ use crate::common::{
|
||||||
user_balance::user_get_balance,
|
user_balance::user_get_balance,
|
||||||
TestAnvil, TestApp, TestInflux, TestMysql,
|
TestAnvil, TestApp, TestInflux, TestMysql,
|
||||||
};
|
};
|
||||||
use ethers::prelude::U64;
|
|
||||||
use migration::sea_orm::prelude::Decimal;
|
|
||||||
use std::time::Duration;
|
|
||||||
use tokio::time::sleep;
|
|
||||||
use tracing::info;
|
|
||||||
use web3_proxy::balance::Balance;
|
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
#[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
||||||
#[test_log::test(tokio::test)]
|
#[test_log::test(tokio::test)]
|
|
@ -1,28 +1,27 @@
|
||||||
mod common;
|
|
||||||
|
|
||||||
use crate::common::admin_deposits::get_admin_deposits;
|
|
||||||
use crate::common::admin_increases_balance::admin_increase_balance;
|
|
||||||
use crate::common::anvil::TestAnvil;
|
|
||||||
use crate::common::create_admin::create_user_as_admin;
|
|
||||||
use crate::common::create_user::create_user;
|
|
||||||
use crate::common::mysql::TestMysql;
|
|
||||||
use crate::common::referral::{
|
|
||||||
get_referral_code, get_shared_referral_codes, get_used_referral_codes, UserSharedReferralInfo,
|
|
||||||
UserUsedReferralInfo,
|
|
||||||
};
|
|
||||||
use crate::common::rpc_key::{user_get_first_rpc_key, RpcKey};
|
|
||||||
use crate::common::user_balance::user_get_balance;
|
|
||||||
use crate::common::TestApp;
|
|
||||||
use ethers::prelude::{Http, Provider};
|
|
||||||
use ethers::{signers::Signer, types::Signature};
|
|
||||||
use migration::sea_orm::prelude::Decimal;
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tracing::{debug, info, trace};
|
use tracing::{debug, info, trace};
|
||||||
use ulid::Ulid;
|
|
||||||
use web3_proxy::frontend::users::authentication::PostLogin;
|
use web3_proxy::frontend::users::authentication::PostLogin;
|
||||||
|
use web3_proxy::prelude::ethers::prelude::{Http, Provider};
|
||||||
|
use web3_proxy::prelude::ethers::{signers::Signer, types::Signature};
|
||||||
|
use web3_proxy::prelude::migration::sea_orm::prelude::Decimal;
|
||||||
|
use web3_proxy::prelude::reqwest;
|
||||||
|
use web3_proxy::prelude::ulid::Ulid;
|
||||||
use web3_proxy::rpcs::blockchain::ArcBlock;
|
use web3_proxy::rpcs::blockchain::ArcBlock;
|
||||||
|
use web3_proxy_cli::test_utils::admin_deposits::get_admin_deposits;
|
||||||
|
use web3_proxy_cli::test_utils::admin_increases_balance::admin_increase_balance;
|
||||||
|
use web3_proxy_cli::test_utils::create_admin::create_user_as_admin;
|
||||||
|
use web3_proxy_cli::test_utils::create_user::create_user;
|
||||||
|
use web3_proxy_cli::test_utils::referral::{
|
||||||
|
get_referral_code, get_shared_referral_codes, get_used_referral_codes, UserSharedReferralInfo,
|
||||||
|
UserUsedReferralInfo,
|
||||||
|
};
|
||||||
|
use web3_proxy_cli::test_utils::rpc_key::{user_get_first_rpc_key, RpcKey};
|
||||||
|
use web3_proxy_cli::test_utils::user_balance::user_get_balance;
|
||||||
|
use web3_proxy_cli::test_utils::TestAnvil;
|
||||||
|
use web3_proxy_cli::test_utils::TestApp;
|
||||||
|
use web3_proxy_cli::test_utils::TestMysql;
|
||||||
|
|
||||||
/// TODO: use this type in the frontend
|
/// TODO: use this type in the frontend
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
Loading…
Reference in New Issue