Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: flaky test #262

Merged
merged 7 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- fix: generate a fixed set of public and private keys for devnet
- fix: defaulted l1 gas price in devnet mode
- fix: fixed anvil port value in tests
- fix: flaky tests in gas price worker fixed
- ci: add coveralls report
- test: added tests for declare and deploy transactions
- fix: pending block must always be returned in rpc even if none is in db
Expand Down
41 changes: 41 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ httpmock = "0.7.0"
tempfile = "3.10.1"
env_logger = "0.11.3"
mockall = "0.13.0"
serial_test = "3.1.1"

[patch.crates-io]
starknet-core = { git = "https://github.com/kasarlabs/starknet-rs.git", branch = "fork" }
Expand Down
2 changes: 1 addition & 1 deletion cairo/.tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
scarb 2.7.0
scarb 2.8.2
1 change: 1 addition & 0 deletions crates/client/eth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,4 @@ dotenv = { workspace = true }
prometheus = { workspace = true }
httpmock = { workspace = true }
tracing-test = "0.2.5"
serial_test = { workspace = true }
76 changes: 38 additions & 38 deletions crates/client/eth/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,8 @@ pub mod eth_client_getter_test {
primitives::U256,
};
use mc_metrics::MetricsService;
use rstest::*;
use serial_test::serial;
use tokio;

