Last active
July 22, 2024 12:55
-
-
Save flarocca/6116abe2748157218c72827431906cc4 to your computer and use it in GitHub Desktop.
revm EthersDB failure on single threaded test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[tokio::test] | |
async fn demo_test() { | |
// Problem: | |
// This test works fine with revm 8.0.0, but at latest version (12.1.0) it fails. | |
// There is a new at EthersDB::new() that checks that current tokio::runtime is | |
// not single-threaded (https://github.com/bluealloy/revm/blob/8eaff99234aca42955345e2775ef11e24e2c0339/crates/revm/src/db/ethersdb.rs#L24). | |
// Context: | |
// Our main application runs using tokio::main macro, which works pretty well with | |
// both versions of the library. However, as you can appreciate in the code snippet, | |
// all our integration tests run using tokio::test. | |
// These tests are integration tests meant to execute logic as close as possible to | |
// the real environment, that's why we use EthersDB directly. | |
// Challenge: | |
// Even though there is an alternative to create a EthersDB from a tokio::runtime | |
// (EthersDB::with_runtime(...)), that implies using different building mechanisms | |
// depending whether it is a test or the real application, which will require quite a | |
// significant amount of refactoring. | |
// Additionally, since we also use some Channels to send events between different parts | |
// of the application, it would also force us to refactor parts of the application not | |
// strictly related to EthersDB usage just for testing purposes. | |
// Open questions: | |
// 1. What is the reason behind the validation to prevent single-threaded scenarios? | |
// 2. What is the best way to use EthersDB to simulate transactions? | |
// 3. What is the best way to use EthersDB for integration testing like mine? | |
let provider = "https://eth-mainnet.g.alchemy.com/v2/{API_KEY}"; | |
let client = Arc::new(Provider::<Http>::try_from(provider).unwrap()); | |
let mut set = JoinSet::new(); | |
// This process simulates how a transaction is executed. For each transaction | |
// we spawn a new task that executes the transaction against a fresh EthersDB. | |
for _transaction in 1..4 { | |
let cloned_client = client.clone(); | |
set.spawn(async move { | |
// Select a specific block for simulation | |
let block_id = Some(BlockId::Number( | |
ethers_core::types::BlockNumber::from_str("latest").unwrap(), | |
)); | |
let db = EthersDB::new(cloned_client, block_id); | |
assert!(db.is_some(), "Failed to create EthersDB"); | |
}); | |
} | |
while let Some(res) = set.join_next().await { | |
assert!(res.is_ok()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment