always do connectinfo for now
This commit is contained in:
parent
ffc5a46dc4
commit
f6c8172a13
@ -52,7 +52,7 @@ RUN --mount=type=cache,target=/usr/local/cargo/git \
|
||||
curl -L https://foundry.paradigm.xyz | bash && foundryup
|
||||
|
||||
# changing our features doesn't change any of the steps above
|
||||
ENV WEB3_PROXY_FEATURES "rdkafka-src,connectinfo"
|
||||
ENV WEB3_PROXY_FEATURES "rdkafka-src"
|
||||
|
||||
FROM rust as build_tests
|
||||
|
||||
|
@ -7,12 +7,11 @@ default-run = "web3_proxy_cli"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[features]
|
||||
default = ["connectinfo", "deadlock_detection"]
|
||||
default = ["deadlock_detection"]
|
||||
deadlock_detection = ["parking_lot/deadlock_detection"]
|
||||
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"]
|
||||
connectinfo = []
|
||||
|
||||
[dependencies]
|
||||
deferred-rate-limiter = { path = "../deferred-rate-limiter" }
|
||||
|
@ -264,17 +264,16 @@ pub async fn serve(
|
||||
- forwarded header (new standard)
|
||||
- axum::extract::ConnectInfo (if not behind proxy)
|
||||
*/
|
||||
#[cfg(feature = "connectinfo")]
|
||||
let make_service = {
|
||||
info!("connectinfo feature enabled");
|
||||
router.into_make_service_with_connect_info::<SocketAddr>()
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "connectinfo"))]
|
||||
let make_service = {
|
||||
info!("connectinfo feature disabled");
|
||||
router.into_make_service()
|
||||
};
|
||||
// #[cfg(not(feature = "connectinfo"))]
|
||||
// let make_service = {
|
||||
// info!("connectinfo feature disabled");
|
||||
// router.into_make_service()
|
||||
// };
|
||||
|
||||
let server = server_builder.serve(make_service);
|
||||
|
||||
|
162
web3_proxy/tests/common/app.rs
Normal file
162
web3_proxy/tests/common/app.rs
Normal file
@ -0,0 +1,162 @@
|
||||
use ethers::{
|
||||
prelude::{Http, Provider},
|
||||
signers::LocalWallet,
|
||||
types::Address,
|
||||
utils::{Anvil, AnvilInstance},
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
use parking_lot::Mutex;
|
||||
use std::{
|
||||
env,
|
||||
str::FromStr,
|
||||
sync::atomic::{AtomicU16, Ordering},
|
||||
};
|
||||
use std::{sync::Arc, time::Duration};
|
||||
use tokio::{
|
||||
sync::broadcast::{self, error::SendError},
|
||||
task::JoinHandle,
|
||||
time::{sleep, Instant},
|
||||
};
|
||||
use tracing::info;
|
||||
use web3_proxy::{
|
||||
config::{AppConfig, TopConfig, Web3RpcConfig},
|
||||
sub_commands::ProxydSubCommand,
|
||||
};
|
||||
|
||||
pub struct TestApp {
|
||||
/// anvil shuts down when this guard is dropped.
|
||||
anvil: AnvilInstance,
|
||||
|
||||
/// spawn handle for the proxy.
|
||||
handle: Mutex<Option<JoinHandle<anyhow::Result<()>>>>,
|
||||
|
||||
/// tell the app to shut down (use `self.stop()`).
|
||||
shutdown_sender: broadcast::Sender<()>,
|
||||
|
||||
/// connection to anvil.
|
||||
pub anvil_provider: Provider<Http>,
|
||||
|
||||
/// connection to the proxy that is connected to anil.
|
||||
pub proxy_provider: Provider<Http>,
|
||||
}
|
||||
|
||||
impl TestApp {
|
||||
pub async fn spawn() -> Self {
|
||||
let num_workers = 2;
|
||||
|
||||
// TODO: move basic setup into a test fixture
|
||||
let path = env::var("PATH").unwrap();
|
||||
|
||||
info!("path: {}", path);
|
||||
|
||||
// TODO: configurable rpc and block
|
||||
let anvil = Anvil::new()
|
||||
// .fork("https://polygon.llamarpc.com@44300000")
|
||||
.spawn();
|
||||
|
||||
info!("Anvil running at `{}`", anvil.endpoint());
|
||||
|
||||
let anvil_provider = Provider::<Http>::try_from(anvil.endpoint()).unwrap();
|
||||
|
||||
// make a test TopConfig
|
||||
// TODO: test influx
|
||||
// TODO: test redis
|
||||
let top_config = TopConfig {
|
||||
app: AppConfig {
|
||||
chain_id: 31337,
|
||||
// TODO: [make sqlite work](<https://www.sea-ql.org/SeaORM/docs/write-test/sqlite/>)
|
||||
// db_url: Some("sqlite::memory:".into()),
|
||||
default_user_max_requests_per_period: Some(6_000_000),
|
||||
deposit_factory_contract: Address::from_str(
|
||||
"4e3BC2054788De923A04936C6ADdB99A05B0Ea36",
|
||||
)
|
||||
.ok(),
|
||||
min_sum_soft_limit: 1,
|
||||
min_synced_rpcs: 1,
|
||||
public_requests_per_period: Some(1_000_000),
|
||||
response_cache_max_bytes: 10_u64.pow(7),
|
||||
..Default::default()
|
||||
},
|
||||
balanced_rpcs: HashMap::from([(
|
||||
"anvil".to_string(),
|
||||
Web3RpcConfig {
|
||||
http_url: Some(anvil.endpoint()),
|
||||
ws_url: Some(anvil.ws_endpoint()),
|
||||
..Default::default()
|
||||
},
|
||||
)]),
|
||||
private_rpcs: None,
|
||||
bundler_4337_rpcs: None,
|
||||
extra: Default::default(),
|
||||
};
|
||||
|
||||
let (shutdown_sender, _shutdown_receiver) = broadcast::channel(1);
|
||||
|
||||
let frontend_port_arc = Arc::new(AtomicU16::new(0));
|
||||
let prometheus_port_arc = Arc::new(AtomicU16::new(0));
|
||||
|
||||
// spawn the app
|
||||
// TODO: spawn in a thread so we can run from non-async tests and so the Drop impl can wait for it to stop
|
||||
let handle = {
|
||||
tokio::spawn(ProxydSubCommand::_main(
|
||||
top_config,
|
||||
None,
|
||||
frontend_port_arc.clone(),
|
||||
prometheus_port_arc,
|
||||
num_workers,
|
||||
shutdown_sender.clone(),
|
||||
))
|
||||
};
|
||||
|
||||
let mut frontend_port = frontend_port_arc.load(Ordering::Relaxed);
|
||||
let start = Instant::now();
|
||||
while frontend_port == 0 {
|
||||
if start.elapsed() > Duration::from_secs(1) {
|
||||
panic!("took too long to start!");
|
||||
}
|
||||
|
||||
sleep(Duration::from_millis(10)).await;
|
||||
frontend_port = frontend_port_arc.load(Ordering::Relaxed);
|
||||
}
|
||||
|
||||
let proxy_endpoint = format!("http://127.0.0.1:{}", frontend_port);
|
||||
|
||||
let proxy_provider = Provider::<Http>::try_from(proxy_endpoint).unwrap();
|
||||
|
||||
Self {
|
||||
anvil,
|
||||
anvil_provider,
|
||||
handle: Mutex::new(Some(handle)),
|
||||
proxy_provider,
|
||||
shutdown_sender,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stop(&self) -> Result<usize, SendError<()>> {
|
||||
self.shutdown_sender.send(())
|
||||
}
|
||||
|
||||
pub async fn wait(&self) {
|
||||
// TODO: lock+take feels weird, but it works
|
||||
let handle = self.handle.lock().take();
|
||||
|
||||
if let Some(handle) = handle {
|
||||
let _ = self.stop();
|
||||
|
||||
info!("waiting for the app to stop...");
|
||||
handle.await.unwrap().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wallet(&self, id: usize) -> LocalWallet {
|
||||
self.anvil.keys()[id].clone().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestApp {
|
||||
fn drop(&mut self) {
|
||||
let _ = self.stop();
|
||||
|
||||
// TODO: do we care about waiting for it to stop? it will slow our tests down so we probably only care about waiting in some tests
|
||||
}
|
||||
}
|
@ -1,157 +1,3 @@
|
||||
use ethers::{
|
||||
prelude::{Http, Provider},
|
||||
types::Address,
|
||||
utils::{Anvil, AnvilInstance},
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
use parking_lot::Mutex;
|
||||
use std::{
|
||||
env,
|
||||
str::FromStr,
|
||||
sync::atomic::{AtomicU16, Ordering},
|
||||
};
|
||||
use std::{sync::Arc, time::Duration};
|
||||
use tokio::{
|
||||
sync::broadcast::{self, error::SendError},
|
||||
task::JoinHandle,
|
||||
time::{sleep, Instant},
|
||||
};
|
||||
use tracing::info;
|
||||
use web3_proxy::{
|
||||
config::{AppConfig, TopConfig, Web3RpcConfig},
|
||||
sub_commands::ProxydSubCommand,
|
||||
};
|
||||
mod app;
|
||||
|
||||
pub struct TestApp {
|
||||
/// anvil shuts down when this guard is dropped.
|
||||
_anvil: AnvilInstance,
|
||||
|
||||
/// spawn handle for the proxy.
|
||||
handle: Mutex<Option<JoinHandle<anyhow::Result<()>>>>,
|
||||
|
||||
/// tell the app to shut down (use `self.stop()`).
|
||||
shutdown_sender: broadcast::Sender<()>,
|
||||
|
||||
/// connection to anvil.
|
||||
pub anvil_provider: Provider<Http>,
|
||||
|
||||
/// connection to the proxy that is connected to anil.
|
||||
pub proxy_provider: Provider<Http>,
|
||||
}
|
||||
|
||||
impl TestApp {
|
||||
pub async fn spawn() -> Self {
|
||||
let num_workers = 2;
|
||||
|
||||
// TODO: move basic setup into a test fixture
|
||||
let path = env::var("PATH").unwrap();
|
||||
|
||||
info!("path: {}", path);
|
||||
|
||||
// TODO: configurable rpc and block
|
||||
let anvil = Anvil::new()
|
||||
// .fork("https://polygon.llamarpc.com@44300000")
|
||||
.spawn();
|
||||
|
||||
info!("Anvil running at `{}`", anvil.endpoint());
|
||||
|
||||
let anvil_provider = Provider::<Http>::try_from(anvil.endpoint()).unwrap();
|
||||
|
||||
// make a test TopConfig
|
||||
// TODO: test influx
|
||||
// TODO: test redis
|
||||
let top_config = TopConfig {
|
||||
app: AppConfig {
|
||||
chain_id: 31337,
|
||||
// TODO: [make sqlite work](<https://www.sea-ql.org/SeaORM/docs/write-test/sqlite/>)
|
||||
// db_url: Some("sqlite::memory:".into()),
|
||||
default_user_max_requests_per_period: Some(6_000_000),
|
||||
deposit_factory_contract: Address::from_str(
|
||||
"4e3BC2054788De923A04936C6ADdB99A05B0Ea36",
|
||||
)
|
||||
.ok(),
|
||||
min_sum_soft_limit: 1,
|
||||
min_synced_rpcs: 1,
|
||||
public_requests_per_period: Some(1_000_000),
|
||||
response_cache_max_bytes: 10_u64.pow(7),
|
||||
..Default::default()
|
||||
},
|
||||
balanced_rpcs: HashMap::from([(
|
||||
"anvil".to_string(),
|
||||
Web3RpcConfig {
|
||||
http_url: Some(anvil.endpoint()),
|
||||
ws_url: Some(anvil.ws_endpoint()),
|
||||
..Default::default()
|
||||
},
|
||||
)]),
|
||||
private_rpcs: None,
|
||||
bundler_4337_rpcs: None,
|
||||
extra: Default::default(),
|
||||
};
|
||||
|
||||
let (shutdown_sender, _shutdown_receiver) = broadcast::channel(1);
|
||||
|
||||
let frontend_port_arc = Arc::new(AtomicU16::new(0));
|
||||
let prometheus_port_arc = Arc::new(AtomicU16::new(0));
|
||||
|
||||
// spawn the app
|
||||
// TODO: spawn in a thread so we can run from non-async tests and so the Drop impl can wait for it to stop
|
||||
let handle = {
|
||||
tokio::spawn(ProxydSubCommand::_main(
|
||||
top_config,
|
||||
None,
|
||||
frontend_port_arc.clone(),
|
||||
prometheus_port_arc,
|
||||
num_workers,
|
||||
shutdown_sender.clone(),
|
||||
))
|
||||
};
|
||||
|
||||
let mut frontend_port = frontend_port_arc.load(Ordering::Relaxed);
|
||||
let start = Instant::now();
|
||||
while frontend_port == 0 {
|
||||
if start.elapsed() > Duration::from_secs(1) {
|
||||
panic!("took too long to start!");
|
||||
}
|
||||
|
||||
sleep(Duration::from_millis(10)).await;
|
||||
frontend_port = frontend_port_arc.load(Ordering::Relaxed);
|
||||
}
|
||||
|
||||
let proxy_endpoint = format!("http://127.0.0.1:{}", frontend_port);
|
||||
|
||||
let proxy_provider = Provider::<Http>::try_from(proxy_endpoint).unwrap();
|
||||
|
||||
Self {
|
||||
handle: Mutex::new(Some(handle)),
|
||||
anvil_provider,
|
||||
proxy_provider,
|
||||
shutdown_sender,
|
||||
_anvil: anvil,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn stop(&self) -> Result<usize, SendError<()>> {
|
||||
self.shutdown_sender.send(())
|
||||
}
|
||||
|
||||
pub async fn wait(&self) {
|
||||
// TODO: lock+take feels weird, but it works
|
||||
let handle = self.handle.lock().take();
|
||||
|
||||
if let Some(handle) = handle {
|
||||
let _ = self.stop();
|
||||
|
||||
info!("waiting for the app to stop...");
|
||||
handle.await.unwrap().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TestApp {
|
||||
fn drop(&mut self) {
|
||||
let _ = self.stop();
|
||||
|
||||
// TODO: do we care about waiting for it to stop? it will slow our tests down so we probably only care about waiting in some tests
|
||||
}
|
||||
}
|
||||
pub use self::app::TestApp;
|
||||
|
@ -2,8 +2,12 @@ mod common;
|
||||
|
||||
use crate::common::TestApp;
|
||||
use ethers::prelude::U256;
|
||||
use http::StatusCode;
|
||||
use std::time::Duration;
|
||||
use tokio::time::{sleep, Instant};
|
||||
use tokio::{
|
||||
task::yield_now,
|
||||
time::{sleep, Instant},
|
||||
};
|
||||
use web3_proxy::rpcs::blockchain::ArcBlock;
|
||||
|
||||
#[test_log::test(tokio::test)]
|
||||
@ -26,6 +30,17 @@ async fn it_starts_and_stops() {
|
||||
|
||||
assert_eq!(anvil_result, proxy_result);
|
||||
|
||||
// check the /health page
|
||||
let proxy_url = x.proxy_provider.url();
|
||||
let health_response = reqwest::get(format!("{}health", proxy_url)).await;
|
||||
dbg!(&health_response);
|
||||
assert_eq!(health_response.unwrap().status(), StatusCode::OK);
|
||||
|
||||
// check the /status page
|
||||
let status_response = reqwest::get(format!("{}status", proxy_url)).await;
|
||||
dbg!(&status_response);
|
||||
assert_eq!(status_response.unwrap().status(), StatusCode::OK);
|
||||
|
||||
let first_block_num = anvil_result.number.unwrap();
|
||||
|
||||
// mine a block
|
||||
@ -42,6 +57,8 @@ async fn it_starts_and_stops() {
|
||||
|
||||
assert_eq!(first_block_num, second_block_num - 1);
|
||||
|
||||
yield_now().await;
|
||||
|
||||
let mut proxy_result;
|
||||
let start = Instant::now();
|
||||
loop {
|
||||
@ -55,7 +72,7 @@ async fn it_starts_and_stops() {
|
||||
.unwrap();
|
||||
|
||||
if let Some(ref proxy_result) = proxy_result {
|
||||
if proxy_result.number != Some(first_block_num) {
|
||||
if proxy_result.number == Some(second_block_num) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ use crate::common::TestApp;
|
||||
async fn test_log_in_and_out() {
|
||||
let x = TestApp::spawn().await;
|
||||
|
||||
let w = x.wallet(0);
|
||||
|
||||
todo!();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user