// https://etherscan.io/tx/0xcadb202495cd8adba0d9b382caff907abf755cd42633d23c4988f875f2995d81#eventlog
// The txn we are referring to it is here ^
const L1_BLOCK_NUMBER: u64 = 20395662;
Expand All @@ -155,9 +154,7 @@ pub mod eth_client_getter_test {
const L2_BLOCK_HASH: &str = "563216050958639290223177746678863910249919294431961492885921903486585884664";
const L2_STATE_ROOT: &str = "1456190284387746219409791261254265303744585499659352223397867295223408682130";

#[fixture]
#[once]
fn anvil_instance() -> AnvilInstance {
fn create_anvil_instance() -> AnvilInstance {
let anvil = Anvil::new()
.fork(FORK_URL)
.fork_block_number(L1_BLOCK_NUMBER)
Expand All @@ -168,26 +165,8 @@ pub mod eth_client_getter_test {
anvil
}

#[rstest]
#[tokio::test]
async fn fail_create_new_client_invalid_core_contract(anvil_instance: &AnvilInstance) {
let anvil = anvil_instance;
// Sepolia core contract instead of mainnet
const INVALID_CORE_CONTRACT_ADDRESS: &str = "0xE2Bb56ee936fd6433DC0F6e7e3b8365C906AA057";

let rpc_url: Url = anvil.endpoint_url();

let core_contract_address = Address::parse_checksummed(INVALID_CORE_CONTRACT_ADDRESS, None).unwrap();
let prometheus_service = MetricsService::new(true, false, 9615).unwrap();
let l1_block_metrics = L1BlockMetrics::register(&prometheus_service.registry()).unwrap();

let new_client_result = EthereumClient::new(rpc_url, core_contract_address, l1_block_metrics).await;
assert!(new_client_result.is_err(), "EthereumClient::new should fail with an invalid core contract address");
}

pub fn create_ethereum_client(url: Option<&str>) -> EthereumClient {
let rpc_url_string = url.unwrap_or("http://localhost:8545").to_string();
let rpc_url: Url = rpc_url_string.parse().expect("issue while parsing URL");
let rpc_url: Url = url.unwrap_or("http://localhost:8545").parse().expect("issue while parsing URL");

let provider = ProviderBuilder::new().on_http(rpc_url.clone());
let address = Address::parse_checksummed(CORE_CONTRACT_ADDRESS, None).unwrap();
Expand All @@ -199,50 +178,71 @@ pub mod eth_client_getter_test {
EthereumClient { provider: Arc::new(provider), l1_core_contract: contract.clone(), l1_block_metrics }
}

#[fixture]
#[once]
pub fn eth_client(anvil_instance: &AnvilInstance) -> EthereumClient {
create_ethereum_client(Some(&anvil_instance.endpoint()))
#[serial]
#[tokio::test]
async fn fail_create_new_client_invalid_core_contract() {
let anvil = create_anvil_instance();
// Sepolia core contract instead of mainnet
const INVALID_CORE_CONTRACT_ADDRESS: &str = "0xE2Bb56ee936fd6433DC0F6e7e3b8365C906AA057";

let rpc_url: Url = anvil.endpoint_url();

let core_contract_address = Address::parse_checksummed(INVALID_CORE_CONTRACT_ADDRESS, None).unwrap();
let prometheus_service = MetricsService::new(true, false, 9615).unwrap();
let l1_block_metrics = L1BlockMetrics::register(&prometheus_service.registry()).unwrap();

let new_client_result = EthereumClient::new(rpc_url, core_contract_address, l1_block_metrics).await;
assert!(new_client_result.is_err(), "EthereumClient::new should fail with an invalid core contract address");
}

#[rstest]
#[serial]
#[tokio::test]
async fn get_latest_block_number_works(eth_client: &EthereumClient) {
async fn get_latest_block_number_works() {
let anvil = create_anvil_instance();
let eth_client = create_ethereum_client(Some(anvil.endpoint().as_str()));
let block_number =
eth_client.provider.get_block_number().await.expect("issue while fetching the block number").as_u64();
assert_eq!(block_number, L1_BLOCK_NUMBER, "provider unable to get the correct block number");
}

#[rstest]
#[serial]
#[tokio::test]
async fn get_last_event_block_number_works(eth_client: &EthereumClient) {
async fn get_last_event_block_number_works() {
let anvil = create_anvil_instance();
let eth_client = create_ethereum_client(Some(anvil.endpoint().as_str()));
let block_number = eth_client
.get_last_event_block_number::<StarknetCoreContract::LogStateUpdate>()
.await
.expect("issue while getting the last block number with given event");
assert_eq!(block_number, L1_BLOCK_NUMBER, "block number with given event not matching");
}

#[rstest]
#[serial]
#[tokio::test]
async fn get_last_verified_block_hash_works(eth_client: &EthereumClient) {
async fn get_last_verified_block_hash_works() {
let anvil = create_anvil_instance();
let eth_client = create_ethereum_client(Some(anvil.endpoint().as_str()));
let block_hash =
eth_client.get_last_verified_block_hash().await.expect("issue while getting the last verified block hash");
let expected = u256_to_felt(U256::from_str_radix(L2_BLOCK_HASH, 10).unwrap()).unwrap();
assert_eq!(block_hash, expected, "latest block hash not matching");
}

#[rstest]
#[serial]
#[tokio::test]
async fn get_last_state_root_works(eth_client: &EthereumClient) {
async fn get_last_state_root_works() {
let anvil = create_anvil_instance();
let eth_client = create_ethereum_client(Some(anvil.endpoint().as_str()));
let state_root = eth_client.get_last_state_root().await.expect("issue while getting the state root");
let expected = u256_to_felt(U256::from_str_radix(L2_STATE_ROOT, 10).unwrap()).unwrap();
assert_eq!(state_root, expected, "latest block state root not matching");
}

#[rstest]
#[serial]
#[tokio::test]
async fn get_last_verified_block_number_works(eth_client: &EthereumClient) {
async fn get_last_verified_block_number_works() {
let anvil = create_anvil_instance();
let eth_client = create_ethereum_client(Some(anvil.endpoint().as_str()));
let block_number = eth_client.get_last_verified_block_number().await.expect("issue");
assert_eq!(block_number, L2_BLOCK_NUMBER, "verified block number not matching");
}
Expand Down
48 changes: 27 additions & 21 deletions crates/client/eth/src/l1_gas_price.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,29 +91,28 @@ async fn update_l1_block_metrics(eth_client: &EthereumClient, l1_gas_provider: G
#[cfg(test)]
mod eth_client_gas_price_worker_test {
use super::*;
use crate::client::eth_client_getter_test::{create_ethereum_client, eth_client};
use crate::client::eth_client_getter_test::create_ethereum_client;
use alloy::node_bindings::Anvil;
use httpmock::{MockServer, Regex};
use mc_mempool::GasPriceProvider;
use rstest::*;
use serial_test::serial;
use std::time::SystemTime;
use tokio::task::JoinHandle;
use tokio::time::{timeout, Duration};

const ANOTHER_ANVIL_PORT: u16 = 8546;
const L1_BLOCK_NUMBER: u64 = 20395662;
const FORK_URL: &str = "https://eth.merkle.io";

#[fixture]
#[once]
pub fn eth_client_with_mock() -> (MockServer, EthereumClient) {
let server = MockServer::start();
let addr = format!("http://{}", server.address());
let eth_client = create_ethereum_client(Some(&addr));
(server, eth_client)
}

#[rstest]
#[serial]
#[tokio::test]
async fn gas_price_worker_when_infinite_loop_true_works(eth_client: &EthereumClient) {
async fn gas_price_worker_when_infinite_loop_true_works() {
let anvil = Anvil::new()
.fork(FORK_URL)
.fork_block_number(L1_BLOCK_NUMBER)
.port(ANOTHER_ANVIL_PORT)
.try_spawn()
.expect("issue while forking for the anvil");
let eth_client = create_ethereum_client(Some(anvil.endpoint().as_str()));
let l1_gas_provider = GasPriceProvider::new();

// Spawn the gas_price_worker in a separate task
Expand Down Expand Up @@ -145,11 +144,12 @@ mod eth_client_gas_price_worker_test {
assert_eq!(updated_price.eth_l1_data_gas_price, 1);
}

#[serial]
#[tokio::test]
async fn gas_price_worker_when_infinite_loop_false_works() {
let anvil = Anvil::new()
.fork("https://eth.merkle.io")
.fork_block_number(20395662)
.fork(FORK_URL)
.fork_block_number(L1_BLOCK_NUMBER)
.port(ANOTHER_ANVIL_PORT)
.try_spawn()
.expect("issue while forking for the anvil");
Expand All @@ -168,14 +168,13 @@ mod eth_client_gas_price_worker_test {
assert_eq!(updated_price.eth_l1_data_gas_price, 1);
}

#[serial]
#[tokio::test]
async fn gas_price_worker_when_eth_fee_history_fails_should_fails() {
let mock_server = MockServer::start();
let addr = format!("http://{}", mock_server.address());
let eth_client = create_ethereum_client(Some(&addr));

println!("add is: {:?} ", addr.as_str());

let mock = mock_server.mock(|when, then| {
when.method("POST").path("/").json_body_obj(&serde_json::json!({
"jsonrpc": "2.0",
Expand Down Expand Up @@ -228,15 +227,22 @@ mod eth_client_gas_price_worker_test {
mock.assert();
}

#[rstest]
#[serial]
#[tokio::test]
async fn update_gas_price_works(eth_client: &'static EthereumClient) {
async fn update_gas_price_works() {
let anvil = Anvil::new()
.fork(FORK_URL)
.fork_block_number(L1_BLOCK_NUMBER)
.port(ANOTHER_ANVIL_PORT)
.try_spawn()
.expect("issue while forking for the anvil");
let eth_client = create_ethereum_client(Some(anvil.endpoint().as_str()));
let l1_gas_provider = GasPriceProvider::new();

l1_gas_provider.update_last_update_timestamp();

// Update gas prices
update_gas_price(eth_client, l1_gas_provider.clone()).await.expect("Failed to update gas prices");
update_gas_price(&eth_client, l1_gas_provider.clone()).await.expect("Failed to update gas prices");

// Access the updated gas prices
let updated_prices = l1_gas_provider.get_gas_prices();
Expand Down
Loading