2020-09-24 21:33:09 +00:00
|
|
|
use ethers::providers::{Http, Middleware, Provider};
|
2020-06-22 08:44:08 +00:00
|
|
|
use std::{convert::TryFrom, time::Duration};
|
2020-06-17 08:02:03 +00:00
|
|
|
|
2020-06-17 09:22:01 +00:00
|
|
|
#[cfg(not(feature = "celo"))]
|
2020-06-21 07:17:11 +00:00
|
|
|
mod eth_tests {
|
|
|
|
use super::*;
|
2020-06-17 09:22:01 +00:00
|
|
|
use ethers::{
|
2020-12-17 09:23:10 +00:00
|
|
|
middleware::SignerMiddleware,
|
2021-08-09 00:31:11 +00:00
|
|
|
prelude::transaction::eip2718::TypedTransaction,
|
2021-07-29 20:22:25 +00:00
|
|
|
signers::{LocalWallet, Signer},
|
2020-09-17 11:06:56 +00:00
|
|
|
types::{BlockId, TransactionRequest, H256},
|
2020-12-17 09:23:10 +00:00
|
|
|
utils::Ganache,
|
2020-06-17 09:22:01 +00:00
|
|
|
};
|
2020-06-21 07:17:11 +00:00
|
|
|
|
2020-09-17 11:06:56 +00:00
|
|
|
#[tokio::test]
|
|
|
|
async fn non_existing_data_works() {
|
|
|
|
let provider = Provider::<Http>::try_from(
|
|
|
|
"https://rinkeby.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27",
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
assert!(provider
|
|
|
|
.get_transaction(H256::zero())
|
|
|
|
.await
|
|
|
|
.unwrap()
|
|
|
|
.is_none());
|
|
|
|
assert!(provider
|
|
|
|
.get_transaction_receipt(H256::zero())
|
|
|
|
.await
|
|
|
|
.unwrap()
|
|
|
|
.is_none());
|
|
|
|
assert!(provider
|
|
|
|
.get_block(BlockId::Hash(H256::zero()))
|
|
|
|
.await
|
|
|
|
.unwrap()
|
|
|
|
.is_none());
|
|
|
|
assert!(provider
|
|
|
|
.get_block_with_txs(BlockId::Hash(H256::zero()))
|
|
|
|
.await
|
|
|
|
.unwrap()
|
|
|
|
.is_none());
|
|
|
|
}
|
|
|
|
|
2021-08-08 21:10:40 +00:00
|
|
|
#[tokio::test]
|
|
|
|
async fn client_version() {
|
|
|
|
let provider = Provider::<Http>::try_from(
|
|
|
|
"https://rinkeby.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27",
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
// e.g., Geth/v1.10.6-omnibus-1af33248/linux-amd64/go1.16.6
|
|
|
|
assert!(provider
|
|
|
|
.client_version()
|
|
|
|
.await
|
|
|
|
.expect("Could not make web3_clientVersion call to provider")
|
|
|
|
.starts_with("Geth/v"));
|
|
|
|
}
|
|
|
|
|
2020-06-21 07:17:11 +00:00
|
|
|
// Without TLS this would error with "TLS Support not compiled in"
|
2020-12-31 17:19:14 +00:00
|
|
|
#[tokio::test]
|
|
|
|
async fn ssl_websocket() {
|
2020-06-21 07:17:11 +00:00
|
|
|
use ethers::providers::Ws;
|
2020-12-31 17:19:14 +00:00
|
|
|
let ws = Ws::connect("wss://rinkeby.infura.io/ws/v3/c60b0bb42f8a4c6481ecd229eddaca27")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
let provider = Provider::new(ws);
|
|
|
|
let _number = provider.get_block_number().await.unwrap();
|
2020-06-21 07:17:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
async fn watch_blocks_websocket() {
|
|
|
|
use ethers::{
|
2020-09-23 08:04:54 +00:00
|
|
|
providers::{StreamExt, Ws},
|
2020-06-21 07:17:11 +00:00
|
|
|
types::H256,
|
|
|
|
};
|
2020-06-17 09:22:01 +00:00
|
|
|
|
2020-06-22 13:42:34 +00:00
|
|
|
let ganache = Ganache::new().block_time(2u64).spawn();
|
2020-12-31 17:19:14 +00:00
|
|
|
let (ws, _) = tokio_tungstenite::connect_async(ganache.ws_endpoint())
|
2020-06-21 07:17:11 +00:00
|
|
|
.await
|
|
|
|
.unwrap();
|
2020-06-22 08:44:08 +00:00
|
|
|
let provider = Provider::new(Ws::new(ws)).interval(Duration::from_millis(500u64));
|
2020-06-21 07:17:11 +00:00
|
|
|
|
2020-06-22 08:44:08 +00:00
|
|
|
let stream = provider.watch_blocks().await.unwrap().stream();
|
2020-06-21 07:17:11 +00:00
|
|
|
|
|
|
|
let _blocks = stream.take(3usize).collect::<Vec<H256>>().await;
|
|
|
|
let _number = provider.get_block_number().await.unwrap();
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
async fn pending_txs_with_confirmations_ganache() {
|
2020-06-22 13:42:34 +00:00
|
|
|
let ganache = Ganache::new().block_time(2u64).spawn();
|
|
|
|
let provider = Provider::<Http>::try_from(ganache.endpoint())
|
2020-06-22 08:44:08 +00:00
|
|
|
.unwrap()
|
|
|
|
.interval(Duration::from_millis(500u64));
|
2020-12-17 09:23:10 +00:00
|
|
|
let accounts = provider.get_accounts().await.unwrap();
|
|
|
|
generic_pending_txs_test(provider, accounts[0]).await;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
async fn pending_txs_with_confirmations_testnet() {
|
|
|
|
let provider = Provider::<Http>::try_from(
|
|
|
|
"https://rinkeby.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27",
|
|
|
|
)
|
|
|
|
.unwrap();
|
2021-07-29 20:22:25 +00:00
|
|
|
let chain_id = provider.get_chainid().await.unwrap();
|
2020-12-17 09:23:10 +00:00
|
|
|
let wallet = "59c37cb6b16fa2de30675f034c8008f890f4b2696c729d6267946d29736d73e4"
|
|
|
|
.parse::<LocalWallet>()
|
2021-07-29 20:22:25 +00:00
|
|
|
.unwrap()
|
|
|
|
.with_chain_id(chain_id.as_u64());
|
2020-12-17 09:23:10 +00:00
|
|
|
let address = wallet.address();
|
|
|
|
let provider = SignerMiddleware::new(provider, wallet);
|
|
|
|
generic_pending_txs_test(provider, address).await;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
#[cfg(any(feature = "tokio-runtime", feature = "tokio-tls"))]
|
|
|
|
// different keys to avoid nonce errors
|
|
|
|
async fn websocket_pending_txs_with_confirmations_testnet() {
|
|
|
|
let provider =
|
|
|
|
Provider::connect("wss://rinkeby.infura.io/ws/v3/c60b0bb42f8a4c6481ecd229eddaca27")
|
|
|
|
.await
|
|
|
|
.unwrap();
|
2021-07-29 20:22:25 +00:00
|
|
|
let chain_id = provider.get_chainid().await.unwrap();
|
2020-12-17 09:23:10 +00:00
|
|
|
let wallet = "ff7f80c6e9941865266ed1f481263d780169f1d98269c51167d20c630a5fdc8a"
|
|
|
|
.parse::<LocalWallet>()
|
2021-07-29 20:22:25 +00:00
|
|
|
.unwrap()
|
|
|
|
.with_chain_id(chain_id.as_64());
|
2020-12-17 09:23:10 +00:00
|
|
|
let address = wallet.address();
|
|
|
|
let provider = SignerMiddleware::new(provider, wallet);
|
|
|
|
generic_pending_txs_test(provider, address).await;
|
2020-06-21 08:09:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
#[cfg(any(feature = "tokio-runtime", feature = "tokio-tls"))]
|
|
|
|
async fn websocket_pending_txs_with_confirmations_ganache() {
|
|
|
|
use ethers::providers::Ws;
|
2020-06-22 13:42:34 +00:00
|
|
|
let ganache = Ganache::new().block_time(2u64).spawn();
|
|
|
|
let ws = Ws::connect(ganache.ws_endpoint()).await.unwrap();
|
2020-06-21 08:09:19 +00:00
|
|
|
let provider = Provider::new(ws);
|
2020-06-21 07:17:11 +00:00
|
|
|
let accounts = provider.get_accounts().await.unwrap();
|
2020-12-17 09:23:10 +00:00
|
|
|
generic_pending_txs_test(provider, accounts[0]).await;
|
|
|
|
}
|
2020-06-17 08:02:03 +00:00
|
|
|
|
2020-12-17 09:23:10 +00:00
|
|
|
async fn generic_pending_txs_test<M: Middleware>(provider: M, who: ethers::types::Address) {
|
|
|
|
let tx = TransactionRequest::new().to(who).from(who);
|
2020-12-17 11:26:01 +00:00
|
|
|
let pending_tx = provider.send_transaction(tx, None).await.unwrap();
|
|
|
|
let tx_hash = *pending_tx;
|
2021-07-06 08:06:18 +00:00
|
|
|
let receipt = pending_tx.confirmations(3).await.unwrap().unwrap();
|
2020-06-21 07:17:11 +00:00
|
|
|
// got the correct receipt
|
2020-06-22 08:44:08 +00:00
|
|
|
assert_eq!(receipt.transaction_hash, tx_hash);
|
2020-06-21 07:17:11 +00:00
|
|
|
}
|
2021-08-09 00:31:11 +00:00
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
async fn typed_txs() {
|
|
|
|
use ethers_core::types::Eip1559TransactionRequest;
|
|
|
|
let provider = Provider::<Http>::try_from(
|
|
|
|
"https://rinkeby.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27",
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let chain_id = provider.get_chainid().await.unwrap();
|
2021-08-12 16:01:52 +00:00
|
|
|
let wallet = "87203087aed9246e0b2417e248752a1a0df4fdaf65085c11a2b48087ba036b41"
|
2021-08-09 00:31:11 +00:00
|
|
|
.parse::<LocalWallet>()
|
|
|
|
.unwrap()
|
|
|
|
.with_chain_id(chain_id.as_u64());
|
|
|
|
let address = wallet.address();
|
|
|
|
let provider = SignerMiddleware::new(provider, wallet);
|
|
|
|
|
|
|
|
async fn check_tx<M: Middleware>(provider: &M, tx: TypedTransaction, expected: u64) {
|
|
|
|
let receipt = provider
|
|
|
|
.send_transaction(tx, None)
|
|
|
|
.await
|
|
|
|
.unwrap()
|
|
|
|
.await
|
|
|
|
.unwrap()
|
|
|
|
.unwrap();
|
|
|
|
let tx = provider
|
|
|
|
.get_transaction(receipt.transaction_hash)
|
|
|
|
.await
|
|
|
|
.unwrap()
|
|
|
|
.unwrap();
|
|
|
|
assert_eq!(receipt.transaction_type, Some(expected.into()));
|
|
|
|
assert_eq!(tx.transaction_type, Some(expected.into()));
|
|
|
|
}
|
|
|
|
|
|
|
|
let tx: TypedTransaction = TransactionRequest::new().from(address).to(address).into();
|
|
|
|
check_tx(&provider, tx, 0).await;
|
|
|
|
|
|
|
|
let tx: TypedTransaction = TransactionRequest::new()
|
|
|
|
.from(address)
|
|
|
|
.to(address)
|
|
|
|
.with_access_list(vec![])
|
|
|
|
.into();
|
|
|
|
check_tx(&provider, tx, 1).await;
|
|
|
|
|
|
|
|
let tx: TypedTransaction = Eip1559TransactionRequest::new()
|
|
|
|
.from(address)
|
|
|
|
.to(address)
|
|
|
|
.into();
|
|
|
|
check_tx(&provider, tx, 2).await;
|
|
|
|
}
|
2021-08-19 14:01:40 +00:00
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
async fn eip1559_fee_estimation() {
|
|
|
|
let provider = Provider::<Http>::try_from(
|
|
|
|
"https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27",
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
let (_max_fee_per_gas, _max_priority_fee_per_gas) =
|
|
|
|
provider.estimate_eip1559_fees(None).await.unwrap();
|
|
|
|
}
|
2020-06-17 08:02:03 +00:00
|
|
|
}
|
2020-06-17 09:22:01 +00:00
|
|
|
|
|
|
|
#[cfg(feature = "celo")]
|
|
|
|
mod celo_tests {
|
|
|
|
use super::*;
|
2020-09-23 08:04:54 +00:00
|
|
|
use ethers::types::{Randomness, H256};
|
2020-06-17 13:09:41 +00:00
|
|
|
use futures_util::stream::StreamExt;
|
2020-06-17 09:22:01 +00:00
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
// https://alfajores-blockscout.celo-testnet.org/tx/0x544ea96cddb16aeeaedaf90885c1e02be4905f3eb43d6db3f28cac4dbe76a625/internal_transactions
|
|
|
|
async fn get_transaction() {
|
|
|
|
let provider =
|
|
|
|
Provider::<Http>::try_from("https://alfajores-forno.celo-testnet.org").unwrap();
|
|
|
|
|
2020-08-12 08:35:33 +00:00
|
|
|
let tx_hash = "c8496681d0ade783322980cce00c89419fce4b484635d9e09c79787a0f75d450"
|
2020-06-17 09:22:01 +00:00
|
|
|
.parse::<H256>()
|
|
|
|
.unwrap();
|
2020-09-17 11:06:56 +00:00
|
|
|
let tx = provider.get_transaction(tx_hash).await.unwrap().unwrap();
|
2020-06-17 09:22:01 +00:00
|
|
|
assert!(tx.gateway_fee_recipient.is_none());
|
|
|
|
assert_eq!(tx.gateway_fee.unwrap(), 0.into());
|
|
|
|
assert_eq!(tx.hash, tx_hash);
|
2020-08-12 08:35:33 +00:00
|
|
|
assert_eq!(tx.block_number.unwrap(), 447181.into())
|
2020-06-17 09:22:01 +00:00
|
|
|
}
|
2020-06-17 13:09:41 +00:00
|
|
|
|
2020-07-02 13:05:27 +00:00
|
|
|
#[tokio::test]
|
|
|
|
async fn get_block() {
|
|
|
|
let provider =
|
|
|
|
Provider::<Http>::try_from("https://alfajores-forno.celo-testnet.org").unwrap();
|
|
|
|
|
2020-09-17 11:06:56 +00:00
|
|
|
let block = provider.get_block(447254).await.unwrap().unwrap();
|
2020-07-02 13:05:27 +00:00
|
|
|
assert_eq!(
|
|
|
|
block.randomness,
|
|
|
|
Randomness {
|
2020-12-31 17:19:14 +00:00
|
|
|
committed: hex::decode(
|
|
|
|
"003e12deb86292844274493e9ab6e57ed1e276202c16799d97af723eb0d3253f"
|
|
|
|
)
|
|
|
|
.unwrap()
|
|
|
|
.into(),
|
|
|
|
revealed: hex::decode(
|
|
|
|
"1333b3b45e0385da48a01b4459aeda7607867ef6a41167cfdeefa49b9fdce6d7"
|
|
|
|
)
|
|
|
|
.unwrap()
|
|
|
|
.into(),
|
2020-07-02 13:05:27 +00:00
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-06-17 13:09:41 +00:00
|
|
|
#[tokio::test]
|
|
|
|
async fn watch_blocks() {
|
2020-06-22 08:44:08 +00:00
|
|
|
let provider = Provider::<Http>::try_from("https://alfajores-forno.celo-testnet.org")
|
2020-06-17 13:09:41 +00:00
|
|
|
.unwrap()
|
2020-06-22 08:44:08 +00:00
|
|
|
.interval(Duration::from_millis(2000u64));
|
|
|
|
|
|
|
|
let stream = provider.watch_blocks().await.unwrap().stream();
|
2020-06-17 13:09:41 +00:00
|
|
|
|
|
|
|
let _blocks = stream.take(3usize).collect::<Vec<H256>>().await;
|
|
|
|
}
|
2020-06-17 09:22:01 +00:00
|
|
|
}
|