feat: rotating infura keys (#1017)
* feat: add providers which rotate api keys * test: use rotating key in provider instead of hardcoded * chore: fmt
This commit is contained in:
parent
367f3444ec
commit
ae125bcfc7
|
@ -1322,6 +1322,7 @@ dependencies = [
|
|||
"futures-util",
|
||||
"hex",
|
||||
"http",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"pin-project",
|
||||
"reqwest",
|
||||
|
|
|
@ -4,14 +4,11 @@
|
|||
async fn nonce_manager() {
|
||||
use ethers_core::types::*;
|
||||
use ethers_middleware::{nonce_manager::NonceManagerMiddleware, signer::SignerMiddleware};
|
||||
use ethers_providers::{Http, Middleware, Provider};
|
||||
use ethers_providers::Middleware;
|
||||
use ethers_signers::{LocalWallet, Signer};
|
||||
use std::{convert::TryFrom, time::Duration};
|
||||
use std::time::Duration;
|
||||
|
||||
let provider =
|
||||
Provider::<Http>::try_from("https://rinkeby.infura.io/v3/fd8b88b56aa84f6da87b60f5441d6778")
|
||||
.unwrap()
|
||||
.interval(Duration::from_millis(2000u64));
|
||||
let provider = ethers_providers::RINKEBY.provider().interval(Duration::from_millis(2000u64));
|
||||
let chain_id = provider.get_chainid().await.unwrap().as_u64();
|
||||
|
||||
let wallet = std::env::var("RINKEBY_PRIVATE_KEY")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#![allow(unused)]
|
||||
use ethers_providers::{Http, JsonRpcClient, Middleware, Provider};
|
||||
use ethers_providers::{Http, JsonRpcClient, Middleware, Provider, RINKEBY};
|
||||
|
||||
use ethers_core::{
|
||||
types::{BlockNumber, TransactionRequest},
|
||||
|
@ -8,7 +8,7 @@ use ethers_core::{
|
|||
use ethers_middleware::signer::SignerMiddleware;
|
||||
use ethers_signers::{coins_bip39::English, LocalWallet, MnemonicBuilder, Signer};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::{convert::TryFrom, sync::atomic::AtomicU8, time::Duration};
|
||||
use std::{convert::TryFrom, iter::Cycle, sync::atomic::AtomicU8, time::Duration};
|
||||
|
||||
static WALLETS: Lazy<TestWallets> = Lazy::new(|| {
|
||||
TestWallets {
|
||||
|
@ -54,10 +54,7 @@ async fn send_eth() {
|
|||
#[tokio::test]
|
||||
#[cfg(not(feature = "celo"))]
|
||||
async fn pending_txs_with_confirmations_testnet() {
|
||||
let provider =
|
||||
Provider::<Http>::try_from("https://rinkeby.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27")
|
||||
.unwrap()
|
||||
.interval(Duration::from_millis(3000));
|
||||
let provider = RINKEBY.provider().interval(Duration::from_millis(3000));
|
||||
let chain_id = provider.get_chainid().await.unwrap();
|
||||
let wallet = WALLETS.next().with_chain_id(chain_id.as_u64());
|
||||
let address = wallet.address();
|
||||
|
@ -97,9 +94,7 @@ async fn generic_pending_txs_test<M: Middleware>(provider: M, who: Address) {
|
|||
#[tokio::test]
|
||||
#[cfg(not(feature = "celo"))]
|
||||
async fn typed_txs() {
|
||||
let provider =
|
||||
Provider::<Http>::try_from("https://rinkeby.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27")
|
||||
.unwrap();
|
||||
let provider = RINKEBY.provider();
|
||||
|
||||
let chain_id = provider.get_chainid().await.unwrap();
|
||||
let wallet = WALLETS.next().with_chain_id(chain_id.as_u64());
|
||||
|
|
|
@ -39,6 +39,7 @@ tracing = { version = "0.1.32", default-features = false }
|
|||
tracing-futures = { version = "0.2.5", default-features = false, features = ["std-future"] }
|
||||
|
||||
bytes = { version = "1.1.0", default-features = false, optional = true }
|
||||
once_cell = "1.10.0"
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
# tokio
|
||||
|
|
|
@ -657,3 +657,53 @@ pub trait CeloMiddleware: Middleware {
|
|||
self.provider().get_validators_bls_public_keys(block_id).await.map_err(FromErr::from)
|
||||
}
|
||||
}
|
||||
|
||||
pub use test_provider::{GOERLI, MAINNET, RINKEBY, ROPSTEN};
|
||||
|
||||
/// Pre-instantiated Infura HTTP clients which rotate through multiple API keys
|
||||
/// to prevent rate limits
|
||||
pub mod test_provider {
|
||||
use super::*;
|
||||
use crate::Http;
|
||||
use once_cell::sync::Lazy;
|
||||
use std::{convert::TryFrom, iter::Cycle, slice::Iter, sync::Mutex};
|
||||
|
||||
// List of infura keys to rotate through so we don't get rate limited
|
||||
const INFURA_KEYS: &[&str] = &[
|
||||
"6770454bc6ea42c58aac12978531b93f",
|
||||
"7a8769b798b642f6933f2ed52042bd70",
|
||||
"631fd9a6539644088297dc605d35fff3",
|
||||
"16a8be88795540b9b3903d8de0f7baa5",
|
||||
"f4a0bdad42674adab5fc0ac077ffab2b",
|
||||
"5c812e02193c4ba793f8c214317582bd",
|
||||
];
|
||||
|
||||
pub static RINKEBY: Lazy<TestProvider> =
|
||||
Lazy::new(|| TestProvider::new(INFURA_KEYS, "rinkeby"));
|
||||
pub static MAINNET: Lazy<TestProvider> =
|
||||
Lazy::new(|| TestProvider::new(INFURA_KEYS, "mainnet"));
|
||||
pub static GOERLI: Lazy<TestProvider> = Lazy::new(|| TestProvider::new(INFURA_KEYS, "goerli"));
|
||||
pub static ROPSTEN: Lazy<TestProvider> =
|
||||
Lazy::new(|| TestProvider::new(INFURA_KEYS, "ropsten"));
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TestProvider {
|
||||
network: String,
|
||||
keys: Mutex<Cycle<Iter<'static, &'static str>>>,
|
||||
}
|
||||
|
||||
impl TestProvider {
|
||||
pub fn new(keys: &'static [&'static str], network: &str) -> Self {
|
||||
Self { keys: Mutex::new(keys.iter().cycle()), network: network.to_owned() }
|
||||
}
|
||||
|
||||
pub fn provider(&self) -> Provider<Http> {
|
||||
let url = format!(
|
||||
"https://{}.infura.io/v3/{}",
|
||||
self.network,
|
||||
self.keys.lock().unwrap().next().unwrap()
|
||||
);
|
||||
Provider::try_from(url.as_str()).unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1488,12 +1488,10 @@ mod tests {
|
|||
};
|
||||
use futures_util::StreamExt;
|
||||
|
||||
const INFURA: &str = "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27";
|
||||
|
||||
#[tokio::test]
|
||||
// Test vector from: https://docs.ethers.io/ethers.js/v5-beta/api-providers.html#id2
|
||||
async fn mainnet_resolve_name() {
|
||||
let provider = Provider::<HttpProvider>::try_from(INFURA).unwrap();
|
||||
let provider = crate::test_provider::MAINNET.provider();
|
||||
|
||||
let addr = provider.resolve_name("registrar.firefly.eth").await.unwrap();
|
||||
assert_eq!(addr, "6fC21092DA55B392b045eD78F4732bff3C580e2c".parse().unwrap());
|
||||
|
@ -1508,7 +1506,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
// Test vector from: https://docs.ethers.io/ethers.js/v5-beta/api-providers.html#id2
|
||||
async fn mainnet_lookup_address() {
|
||||
let provider = Provider::<HttpProvider>::try_from(INFURA).unwrap();
|
||||
let provider = crate::MAINNET.provider();
|
||||
|
||||
let name = provider
|
||||
.lookup_address("6fC21092DA55B392b045eD78F4732bff3C580e2c".parse().unwrap())
|
||||
|
@ -1525,7 +1523,7 @@ mod tests {
|
|||
|
||||
#[tokio::test]
|
||||
async fn mainnet_resolve_avatar() {
|
||||
let provider = Provider::<HttpProvider>::try_from(INFURA).unwrap();
|
||||
let provider = crate::MAINNET.provider();
|
||||
|
||||
for (ens_name, res) in &[
|
||||
// HTTPS
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#![cfg(not(target_arch = "wasm32"))]
|
||||
use ethers_providers::{Http, Middleware, Provider};
|
||||
use ethers_providers::{Http, Middleware, Provider, RINKEBY};
|
||||
use std::{convert::TryFrom, time::Duration};
|
||||
|
||||
#[cfg(not(feature = "celo"))]
|
||||
|
@ -12,10 +12,7 @@ mod eth_tests {
|
|||
|
||||
#[tokio::test]
|
||||
async fn non_existing_data_works() {
|
||||
let provider = Provider::<Http>::try_from(
|
||||
"https://rinkeby.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27",
|
||||
)
|
||||
.unwrap();
|
||||
let provider = RINKEBY.provider();
|
||||
|
||||
assert!(provider.get_transaction(H256::zero()).await.unwrap().is_none());
|
||||
assert!(provider.get_transaction_receipt(H256::zero()).await.unwrap().is_none());
|
||||
|
@ -25,10 +22,7 @@ mod eth_tests {
|
|||
|
||||
#[tokio::test]
|
||||
async fn client_version() {
|
||||
let provider = Provider::<Http>::try_from(
|
||||
"https://rinkeby.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27",
|
||||
)
|
||||
.unwrap();
|
||||
let provider = RINKEBY.provider();
|
||||
|
||||
// e.g., Geth/v1.10.6-omnibus-1af33248/linux-amd64/go1.16.6
|
||||
assert!(provider
|
||||
|
@ -95,10 +89,7 @@ mod eth_tests {
|
|||
|
||||
#[tokio::test]
|
||||
async fn eip1559_fee_estimation() {
|
||||
let provider = Provider::<Http>::try_from(
|
||||
"https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27",
|
||||
)
|
||||
.unwrap();
|
||||
let provider = ethers_providers::MAINNET.provider();
|
||||
|
||||
let (_max_fee_per_gas, _max_priority_fee_per_gas) =
|
||||
provider.estimate_eip1559_fees(None).await.unwrap();
|
||||
|
|
Loading…
Reference in New Issue