2020-09-24 21:33:09 +00:00
|
|
|
#[cfg(not(feature = "celo"))]
|
2020-11-27 12:57:44 +00:00
|
|
|
mod tests {
|
|
|
|
use ethers_core::{rand::thread_rng, types::TransactionRequest, utils::Ganache};
|
2020-09-24 21:33:09 +00:00
|
|
|
use ethers_middleware::{
|
2020-10-08 15:56:36 +00:00
|
|
|
gas_escalator::{Frequency, GasEscalatorMiddleware, GeometricGasPrice},
|
|
|
|
gas_oracle::{GasCategory, GasNow, GasOracleMiddleware},
|
|
|
|
nonce_manager::NonceManagerMiddleware,
|
|
|
|
signer::SignerMiddleware,
|
2020-09-24 21:33:09 +00:00
|
|
|
};
|
|
|
|
use ethers_providers::{Http, Middleware, Provider};
|
2020-10-02 08:41:16 +00:00
|
|
|
use ethers_signers::LocalWallet;
|
2020-09-24 21:33:09 +00:00
|
|
|
use std::convert::TryFrom;
|
|
|
|
|
2020-11-27 12:57:44 +00:00
|
|
|
#[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();
|
2020-09-24 21:33:09 +00:00
|
|
|
}
|
|
|
|
|
2020-11-27 12:57:44 +00:00
|
|
|
#[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
|
2020-12-18 11:15:19 +00:00
|
|
|
let provider = Arc::new(Provider::<Http>::try_from(ganache.endpoint()).unwrap());
|
2020-11-27 12:57:44 +00:00
|
|
|
|
|
|
|
// 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);
|
2020-09-24 21:33:09 +00:00
|
|
|
|
2020-11-27 12:57:44 +00:00
|
|
|
// 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
|
2020-12-18 11:15:19 +00:00
|
|
|
use std::sync::Arc;
|
|
|
|
let provider = Arc::new(SignerMiddleware::new(provider, signer));
|
2020-11-27 12:57:44 +00:00
|
|
|
|
|
|
|
// 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();
|
2020-12-17 11:26:01 +00:00
|
|
|
let mut pending_txs = Vec::new();
|
2020-11-27 12:57:44 +00:00
|
|
|
for _ in 0..10 {
|
2020-12-17 11:26:01 +00:00
|
|
|
let pending = provider.send_transaction(tx.clone(), None).await.unwrap();
|
|
|
|
let hash = *pending;
|
|
|
|
let gas_price = provider
|
|
|
|
.get_transaction(hash)
|
|
|
|
.await
|
|
|
|
.unwrap()
|
|
|
|
.unwrap()
|
|
|
|
.gas_price;
|
|
|
|
dbg!(gas_price);
|
|
|
|
pending_txs.push(pending);
|
2020-11-27 12:57:44 +00:00
|
|
|
}
|
|
|
|
|
2020-12-17 11:26:01 +00:00
|
|
|
let receipts = futures_util::future::join_all(pending_txs);
|
|
|
|
dbg!(receipts.await);
|
2020-11-27 12:57:44 +00:00
|
|
|
}
|
2020-09-24 21:33:09 +00:00
|
|
|
}
|