763 lines
26 KiB
Rust
763 lines
26 KiB
Rust
use serde::Deserialize;
|
|
use std::str::FromStr;
|
|
use std::time::Duration;
|
|
use tracing::{debug, info, trace};
|
|
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::tokio;
|
|
use web3_proxy::prelude::ulid::Ulid;
|
|
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
|
|
#[derive(Debug, Deserialize)]
|
|
struct LoginPostResponse {
|
|
pub bearer_token: Ulid,
|
|
// pub rpc_keys: Value,
|
|
// /// unknown data gets put here
|
|
// #[serde(flatten, default = "HashMap::default")]
|
|
// pub extra: HashMap<String, serde_json::Value>,
|
|
}
|
|
|
|
/// TODO: 191 and the other message formats in another test
|
|
#[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
|
#[test_log::test(tokio::test)]
|
|
async fn test_log_in_and_out() {
|
|
let a = TestAnvil::spawn(31337).await;
|
|
|
|
let db = TestMysql::spawn().await;
|
|
|
|
let x = TestApp::spawn(&a, Some(&db), None, None).await;
|
|
|
|
let r = reqwest::Client::new();
|
|
|
|
let w = a.wallet(0);
|
|
|
|
let login_get_url = format!("{}user/login/{:?}", x.proxy_provider.url(), w.address());
|
|
let login_message = r.get(login_get_url).send().await.unwrap();
|
|
|
|
let login_message = login_message.text().await.unwrap();
|
|
|
|
// sign the message and POST it
|
|
let signed: Signature = w.sign_message(&login_message).await.unwrap();
|
|
trace!(?signed);
|
|
|
|
let post_login_data = PostLogin {
|
|
msg: login_message,
|
|
sig: signed.to_string(),
|
|
referral_code: None,
|
|
};
|
|
debug!(?post_login_data);
|
|
|
|
let login_post_url = format!("{}user/login", x.proxy_provider.url());
|
|
let login_response = r
|
|
.post(login_post_url)
|
|
.json(&post_login_data)
|
|
.send()
|
|
.await
|
|
.unwrap()
|
|
.json::<LoginPostResponse>()
|
|
.await
|
|
.unwrap();
|
|
|
|
info!(?login_response);
|
|
|
|
// use the bearer token to log out
|
|
let logout_post_url = format!("{}user/logout", x.proxy_provider.url());
|
|
let logout_response = r
|
|
.post(logout_post_url)
|
|
.bearer_auth(login_response.bearer_token)
|
|
.send()
|
|
.await
|
|
.unwrap()
|
|
.text()
|
|
.await
|
|
.unwrap();
|
|
|
|
info!(?logout_response);
|
|
|
|
assert_eq!(logout_response, "goodbye");
|
|
}
|
|
|
|
#[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
|
#[test_log::test(tokio::test)]
|
|
async fn test_admin_balance_increase() {
|
|
info!("Starting admin can increase balance");
|
|
|
|
let a: TestAnvil = TestAnvil::spawn(31337).await;
|
|
|
|
let db = TestMysql::spawn().await;
|
|
|
|
let x = TestApp::spawn(&a, Some(&db), None, None).await;
|
|
|
|
let r = reqwest::Client::builder()
|
|
.timeout(Duration::from_secs(20))
|
|
.build()
|
|
.unwrap();
|
|
|
|
let user_wallet = a.wallet(0);
|
|
let admin_wallet = a.wallet(1);
|
|
|
|
// Create three users, one referrer, one admin who bumps both their balances
|
|
let admin_login_response = create_user_as_admin(&x, &db, &r, &admin_wallet).await;
|
|
let user_login_response = create_user(&x, &r, &user_wallet, None).await;
|
|
|
|
// Bump both user's wallet to $20
|
|
admin_increase_balance(
|
|
&x,
|
|
&r,
|
|
&admin_login_response,
|
|
&user_wallet,
|
|
Decimal::from(20),
|
|
)
|
|
.await;
|
|
|
|
info!("Getting admin deposits");
|
|
let response = get_admin_deposits(&x, &r, &user_login_response).await;
|
|
info!(?response);
|
|
assert_eq!(
|
|
Decimal::from_str(
|
|
response["deposits"].get(0).unwrap()["amount"]
|
|
.as_str()
|
|
.unwrap()
|
|
)
|
|
.unwrap(),
|
|
Decimal::from(20)
|
|
);
|
|
assert_eq!(
|
|
response["deposits"].get(0).unwrap()["note"]
|
|
.as_str()
|
|
.unwrap(),
|
|
"Test increasing balance"
|
|
);
|
|
}
|
|
|
|
#[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
|
#[test_log::test(tokio::test)]
|
|
async fn test_user_balance_decreases() {
|
|
info!("Starting balance decreases with usage test");
|
|
|
|
let a: TestAnvil = TestAnvil::spawn(31337).await;
|
|
|
|
let db = TestMysql::spawn().await;
|
|
|
|
let x = TestApp::spawn(&a, Some(&db), None, None).await;
|
|
|
|
let r = reqwest::Client::builder()
|
|
.timeout(Duration::from_secs(20))
|
|
.build()
|
|
.unwrap();
|
|
|
|
let user_wallet = a.wallet(0);
|
|
let admin_wallet = a.wallet(1);
|
|
|
|
// Create three users, one referrer, one admin who bumps both their balances
|
|
let admin_login_response = create_user_as_admin(&x, &db, &r, &admin_wallet).await;
|
|
let user_login_response = create_user(&x, &r, &user_wallet, None).await;
|
|
|
|
// Get the rpc keys for this user
|
|
let rpc_keys: RpcKey = user_get_first_rpc_key(&x, &r, &user_login_response).await;
|
|
let proxy_endpoint = format!("{}rpc/{}", x.proxy_provider.url(), rpc_keys.secret_key);
|
|
let proxy_provider = Provider::<Http>::try_from(proxy_endpoint).unwrap();
|
|
|
|
// Make some requests while in the free tier, so we can test bookkeeping here
|
|
for _ in 1..=10_000 {
|
|
let _ = proxy_provider
|
|
.request::<_, Option<ArcBlock>>("eth_getBlockByNumber", ("latest", false))
|
|
.await
|
|
.unwrap()
|
|
.unwrap();
|
|
}
|
|
|
|
// Flush all stats here
|
|
let flushed = x.flush_stats_and_wait().await.unwrap();
|
|
info!(?flushed);
|
|
// assert_eq!(flush_count.timeseries, 0);
|
|
// assert!(flush_count.relational > 0);
|
|
|
|
// Check the balance, it should not have decreased; there should have been accounted free credits, however
|
|
let user_balance = user_get_balance(&x, &r, &user_login_response).await;
|
|
// Check that the balance is 0
|
|
assert_eq!(user_balance.remaining(), Decimal::from(0));
|
|
// Check that paid credits is 0 (because balance is 0)
|
|
assert_eq!(user_balance.total_spent_paid_credits, Decimal::from(0));
|
|
// Check that paid credits is 0 (because balance is 0)
|
|
assert_eq!(user_balance.total_deposits(), Decimal::from(0));
|
|
// Check that total credits incl free used is larger than 0
|
|
let previously_free_spent = user_balance.total_spent;
|
|
assert!(previously_free_spent > Decimal::from(0));
|
|
|
|
// Bump both user's wallet to $20
|
|
admin_increase_balance(
|
|
&x,
|
|
&r,
|
|
&admin_login_response,
|
|
&user_wallet,
|
|
Decimal::from(20),
|
|
)
|
|
.await;
|
|
let user_balance_response = user_get_balance(&x, &r, &user_login_response).await;
|
|
let user_balance_pre = user_balance_response.remaining();
|
|
assert_eq!(user_balance_pre, Decimal::from(20));
|
|
|
|
for _ in 1..=10_000 {
|
|
let _ = proxy_provider
|
|
.request::<_, Option<ArcBlock>>("eth_getBlockByNumber", ("latest", false))
|
|
.await
|
|
.unwrap()
|
|
.unwrap();
|
|
}
|
|
|
|
// Flush all stats here
|
|
let flushed = x.flush_stats_and_wait().await.unwrap();
|
|
info!(?flushed);
|
|
// assert_eq!(flush_count.timeseries, 0);
|
|
// assert!(flush_count.relational == 1);
|
|
|
|
// Deposits should not be affected, and should be equal to what was initially provided
|
|
let user_balance = user_get_balance(&x, &r, &user_login_response).await;
|
|
|
|
let total_deposits = user_balance.total_deposits();
|
|
assert_eq!(total_deposits, Decimal::from(20));
|
|
// Check that total_spent_paid credits is equal to total_spent, because we are all still inside premium
|
|
assert_eq!(
|
|
user_balance.total_spent_paid_credits + previously_free_spent,
|
|
user_balance.total_spent,
|
|
);
|
|
// Get the full balance endpoint
|
|
let user_balance_post = user_balance.remaining();
|
|
assert!(user_balance_post < user_balance_pre);
|
|
|
|
// 10k while free, 10k while premium
|
|
assert_eq!(user_balance.total_frontend_requests, 20_000);
|
|
|
|
// Balance should be total deposits - usage while in the paid tier
|
|
let total_spent_in_paid_credits = user_balance.total_spent_paid_credits;
|
|
assert_eq!(
|
|
total_deposits - total_spent_in_paid_credits,
|
|
user_balance_post
|
|
);
|
|
|
|
// This should never be negative
|
|
assert!(user_balance.total_spent > Decimal::from(0));
|
|
}
|
|
|
|
#[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
|
#[test_log::test(tokio::test)]
|
|
async fn test_referral_bonus_non_concurrent() {
|
|
info!("Starting referral bonus test");
|
|
|
|
let a: TestAnvil = TestAnvil::spawn(31337).await;
|
|
|
|
let db = TestMysql::spawn().await;
|
|
|
|
let x = TestApp::spawn(&a, Some(&db), None, None).await;
|
|
|
|
let r = reqwest::Client::builder()
|
|
.timeout(Duration::from_secs(20))
|
|
.build()
|
|
.unwrap();
|
|
|
|
let user_wallet = a.wallet(0);
|
|
let referrer_wallet = a.wallet(1);
|
|
let admin_wallet = a.wallet(2);
|
|
|
|
// Create three users, one referrer, one admin who bumps both their balances
|
|
let referrer_login_response = create_user(&x, &r, &referrer_wallet, None).await;
|
|
let admin_login_response = create_user_as_admin(&x, &db, &r, &admin_wallet).await;
|
|
// Get the first user's referral link
|
|
let referral_link = get_referral_code(&x, &r, &referrer_login_response).await;
|
|
|
|
let user_login_response = create_user(&x, &r, &user_wallet, Some(referral_link.clone())).await;
|
|
|
|
// Bump both user's wallet to $20 (which will give them the Premium user tier)
|
|
admin_increase_balance(
|
|
&x,
|
|
&r,
|
|
&admin_login_response,
|
|
&user_wallet,
|
|
Decimal::from(20),
|
|
)
|
|
.await;
|
|
admin_increase_balance(
|
|
&x,
|
|
&r,
|
|
&admin_login_response,
|
|
&referrer_wallet,
|
|
Decimal::from(20),
|
|
)
|
|
.await;
|
|
|
|
// Get balance before for both users
|
|
let user_balance_response = user_get_balance(&x, &r, &user_login_response).await;
|
|
let user_balance_pre = user_balance_response.remaining();
|
|
let referrer_balance_response = user_get_balance(&x, &r, &referrer_login_response).await;
|
|
let referrer_balance_pre = referrer_balance_response.remaining();
|
|
|
|
// Make sure they both have balance now
|
|
assert_eq!(user_balance_pre, Decimal::from(20));
|
|
assert_eq!(referrer_balance_pre, Decimal::from(20));
|
|
|
|
// Setup variables that will be used
|
|
let shared_referral_code: UserSharedReferralInfo =
|
|
get_shared_referral_codes(&x, &r, &referrer_login_response).await;
|
|
let used_referral_code: UserUsedReferralInfo =
|
|
get_used_referral_codes(&x, &r, &user_login_response).await;
|
|
|
|
// assert that the used referral code is used
|
|
assert_eq!(
|
|
format!("{:?}", user_wallet.address()),
|
|
shared_referral_code
|
|
.clone()
|
|
.referrals
|
|
.first()
|
|
.unwrap()
|
|
.referred_address
|
|
.clone()
|
|
.unwrap()
|
|
);
|
|
assert_eq!(
|
|
referral_link.clone(),
|
|
used_referral_code
|
|
.clone()
|
|
.referrals
|
|
.first()
|
|
.unwrap()
|
|
.used_referral_code
|
|
.clone()
|
|
.unwrap()
|
|
);
|
|
|
|
// Make a for-loop just spam it a bit
|
|
// Make a JSON request
|
|
let rpc_keys: RpcKey = user_get_first_rpc_key(&x, &r, &user_login_response).await;
|
|
info!("Rpc key is: {:?}", rpc_keys);
|
|
|
|
let proxy_endpoint = format!("{}rpc/{}", x.proxy_provider.url(), rpc_keys.secret_key);
|
|
let proxy_provider = Provider::<Http>::try_from(proxy_endpoint).unwrap();
|
|
|
|
for _ in 1..=20_000 {
|
|
let _proxy_result = proxy_provider
|
|
.request::<_, Option<ArcBlock>>("eth_getBlockByNumber", ("latest", false))
|
|
.await
|
|
.unwrap()
|
|
.unwrap();
|
|
}
|
|
|
|
// Flush all stats here
|
|
let flushed = x.flush_stats_and_wait().await.unwrap();
|
|
info!(?flushed);
|
|
// we can't assert because the intervals might flush for us
|
|
// assert_eq!(flush_count.timeseries, 0);
|
|
// assert!(flush_count.relational > 0);
|
|
|
|
// Check that at least something was earned:
|
|
let shared_referral_code: UserSharedReferralInfo =
|
|
get_shared_referral_codes(&x, &r, &referrer_login_response).await;
|
|
info!(referrals=?shared_referral_code.referrals.first().unwrap(), "Referral code");
|
|
|
|
let user_balance = user_get_balance(&x, &r, &user_login_response).await;
|
|
|
|
// first, make sure that 20k requests were saved to the db
|
|
assert_eq!(user_balance.total_frontend_requests, 20_000);
|
|
|
|
// We make sure that the referrer has $10 + 10% of the used balance
|
|
// The admin provides credits for both
|
|
let user_balance_post = user_balance.remaining();
|
|
let referrer_balance = user_get_balance(&x, &r, &referrer_login_response).await;
|
|
let referrer_balance_post = referrer_balance.remaining();
|
|
|
|
info!(
|
|
"Balances before and after are (user): {:?} {:?}",
|
|
user_balance_pre, user_balance_post
|
|
);
|
|
info!(
|
|
"Balances before and after are (referrer): {:?} {:?}",
|
|
referrer_balance_pre, referrer_balance_post
|
|
);
|
|
|
|
let difference = user_balance_pre - user_balance_post;
|
|
|
|
// Make sure that the pre and post balance is not the same (i.e. some change has occurred)
|
|
assert_ne!(
|
|
user_balance_pre, user_balance_post,
|
|
"Pre and post balance is equivalent"
|
|
);
|
|
assert!(user_balance_pre > user_balance_post);
|
|
assert!(referrer_balance_pre < referrer_balance_post);
|
|
|
|
// Finally, make sure that referrer has received 10$ of balances
|
|
assert_eq!(
|
|
referrer_balance_pre + difference / Decimal::from(10),
|
|
referrer_balance_post
|
|
);
|
|
}
|
|
|
|
#[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
|
#[test_log::test(tokio::test)]
|
|
async fn test_referral_bonus_concurrent_referrer_only() {
|
|
info!("Starting referral bonus test");
|
|
|
|
let a = TestAnvil::spawn(31337).await;
|
|
|
|
let db = TestMysql::spawn().await;
|
|
|
|
let x = TestApp::spawn(&a, Some(&db), None, None).await;
|
|
|
|
let r = reqwest::Client::builder()
|
|
.timeout(Duration::from_secs(20))
|
|
.build()
|
|
.unwrap();
|
|
|
|
let user_wallet = a.wallet(0);
|
|
let referrer_wallet = a.wallet(1);
|
|
let admin_wallet = a.wallet(2);
|
|
|
|
// Create three users, one referrer, one admin who bumps both their balances
|
|
let referrer_login_response = create_user(&x, &r, &referrer_wallet, None).await;
|
|
let admin_login_response = create_user_as_admin(&x, &db, &r, &admin_wallet).await;
|
|
// Get the first user's referral link
|
|
let referral_link = get_referral_code(&x, &r, &referrer_login_response).await;
|
|
|
|
let user_login_response = create_user(&x, &r, &user_wallet, Some(referral_link.clone())).await;
|
|
|
|
// Bump both user's wallet to $20
|
|
admin_increase_balance(
|
|
&x,
|
|
&r,
|
|
&admin_login_response,
|
|
&user_wallet,
|
|
Decimal::from(20),
|
|
)
|
|
.await;
|
|
admin_increase_balance(
|
|
&x,
|
|
&r,
|
|
&admin_login_response,
|
|
&referrer_wallet,
|
|
Decimal::from(20),
|
|
)
|
|
.await;
|
|
|
|
// Get balance before for both users
|
|
let user_balance_response = user_get_balance(&x, &r, &user_login_response).await;
|
|
let user_balance_pre = user_balance_response.remaining();
|
|
let referrer_balance_response = user_get_balance(&x, &r, &referrer_login_response).await;
|
|
let referrer_balance_pre = referrer_balance_response.remaining();
|
|
|
|
// Make sure they both have balance now
|
|
assert_eq!(user_balance_pre, Decimal::from(20));
|
|
assert_eq!(referrer_balance_pre, Decimal::from(20));
|
|
|
|
// Setup variables that will be used
|
|
let shared_referral_code: UserSharedReferralInfo =
|
|
get_shared_referral_codes(&x, &r, &referrer_login_response).await;
|
|
let used_referral_code: UserUsedReferralInfo =
|
|
get_used_referral_codes(&x, &r, &user_login_response).await;
|
|
|
|
// assert that the used referral code is used
|
|
assert_eq!(
|
|
format!("{:?}", user_wallet.address()),
|
|
shared_referral_code
|
|
.clone()
|
|
.referrals
|
|
.first()
|
|
.unwrap()
|
|
.referred_address
|
|
.clone()
|
|
.unwrap()
|
|
);
|
|
assert_eq!(
|
|
referral_link.clone(),
|
|
used_referral_code
|
|
.clone()
|
|
.referrals
|
|
.first()
|
|
.unwrap()
|
|
.used_referral_code
|
|
.clone()
|
|
.unwrap()
|
|
);
|
|
|
|
// Make a for-loop just spam it a bit
|
|
// Make a JSON request
|
|
let rpc_keys: RpcKey = user_get_first_rpc_key(&x, &r, &user_login_response).await;
|
|
info!("Rpc key is: {:?}", rpc_keys);
|
|
|
|
// Spawn many requests proxy_providers
|
|
let number_requests = 100;
|
|
// Spin up concurrent requests ...
|
|
let mut handles = Vec::with_capacity(number_requests);
|
|
for _ in 0..number_requests {
|
|
let url = x.proxy_provider.url().clone();
|
|
let secret_key = rpc_keys.secret_key;
|
|
|
|
handles.push(tokio::spawn(async move {
|
|
let proxy_endpoint = format!("{}rpc/{}", url, secret_key);
|
|
let proxy_provider = Provider::<Http>::try_from(proxy_endpoint).unwrap();
|
|
|
|
proxy_provider
|
|
.request::<_, Option<ArcBlock>>("eth_getBlockByNumber", ("latest", false))
|
|
.await
|
|
.unwrap()
|
|
.unwrap()
|
|
}));
|
|
}
|
|
|
|
let mut results = Vec::with_capacity(handles.len());
|
|
for handle in handles {
|
|
results.push(handle.await.unwrap());
|
|
}
|
|
|
|
// Flush all stats here
|
|
let flushed = x.flush_stats_and_wait().await.unwrap();
|
|
info!(?flushed);
|
|
// assert_eq!(flush_count.timeseries, 0);
|
|
// assert!(flush_count.relational > 0);
|
|
|
|
// Check that at least something was earned:
|
|
let shared_referral_code: UserSharedReferralInfo =
|
|
get_shared_referral_codes(&x, &r, &referrer_login_response).await;
|
|
info!("Referral code");
|
|
info!("{:?}", shared_referral_code.referrals.first().unwrap());
|
|
|
|
// We make sure that the referrer has $10 + 10% of the used balance
|
|
// The admin provides credits for both
|
|
let user_balance_response = user_get_balance(&x, &r, &user_login_response).await;
|
|
let user_balance_post = user_balance_response.remaining();
|
|
let referrer_balance_response = user_get_balance(&x, &r, &referrer_login_response).await;
|
|
let referrer_balance_post = referrer_balance_response.remaining();
|
|
|
|
info!(
|
|
"Balances before and after are (user): {:?} {:?}",
|
|
user_balance_pre, user_balance_post
|
|
);
|
|
info!(
|
|
"Balances before and after are (referrer): {:?} {:?}",
|
|
referrer_balance_pre, referrer_balance_post
|
|
);
|
|
|
|
let difference = user_balance_pre - user_balance_post;
|
|
|
|
// Make sure that the pre and post balance is not the same (i.e. some change has occurred)
|
|
assert_ne!(
|
|
user_balance_pre, user_balance_post,
|
|
"Pre and post balance is equivalent"
|
|
);
|
|
assert!(user_balance_pre > user_balance_post);
|
|
assert!(referrer_balance_pre < referrer_balance_post);
|
|
|
|
// Finally, make sure that referrer has received 10$ of balances
|
|
assert_eq!(
|
|
referrer_balance_pre + difference / Decimal::from(10),
|
|
referrer_balance_post
|
|
);
|
|
|
|
// drop x first to avoid spurious warnings about anvil/influx/mysql shutting down before the app
|
|
drop(x);
|
|
}
|
|
|
|
#[cfg_attr(not(feature = "tests-needing-docker"), ignore)]
|
|
#[test_log::test(tokio::test)]
|
|
async fn test_referral_bonus_concurrent_referrer_and_user() {
|
|
info!("Starting referral bonus test");
|
|
|
|
let a = TestAnvil::spawn(31337).await;
|
|
|
|
let db = TestMysql::spawn().await;
|
|
|
|
let x = TestApp::spawn(&a, Some(&db), None, None).await;
|
|
|
|
let r = reqwest::Client::builder()
|
|
.timeout(Duration::from_secs(20))
|
|
.build()
|
|
.unwrap();
|
|
|
|
let user_wallet = a.wallet(0);
|
|
let referrer_wallet = a.wallet(1);
|
|
let admin_wallet = a.wallet(2);
|
|
|
|
// Create three users, one referrer, one admin who bumps both their balances
|
|
let referrer_login_response = create_user(&x, &r, &referrer_wallet, None).await;
|
|
let admin_login_response = create_user_as_admin(&x, &db, &r, &admin_wallet).await;
|
|
// Get the first user's referral link
|
|
let referral_link = get_referral_code(&x, &r, &referrer_login_response).await;
|
|
|
|
let user_login_response = create_user(&x, &r, &user_wallet, Some(referral_link.clone())).await;
|
|
|
|
// Bump both user's wallet to $20
|
|
admin_increase_balance(
|
|
&x,
|
|
&r,
|
|
&admin_login_response,
|
|
&user_wallet,
|
|
Decimal::from(20),
|
|
)
|
|
.await;
|
|
admin_increase_balance(
|
|
&x,
|
|
&r,
|
|
&admin_login_response,
|
|
&referrer_wallet,
|
|
Decimal::from(20),
|
|
)
|
|
.await;
|
|
|
|
// Get balance before for both users
|
|
let user_balance_response = user_get_balance(&x, &r, &user_login_response).await;
|
|
let user_balance_pre = user_balance_response.remaining();
|
|
let referrer_balance_response = user_get_balance(&x, &r, &referrer_login_response).await;
|
|
let referrer_balance_pre = referrer_balance_response.remaining();
|
|
|
|
// Make sure they both have balance now
|
|
assert_eq!(user_balance_pre, Decimal::from(20));
|
|
assert_eq!(referrer_balance_pre, Decimal::from(20));
|
|
|
|
// Setup variables that will be used
|
|
let shared_referral_code: UserSharedReferralInfo =
|
|
get_shared_referral_codes(&x, &r, &referrer_login_response).await;
|
|
let used_referral_code: UserUsedReferralInfo =
|
|
get_used_referral_codes(&x, &r, &user_login_response).await;
|
|
|
|
// assert that the used referral code is used
|
|
assert_eq!(
|
|
format!("{:?}", user_wallet.address()),
|
|
shared_referral_code
|
|
.clone()
|
|
.referrals
|
|
.first()
|
|
.unwrap()
|
|
.referred_address
|
|
.clone()
|
|
.unwrap()
|
|
);
|
|
assert_eq!(
|
|
referral_link.clone(),
|
|
used_referral_code
|
|
.clone()
|
|
.referrals
|
|
.first()
|
|
.unwrap()
|
|
.used_referral_code
|
|
.clone()
|
|
.unwrap()
|
|
);
|
|
|
|
// Make a for-loop just spam it a bit
|
|
// Make a JSON request
|
|
let referre_rpc_keys: RpcKey = user_get_first_rpc_key(&x, &r, &referrer_login_response).await;
|
|
let user_rpc_keys: RpcKey = user_get_first_rpc_key(&x, &r, &user_login_response).await;
|
|
info!("Rpc key is: {:?}", user_rpc_keys);
|
|
|
|
// Spawn many requests proxy_providers
|
|
let number_requests = 50;
|
|
// Spin up concurrent requests ...
|
|
let mut handles = Vec::with_capacity(number_requests);
|
|
|
|
// Make one request to create the cache; this originates from no user
|
|
let url = x.proxy_provider.url().clone();
|
|
let proxy_endpoint = format!("{}", url);
|
|
let proxy_provider = Provider::<Http>::try_from(proxy_endpoint).unwrap();
|
|
let _proxy_result = proxy_provider
|
|
.request::<_, Option<ArcBlock>>("eth_getBlockByNumber", ("latest", false))
|
|
.await
|
|
.unwrap()
|
|
.unwrap();
|
|
|
|
for _ in 1..number_requests {
|
|
let url = x.proxy_provider.url().clone();
|
|
let user_secret_key = user_rpc_keys.secret_key;
|
|
handles.push(tokio::spawn(async move {
|
|
let proxy_endpoint = format!("{}rpc/{}", url, user_secret_key);
|
|
let proxy_provider = Provider::<Http>::try_from(proxy_endpoint).unwrap();
|
|
proxy_provider
|
|
.request::<_, Option<ArcBlock>>("eth_getBlockByNumber", ("latest", false))
|
|
.await
|
|
.unwrap()
|
|
.unwrap()
|
|
}));
|
|
let url = x.proxy_provider.url().clone();
|
|
let referrer_secret_key = referre_rpc_keys.secret_key;
|
|
handles.push(tokio::spawn(async move {
|
|
let proxy_endpoint = format!("{}rpc/{}", url, referrer_secret_key);
|
|
let proxy_provider = Provider::<Http>::try_from(proxy_endpoint).unwrap();
|
|
proxy_provider
|
|
.request::<_, Option<ArcBlock>>("eth_getBlockByNumber", ("latest", false))
|
|
.await
|
|
.unwrap()
|
|
.unwrap()
|
|
}));
|
|
}
|
|
|
|
let mut results = Vec::with_capacity(handles.len());
|
|
for handle in handles {
|
|
results.push(handle.await.unwrap());
|
|
}
|
|
|
|
// Flush all stats here
|
|
let flushed = x.flush_stats_and_wait().await.unwrap();
|
|
info!(?flushed);
|
|
// assert_eq!(flush_count.timeseries, 0);
|
|
// assert!(flush_count.relational > 0);
|
|
|
|
// Check that at least something was earned:
|
|
let shared_referral_code: UserSharedReferralInfo =
|
|
get_shared_referral_codes(&x, &r, &referrer_login_response).await;
|
|
info!("Referral code");
|
|
info!("{:?}", shared_referral_code.referrals.first().unwrap());
|
|
|
|
// We make sure that the referrer has $10 + 10% of the used balance
|
|
// The admin provides credits for both
|
|
let user_balance_response = user_get_balance(&x, &r, &user_login_response).await;
|
|
let user_balance_post = user_balance_response.remaining();
|
|
let referrer_balance_response = user_get_balance(&x, &r, &referrer_login_response).await;
|
|
let referrer_balance_post = referrer_balance_response.remaining();
|
|
|
|
info!(
|
|
"Balances before and after are (user): {:?} {:?}",
|
|
user_balance_pre, user_balance_post
|
|
);
|
|
info!(
|
|
"Balances before and after are (referrer): {:?} {:?}",
|
|
referrer_balance_pre, referrer_balance_post
|
|
);
|
|
|
|
let user_difference = user_balance_pre - user_balance_post;
|
|
let referrer_difference = referrer_balance_pre - referrer_balance_post;
|
|
|
|
// Make sure that the pre and post balance is not the same (i.e. some change has occurred)
|
|
assert_ne!(
|
|
user_balance_pre, user_balance_post,
|
|
"Pre and post balance is equivalent"
|
|
);
|
|
assert!(user_balance_pre > user_balance_post);
|
|
assert!(referrer_balance_pre > referrer_balance_post);
|
|
assert!(user_difference > referrer_difference);
|
|
|
|
// In this case, the referrer loses as much as the user spends (because exact same operations), but gains 10% of what the user has spent
|
|
// I'm also adding 19.9992160000 - 19.9992944000 = 0.0000784 as this is the non-cached requests cost on top (for the user)
|
|
// Because of 1 cached request, we basically give one unit tolerance
|
|
assert_eq!(
|
|
(referrer_balance_pre - user_difference + user_difference / Decimal::from(10)),
|
|
referrer_balance_post
|
|
);
|
|
|
|
// drop x first to avoid spurious warnings about anvil/influx/mysql shutting down before the app
|
|
drop(x);
|
|
}
|