ethers-rs/ethers-middleware/tests/stack.rs

101 lines
3.9 KiB
Rust

#[cfg(not(feature = "celo"))]
mod tests {
use ethers_core::{rand::thread_rng, types::TransactionRequest, utils::Ganache};
use ethers_middleware::{
gas_escalator::{Frequency, GasEscalatorMiddleware, GeometricGasPrice},
gas_oracle::{GasCategory, GasNow, GasOracleMiddleware},
nonce_manager::NonceManagerMiddleware,
signer::SignerMiddleware,
};
use ethers_providers::{Http, Middleware, Provider};
use ethers_signers::LocalWallet;
use std::convert::TryFrom;
#[tokio::test]
async fn mock_with_middleware() {
let (provider, mock) = Provider::mocked();
// add a bunch of middlewares
let gas_oracle = GasNow::new().category(GasCategory::SafeLow);
let signer = LocalWallet::new(&mut thread_rng());
let address = signer.address();
let escalator = GeometricGasPrice::new(1.125, 60u64, None::<u64>);
let provider = GasEscalatorMiddleware::new(provider, escalator, Frequency::PerBlock);
let provider = GasOracleMiddleware::new(provider, gas_oracle);
let provider = SignerMiddleware::new(provider, signer);
let provider = NonceManagerMiddleware::new(provider, address);
// push a response
use ethers_core::types::U64;
mock.push(U64::from(12u64)).unwrap();
let blk = provider.get_block_number().await.unwrap();
assert_eq!(blk.as_u64(), 12);
// now that the response is gone, there's nothing left
// TODO: This returns:
// MiddlewareError(
// MiddlewareError(
// MiddlewareError(
// MiddlewareError(
// JsonRpcClientError(EmptyResponses)
// ))))
// Can we flatten it in any way? Maybe inherent to the middleware
// infrastructure
provider.get_block_number().await.unwrap_err();
// 2 calls were made
mock.assert_request("eth_blockNumber", ()).unwrap();
mock.assert_request("eth_blockNumber", ()).unwrap();
mock.assert_request("eth_blockNumber", ()).unwrap_err();
}
#[tokio::test]
async fn can_stack_middlewares() {
let ganache = Ganache::new().block_time(5u64).spawn();
let gas_oracle = GasNow::new().category(GasCategory::SafeLow);
let signer: LocalWallet = ganache.keys()[0].clone().into();
let address = signer.address();
// the base provider
let provider = Provider::<Http>::try_from(ganache.endpoint()).unwrap();
let provider_clone = provider.clone();
// the Gas Price escalator middleware is the first middleware above the provider,
// so that it receives the transaction last, after all the other middleware
// have modified it accordingly
let escalator = GeometricGasPrice::new(1.125, 60u64, None::<u64>);
let provider = GasEscalatorMiddleware::new(provider, escalator, Frequency::PerBlock);
// The gas price middleware MUST be below the signing middleware for things to work
let provider = GasOracleMiddleware::new(provider, gas_oracle);
// The signing middleware signs txs
let provider = SignerMiddleware::new(provider, signer);
// The nonce manager middleware MUST be above the signing middleware so that it overrides
// the nonce and the signer does not make any eth_getTransaction count calls
let provider = NonceManagerMiddleware::new(provider, address);
let tx = TransactionRequest::new();
let mut tx_hash = None;
for _ in 0..10 {
tx_hash = Some(provider.send_transaction(tx.clone(), None).await.unwrap());
dbg!(
provider
.get_transaction(tx_hash.unwrap())
.await
.unwrap()
.unwrap()
.gas_price
);
}
let receipt = provider_clone
.pending_transaction(tx_hash.unwrap())
.await
.unwrap();
dbg!(receipt);
}
}