run each etherscan test at least 200ms
This commit is contained in:
parent
20948d9fe5
commit
7e453722db
|
@ -22,7 +22,7 @@ serde-aux = { version = "3.0.1", default-features = false }
|
||||||
thiserror = "1.0.29"
|
thiserror = "1.0.29"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio = { version = "1.5", features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1.5", features = ["macros", "rt-multi-thread", "time"] }
|
||||||
serial_test = "0.5.1"
|
serial_test = "0.5.1"
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
use crate::{Client, Response, Result};
|
|
||||||
use ethers_core::abi::{Abi, Address};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use ethers_core::abi::{Abi, Address};
|
||||||
|
|
||||||
|
use crate::{Client, Response, Result};
|
||||||
|
|
||||||
/// Arguments for verifying contracts
|
/// Arguments for verifying contracts
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
pub struct VerifyContract {
|
pub struct VerifyContract {
|
||||||
|
@ -251,39 +254,49 @@ impl Client {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{contract::VerifyContract, Client};
|
use std::time::Duration;
|
||||||
use ethers_core::types::Chain;
|
|
||||||
|
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
|
||||||
|
use ethers_core::types::Chain;
|
||||||
|
|
||||||
|
use crate::{contract::VerifyContract, tests::run_at_least_duration, Client};
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
async fn can_fetch_contract_abi() {
|
async fn can_fetch_contract_abi() {
|
||||||
|
run_at_least_duration(Duration::from_millis(200), async {
|
||||||
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
||||||
|
|
||||||
let _abi = client
|
let _abi = client
|
||||||
.contract_abi("0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413".parse().unwrap())
|
.contract_abi("0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413".parse().unwrap())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
async fn can_fetch_contract_source_code() {
|
async fn can_fetch_contract_source_code() {
|
||||||
|
run_at_least_duration(Duration::from_millis(200), async {
|
||||||
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
||||||
|
|
||||||
let _meta = client
|
let _meta = client
|
||||||
.contract_source_code("0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413".parse().unwrap())
|
.contract_source_code("0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413".parse().unwrap())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
async fn can_verify_contract() {
|
async fn can_verify_contract() {
|
||||||
|
run_at_least_duration(Duration::from_millis(200), async {
|
||||||
// TODO this needs further investigation
|
// TODO this needs further investigation
|
||||||
|
|
||||||
// https://etherscan.io/address/0x9e744c9115b74834c0f33f4097f40c02a9ac5c33#code
|
// https://etherscan.io/address/0x9e744c9115b74834c0f33f4097f40c02a9ac5c33#code
|
||||||
|
@ -301,5 +314,6 @@ mod tests {
|
||||||
.runs(200);
|
.runs(200);
|
||||||
|
|
||||||
let _resp = client.submit_contract_verification(&contract).await;
|
let _resp = client.submit_contract_verification(&contract).await;
|
||||||
|
}).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,35 +70,46 @@ impl Client {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
|
||||||
use ethers_core::types::Chain;
|
use ethers_core::types::Chain;
|
||||||
|
|
||||||
|
use crate::tests::run_at_least_duration;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn gas_estimate_success() {
|
async fn gas_estimate_success() {
|
||||||
|
run_at_least_duration(Duration::from_millis(200), async {
|
||||||
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
||||||
|
|
||||||
let result = client.gas_estimate(2000000000u32.into()).await;
|
let result = client.gas_estimate(2000000000u32.into()).await;
|
||||||
|
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn gas_estimate_error() {
|
async fn gas_estimate_error() {
|
||||||
|
run_at_least_duration(Duration::from_millis(200), async {
|
||||||
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
||||||
|
|
||||||
let err = client.gas_estimate(7123189371829732819379218u128.into()).await.unwrap_err();
|
let err = client.gas_estimate(7123189371829732819379218u128.into()).await.unwrap_err();
|
||||||
|
|
||||||
assert!(matches!(err, EtherscanError::GasEstimationFailed));
|
assert!(matches!(err, EtherscanError::GasEstimationFailed));
|
||||||
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn gas_oracle_success() {
|
async fn gas_oracle_success() {
|
||||||
|
run_at_least_duration(Duration::from_millis(200), async {
|
||||||
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
||||||
|
|
||||||
let result = client.gas_oracle().await;
|
let result = client.gas_oracle().await;
|
||||||
|
@ -113,5 +124,7 @@ mod tests {
|
||||||
assert!(oracle.last_block > 0);
|
assert!(oracle.last_block > 0);
|
||||||
assert!(oracle.suggested_base_fee > 0.0);
|
assert!(oracle.suggested_base_fee > 0.0);
|
||||||
assert!(oracle.gas_used_ratio.len() > 0);
|
assert!(oracle.gas_used_ratio.len() > 0);
|
||||||
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,8 +78,7 @@ impl Client {
|
||||||
Chain::Mainnet | Chain::Ropsten | Chain::Kovan | Chain::Rinkeby | Chain::Goerli => {
|
Chain::Mainnet | Chain::Ropsten | Chain::Kovan | Chain::Rinkeby | Chain::Goerli => {
|
||||||
std::env::var("ETHERSCAN_API_KEY")?
|
std::env::var("ETHERSCAN_API_KEY")?
|
||||||
}
|
}
|
||||||
Chain::XDai => String::default(),
|
_ => String::default(),
|
||||||
chain => return Err(EtherscanError::ChainNotSupported(chain)),
|
|
||||||
};
|
};
|
||||||
Self::new(chain, api_key)
|
Self::new(chain, api_key)
|
||||||
}
|
}
|
||||||
|
@ -176,6 +175,11 @@ struct Query<'a, T: Serialize> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::{
|
||||||
|
future::Future,
|
||||||
|
time::{Duration, SystemTime},
|
||||||
|
};
|
||||||
|
|
||||||
use ethers_core::types::Chain;
|
use ethers_core::types::Chain;
|
||||||
|
|
||||||
use crate::{Client, EtherscanError};
|
use crate::{Client, EtherscanError};
|
||||||
|
@ -187,4 +191,12 @@ mod tests {
|
||||||
assert!(matches!(err, EtherscanError::ChainNotSupported(_)));
|
assert!(matches!(err, EtherscanError::ChainNotSupported(_)));
|
||||||
assert_eq!(err.to_string(), "chain XDai not supported");
|
assert_eq!(err.to_string(), "chain XDai not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn run_at_least_duration(duration: Duration, block: impl Future) {
|
||||||
|
let start = SystemTime::now();
|
||||||
|
block.await;
|
||||||
|
if let Some(sleep) = duration.checked_sub(start.elapsed().unwrap()) {
|
||||||
|
tokio::time::sleep(sleep).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,15 +52,18 @@ impl Client {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
|
||||||
use crate::Chain;
|
use crate::{tests::run_at_least_duration, Chain};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn check_contract_execution_status_success() {
|
async fn check_contract_execution_status_success() {
|
||||||
|
run_at_least_duration(Duration::from_millis(200), async {
|
||||||
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
||||||
|
|
||||||
let status = client
|
let status = client
|
||||||
|
@ -70,11 +73,14 @@ mod tests {
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
assert!(status.is_ok());
|
assert!(status.is_ok());
|
||||||
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn check_contract_execution_status_error() {
|
async fn check_contract_execution_status_error() {
|
||||||
|
run_at_least_duration(Duration::from_millis(200), async {
|
||||||
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
||||||
|
|
||||||
let err = client
|
let err = client
|
||||||
|
@ -86,11 +92,14 @@ mod tests {
|
||||||
|
|
||||||
assert!(matches!(err, EtherscanError::ExecutionFailed(_)));
|
assert!(matches!(err, EtherscanError::ExecutionFailed(_)));
|
||||||
assert_eq!(err.to_string(), "contract execution call failed: Bad jump destination");
|
assert_eq!(err.to_string(), "contract execution call failed: Bad jump destination");
|
||||||
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn check_transaction_receipt_status_success() {
|
async fn check_transaction_receipt_status_success() {
|
||||||
|
run_at_least_duration(Duration::from_millis(200), async {
|
||||||
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
||||||
|
|
||||||
let success = client
|
let success = client
|
||||||
|
@ -100,11 +109,14 @@ mod tests {
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
assert!(success.is_ok());
|
assert!(success.is_ok());
|
||||||
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn check_transaction_receipt_status_failed() {
|
async fn check_transaction_receipt_status_failed() {
|
||||||
|
run_at_least_duration(Duration::from_millis(200), async {
|
||||||
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
let client = Client::new_from_env(Chain::Mainnet).unwrap();
|
||||||
|
|
||||||
let err = client
|
let err = client
|
||||||
|
@ -115,5 +127,7 @@ mod tests {
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
assert!(matches!(err, EtherscanError::TransactionReceiptFailed));
|
assert!(matches!(err, EtherscanError::TransactionReceiptFailed));
|
||||||
|
})
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue