chore: remove cyclical dependencies (#410)

* chore(core): remove ethers dep

* chore(providers): remove ethers dep

tests using higher-rank crates are temporarily disabled

* chore(middleware): remove ethers dep and move tests over from providers

* chore(signers): remove ethers dep

* fix(contracts): correctly determine ethers sub-crates & remove ethers

* fix: re-enable tests for all members

* fix: make contract compile without middleware dep

move over the test using middleware to ethers-middleware

* chore: cargo fmt

* chore(contract): add missing import

* WIP

* WIP

* fix(middleware): use rustls as dev dep

* chore: cargo fmt

* fix: use different key for nonce manager to avoid nonce conflicts

* chore: fix celo test ported over to middlewares

the test had the same private key with an existing middleware test,
causing potential nonce reuses

it now also uses a different storage contract, so we had to change
it to use u256 instead of string

* fix(middleware): enable contracts/celo feature

* chore: ignore non-eip2718 txs to rinkeby
This commit is contained in:
Georgios Konstantopoulos 2021-08-29 00:06:29 +03:00 committed by GitHub
parent 6cc20688d0
commit 38c7f5030f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 300 additions and 299 deletions

6
Cargo.lock generated
View File

@ -856,11 +856,9 @@ dependencies = [
name = "ethers-contract"
version = "0.4.7"
dependencies = [
"ethers",
"ethers-contract-abigen",
"ethers-contract-derive",
"ethers-core",
"ethers-middleware",
"ethers-providers",
"ethers-signers",
"futures-util",
@ -917,7 +915,6 @@ dependencies = [
"ecdsa",
"elliptic-curve",
"ethabi",
"ethers",
"futures-util",
"generic-array 0.14.4",
"glob",
@ -940,7 +937,6 @@ name = "ethers-middleware"
version = "0.4.8"
dependencies = [
"async-trait",
"ethers",
"ethers-contract",
"ethers-core",
"ethers-providers",
@ -967,7 +963,6 @@ dependencies = [
"async-trait",
"auto_impl",
"bytes",
"ethers",
"ethers-core",
"futures-channel",
"futures-core",
@ -1004,7 +999,6 @@ dependencies = [
"coins-ledger",
"elliptic-curve",
"eth-keystore",
"ethers",
"ethers-core",
"futures-executor",
"futures-util",

View File

@ -24,10 +24,10 @@ futures-util = { version = "0.3.16" }
hex = { version = "0.4.3", default-features = false, features = ["std"] }
[dev-dependencies]
ethers = { version = "0.4.0", path = ".." }
ethers-providers = { version = "0.4.6", path = "../ethers-providers", default-features = false, features = ["ws"] }
ethers-signers = { version = "0.4.6", path = "../ethers-signers" }
ethers-middleware = { version = "0.4.8", path = "../ethers-middleware" }
ethers-contract-abigen = { version = "0.4.7", path = "ethers-contract-abigen" }
ethers-contract-derive = { version = "0.4.7", path = "ethers-contract-derive" }
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
tokio = { version = "1.5", default-features = false, features = ["macros"] }

View File

@ -65,14 +65,14 @@ use std::{fmt::Debug, marker::PhantomData, sync::Arc};
/// interact with its methods and retrieve raw logs it has emitted.
///
/// ```no_run
/// use ethers::{
/// use ethers_core::{
/// abi::Abi,
/// utils::Solc,
/// types::{Address, H256},
/// contract::Contract,
/// providers::{Provider, Http},
/// signers::Wallet,
/// };
/// use ethers_contract::Contract;
/// use ethers_providers::{Provider, Http};
/// use ethers_signers::Wallet;
/// use std::convert::TryFrom;
///
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
@ -112,7 +112,7 @@ use std::{fmt::Debug, marker::PhantomData, sync::Arc};
/// datatypes and to have implemented `Detokenize` for it. This boilerplate code
/// is generated for you via the [`abigen`] and [`Abigen` builder] utilities.
///
/// ```no_run
/// ```ignore
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
/// use ethers_core::{abi::Abi, types::Address};
/// use ethers_contract::{Contract, EthEvent};

View File

@ -92,12 +92,10 @@ impl<M: Middleware> Deployer<M> {
/// # Example
///
/// ```no_run
/// use ethers::{
/// utils::Solc,
/// contract::ContractFactory,
/// providers::{Provider, Http},
/// signers::Wallet
/// };
/// use ethers_core::utils::Solc;
/// use ethers_contract::ContractFactory;
/// use ethers_providers::{Provider, Http};
/// use ethers_signers::Wallet;
/// use std::convert::TryFrom;
///
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {

View File

@ -44,11 +44,11 @@ pub mod builders {
pub use super::factory::Deployer;
}
#[cfg(feature = "abigen")]
#[cfg(any(test, feature = "abigen"))]
#[cfg_attr(docsrs, doc(cfg(feature = "abigen")))]
pub use ethers_contract_abigen::Abigen;
#[cfg(feature = "abigen")]
#[cfg(any(test, feature = "abigen"))]
#[cfg_attr(docsrs, doc(cfg(feature = "abigen")))]
pub use ethers_contract_derive::{abigen, EthAbiType, EthEvent};

View File

@ -63,12 +63,12 @@ pub static ADDRESS_BOOK: Lazy<HashMap<U256, Address>> = Lazy::new(|| {
/// # Example
///
/// ```no_run
/// use ethers::{
/// use ethers_core::{
/// abi::Abi,
/// contract::{Contract, Multicall},
/// providers::{Middleware, Http, Provider, PendingTransaction},
/// types::{Address, H256, U256},
/// };
/// use ethers_contract::{Contract, Multicall};
/// use ethers_providers::{Middleware, Http, Provider, PendingTransaction};
/// use std::{convert::TryFrom, sync::Arc};
///
/// # async fn bar() -> Result<(), Box<dyn std::error::Error>> {
@ -247,7 +247,9 @@ impl<M: Middleware> Multicall<M> {
///
/// ```no_run
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
/// # use ethers::{abi::Abi, prelude::*};
/// # use ethers_core::{abi::Abi, types::{Address, H256}};
/// # use ethers_providers::{Provider, Http};
/// # use ethers_contract::{Multicall, Contract};
/// # use std::{sync::Arc, convert::TryFrom};
/// #
/// # let client = Provider::<Http>::try_from("http://localhost:8545")?;
@ -290,7 +292,9 @@ impl<M: Middleware> Multicall<M> {
///
/// ```no_run
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
/// # use ethers::prelude::*;
/// # use ethers_core::types::{U256, Address};
/// # use ethers_providers::{Provider, Http};
/// # use ethers_contract::Multicall;
/// # use std::convert::TryFrom;
/// #
/// # let client = Provider::<Http>::try_from("http://localhost:8545")?;
@ -343,7 +347,8 @@ impl<M: Middleware> Multicall<M> {
///
/// ```no_run
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
/// # use ethers::prelude::*;
/// # use ethers_providers::{Provider, Http};
/// # use ethers_contract::Multicall;
/// # use std::convert::TryFrom;
/// # let client = Provider::<Http>::try_from("http://localhost:8545")?;
/// # let multicall = Multicall::new(client, None).await?;

View File

@ -1,3 +1,4 @@
#![cfg(feature = "abigen")]
//! Test cases to validate the `abigen!` macro
use ethers_contract::{abigen, EthEvent};
use ethers_core::abi::Tokenizable;

View File

@ -1,7 +1,8 @@
use ethers::core::types::{H160, H256, I256, U128, U256};
use ethers_contract::{abigen, EthAbiType, EthEvent, EthLogDecode};
use ethers_contract::EthLogDecode;
use ethers_contract::{abigen, EthAbiType, EthEvent};
use ethers_core::abi::{RawLog, Tokenizable};
use ethers_core::types::Address;
use ethers_core::types::{H160, H256, I256, U128, U256};
#[derive(Debug, Clone, PartialEq, EthAbiType)]
struct ValueChanged {

View File

@ -1,19 +1,23 @@
#![cfg(not(target_arch = "wasm32"))]
mod derive;
use ethers_core::{
abi::Abi,
types::{Address, Bytes},
};
use ethers_contract::{Contract, ContractFactory, EthEvent};
#[cfg(feature = "abigen")]
use ethers_core::types::Address;
#[cfg(feature = "abigen")]
use ethers_contract::EthEvent;
#[cfg(feature = "abigen")]
mod derive;
use ethers_contract::{Contract, ContractFactory};
use ethers_core::utils::{GanacheInstance, Solc};
use ethers_middleware::signer::SignerMiddleware;
use ethers_core::{abi::Abi, types::Bytes};
use ethers_providers::{Http, Middleware, Provider};
use ethers_signers::{LocalWallet, Signer};
use std::{convert::TryFrom, sync::Arc, time::Duration};
// Note: The `EthEvent` derive macro implements the necessary conversion between `Tokens` and
// the struct
#[cfg(feature = "abigen")]
#[derive(Clone, Debug, EthEvent)]
pub struct ValueChanged {
#[ethevent(indexed)]
@ -33,16 +37,14 @@ pub fn compile_contract(name: &str, filename: &str) -> (Abi, Bytes) {
(contract.abi.clone(), contract.bytecode.clone())
}
type HttpWallet = SignerMiddleware<Provider<Http>, LocalWallet>;
/// connects the private key to http://localhost:8545
pub fn connect(ganache: &GanacheInstance, idx: usize) -> Arc<HttpWallet> {
pub fn connect(ganache: &GanacheInstance, idx: usize) -> Arc<Provider<Http>> {
let sender = ganache.addresses()[idx];
let provider = Provider::<Http>::try_from(ganache.endpoint())
.unwrap()
.interval(Duration::from_millis(10u64));
let wallet: LocalWallet = ganache.keys()[idx].clone().into();
let wallet = wallet.with_chain_id(1u64);
Arc::new(SignerMiddleware::new(provider, wallet))
.interval(Duration::from_millis(10u64))
.with_sender(sender);
Arc::new(provider)
}
/// Launches a ganache instance and deploys the SimpleStorage contract

View File

@ -1,8 +1,5 @@
#![cfg(not(target_arch = "wasm32"))]
use ethers::{
contract::ContractFactory,
types::{Filter, ValueOrArray, H256},
};
use ethers_contract::ContractFactory;
use ethers_core::types::{Filter, ValueOrArray, H256};
mod common;
pub use common::*;
@ -10,12 +7,12 @@ pub use common::*;
#[cfg(not(feature = "celo"))]
mod eth_tests {
use super::*;
use ethers::{
contract::{LogMeta, Multicall},
providers::{Http, Middleware, PendingTransaction, Provider, StreamExt},
use ethers_contract::{LogMeta, Multicall};
use ethers_core::{
types::{Address, BlockId, U256},
utils::Ganache,
};
use ethers_providers::{Http, Middleware, PendingTransaction, Provider, StreamExt};
use std::{convert::TryFrom, sync::Arc};
#[tokio::test]
@ -27,6 +24,8 @@ mod eth_tests {
// Instantiate the clients. We assume that clients consume the provider and the wallet
// (which makes sense), so for multi-client tests, you must clone the provider.
let addrs = ganache.addresses().to_vec();
let addr2 = addrs[1];
let client = connect(&ganache, 0);
let client2 = connect(&ganache, 1);
@ -62,7 +61,7 @@ mod eth_tests {
let pending_tx = contract_call.send().await.unwrap();
let tx = client.get_transaction(*pending_tx).await.unwrap().unwrap();
let tx_receipt = pending_tx.await.unwrap().unwrap();
assert_eq!(last_sender.clone().call().await.unwrap(), client2.address());
assert_eq!(last_sender.clone().call().await.unwrap(), addr2);
assert_eq!(get_value.clone().call().await.unwrap(), "hi");
assert_eq!(tx.input, calldata);
assert_eq!(tx_receipt.gas_used.unwrap(), gas_estimate);
@ -99,10 +98,12 @@ mod eth_tests {
}
#[tokio::test]
#[cfg(feature = "abigen")]
async fn get_past_events() {
let (abi, bytecode) = compile_contract("SimpleStorage", "SimpleStorage.sol");
let ganache = Ganache::new().spawn();
let client = connect(&ganache, 0);
let address = client.get_accounts().await.unwrap()[0];
let contract = deploy(client.clone(), abi, bytecode).await;
// make a call with `client`
@ -117,7 +118,7 @@ mod eth_tests {
let logs: Vec<ValueChanged> = contract
.event()
.from_block(0u64)
.topic1(client.address()) // Corresponds to the first indexed parameter
.topic1(address) // Corresponds to the first indexed parameter
.query()
.await
.unwrap();
@ -130,7 +131,7 @@ mod eth_tests {
let logs: Vec<ValueChanged> = contract
.event()
.at_block_hash(hash)
.topic1(client.address()) // Corresponds to the first indexed parameter
.topic1(address) // Corresponds to the first indexed parameter
.query()
.await
.unwrap();
@ -139,17 +140,19 @@ mod eth_tests {
}
#[tokio::test]
#[cfg(feature = "abigen")]
async fn get_events_with_meta() {
let (abi, bytecode) = compile_contract("SimpleStorage", "SimpleStorage.sol");
let ganache = Ganache::new().spawn();
let client = connect(&ganache, 0);
let address = ganache.addresses()[0];
let contract = deploy(client.clone(), abi, bytecode).await;
// and we can fetch the events
let logs: Vec<(ValueChanged, LogMeta)> = contract
.event()
.from_block(0u64)
.topic1(client.address()) // Corresponds to the first indexed parameter
.topic1(address) // Corresponds to the first indexed parameter
.query_with_meta()
.await
.unwrap();
@ -288,6 +291,7 @@ mod eth_tests {
}
#[tokio::test]
#[cfg(feature = "abigen")]
async fn watch_events() {
let (abi, bytecode) = compile_contract("SimpleStorage", "SimpleStorage.sol");
let ganache = Ganache::new().spawn();
@ -436,6 +440,9 @@ mod eth_tests {
// `client2` is used to deploy the first SimpleStorage contract
// `client3` is used to deploy the second SimpleStorage contract
// `client4` is used to make the aggregate call
let addrs = ganache.addresses().to_vec();
let addr2 = addrs[1];
let addr3 = addrs[2];
let client = connect(&ganache, 0);
let client2 = connect(&ganache, 1);
let client3 = connect(&ganache, 2);
@ -516,9 +523,9 @@ mod eth_tests {
assert_eq!(return_data.0, "reset first");
assert_eq!((return_data.1).0, "reset second");
assert_eq!((return_data.1).1, client3.address());
assert_eq!(return_data.2, client2.address());
assert_eq!(return_data.3, client3.address());
assert_eq!((return_data.1).1, addr3);
assert_eq!(return_data.2, addr2);
assert_eq!(return_data.3, addr3);
// construct broadcast transactions that will be batched and broadcast via Multicall
let broadcast = simple_contract
@ -574,68 +581,3 @@ mod eth_tests {
assert_eq!(balances.2, U256::from(100000000000000000000u128));
}
}
#[cfg(feature = "celo")]
mod celo_tests {
use super::*;
use ethers::{
middleware::signer::SignerMiddleware,
providers::{Http, Middleware, Provider},
signers::{LocalWallet, Signer},
types::BlockNumber,
};
use std::{convert::TryFrom, sync::Arc, time::Duration};
#[tokio::test]
async fn deploy_and_call_contract() {
let (abi, bytecode) = compile_contract("SimpleStorage", "SimpleStorage.sol");
// Celo testnet
let provider = Provider::<Http>::try_from("https://alfajores-forno.celo-testnet.org")
.unwrap()
.interval(Duration::from_millis(6000));
let chain_id = provider.get_chainid().await.unwrap().as_u64();
// Funded with https://celo.org/developers/faucet
let wallet = "d652abb81e8c686edba621a895531b1f291289b63b5ef09a94f686a5ecdd5db1"
.parse::<LocalWallet>()
.unwrap()
.with_chain_id(chain_id);
let client = SignerMiddleware::new(provider, wallet);
let client = Arc::new(client);
let factory = ContractFactory::new(abi, bytecode, client);
let deployer = factory
.deploy("initial value".to_string())
.unwrap()
.legacy();
let contract = deployer.block(BlockNumber::Pending).send().await.unwrap();
let value: String = contract
.method("getValue", ())
.unwrap()
.call()
.await
.unwrap();
assert_eq!(value, "initial value");
// make a state mutating transaction
// gas estimation costs are sometimes under-reported on celo,
// so we manually set it to avoid failures
let call = contract
.method::<_, H256>("setValue", "hi".to_owned())
.unwrap()
.gas(100000);
let pending_tx = call.send().await.unwrap();
let _receipt = pending_tx.await.unwrap();
let value: String = contract
.method("getValue", ())
.unwrap()
.call()
.await
.unwrap();
assert_eq!(value, "hi");
}
}

View File

@ -37,8 +37,6 @@ tokio = { version = "1.5", default-features = false, optional = true}
futures-util = { version = "0.3.16", optional = true }
[dev-dependencies]
ethers = { version = "0.4.0", path = ".." }
serde_json = { version = "1.0.64", default-features = false }
bincode = { version = "1.3.3", default-features = false }
once_cell = { version = "1.8.0" }

View File

@ -21,7 +21,7 @@ impl AbiParser {
/// # Example
///
/// ```
/// # use ethers::abi::AbiParser;
/// # use ethers_core::abi::AbiParser;
/// let abi = AbiParser::default().parse_str(r#"[
/// function setValue(string)
/// function getValue() external view returns (string)
@ -42,7 +42,7 @@ impl AbiParser {
///
/// # Example
/// ```
/// use ethers::abi::AbiParser;
/// use ethers_core::abi::AbiParser;
///
/// let abi = AbiParser::default().parse(&[
/// "function x() external view returns (uint256)",
@ -377,7 +377,7 @@ impl Default for AbiParser {
/// Parses a "human readable abi" string vector
///
/// ```
/// use ethers::abi::parse_abi;
/// use ethers_core::abi::parse_abi;
///
/// let abi = parse_abi(&[
/// "function x() external view returns (uint256)",

View File

@ -225,7 +225,7 @@ impl SolStruct {
/// # Example
///
/// ```
/// # use ethers::abi::SolStruct;
/// # use ethers_core::abi::SolStruct;
/// let s = SolStruct::parse("struct MyStruct { uint x; uint y;}").unwrap();
/// ```
pub fn parse(s: &str) -> Result<Self> {

View File

@ -12,7 +12,7 @@
//! `"\x19Ethereum Signed Message:\n" + message.length`, and then
//! signing the hash of the result.
//!
//! ```rust
//! ```rust,ignore
//! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
//! use ethers::signers::{Signer, LocalWallet};
//!

View File

@ -254,7 +254,7 @@ impl Filter {
/// Match only a specific block
///
/// ```rust
/// # use ethers::types::Filter;
/// # use ethers_core::types::Filter;
/// # fn main() {
/// let filter = Filter::new().select(69u64);
/// # }
@ -264,7 +264,7 @@ impl Filter {
/// Match the latest block only
///
/// ```rust
/// # use ethers::types::{Filter, BlockNumber};
/// # use ethers_core::types::{Filter, BlockNumber};
/// # fn main() {
/// let filter = Filter::new().select(BlockNumber::Latest);
/// # }
@ -273,7 +273,7 @@ impl Filter {
/// Match a block by its hash
///
/// ```rust
/// # use ethers::types::{Filter, H256};
/// # use ethers_core::types::{Filter, H256};
/// # fn main() {
/// let filter = Filter::new().select(H256::zero());
/// # }
@ -283,7 +283,7 @@ impl Filter {
/// Match a range of blocks
///
/// ```rust
/// # use ethers::types::{Filter, H256};
/// # use ethers_core::types::{Filter, H256};
/// # fn main() {
/// let filter = Filter::new().select(0u64..100u64);
/// # }
@ -292,7 +292,7 @@ impl Filter {
/// Match all blocks in range `(1337..BlockNumber::Latest)`
///
/// ```rust
/// # use ethers::types::{Filter, H256};
/// # use ethers_core::types::{Filter, H256};
/// # fn main() {
/// let filter = Filter::new().select(1337u64..);
/// # }
@ -301,7 +301,7 @@ impl Filter {
/// Match all blocks in range `(BlockNumber::Earliest..1337)`
///
/// ```rust
/// # use ethers::types::{Filter, H256};
/// # use ethers_core::types::{Filter, H256};
/// # fn main() {
/// let filter = Filter::new().select(..1337u64);
/// # }

View File

@ -64,7 +64,7 @@ impl Drop for GanacheInstance {
/// # Example
///
/// ```no_run
/// use ethers::utils::Ganache;
/// use ethers_core::utils::Ganache;
///
/// let port = 8545u16;
/// let url = format!("http://localhost:{}", port).to_string();

View File

@ -60,7 +60,7 @@ impl Drop for GethInstance {
/// # Example
///
/// ```no_run
/// use ethers::utils::Geth;
/// use ethers_core::utils::Geth;
///
/// let port = 8545u16;
/// let url = format!("http://localhost:{}", port).to_string();

View File

@ -79,7 +79,7 @@ pub fn format_units<T: Into<U256>, K: Into<Units>>(amount: T, units: K) -> U256
/// Converts the input to a U256 and converts from Ether to Wei.
///
/// ```
/// use ethers::{types::U256, utils::{parse_ether, WEI_IN_ETHER}};
/// use ethers_core::{types::U256, utils::{parse_ether, WEI_IN_ETHER}};
///
/// let eth = U256::from(WEI_IN_ETHER);
/// assert_eq!(eth, parse_ether(1u8).unwrap());

View File

@ -40,7 +40,7 @@ pub struct CompiledContract {
/// # Examples
///
/// ```no_run
/// use ethers::utils::Solc;
/// use ethers_core::utils::Solc;
///
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// // Give it a glob

View File

@ -38,12 +38,12 @@ instant = {version = "0.1.10", features = ["now"] }
tokio = { version = "1.5" }
[dev-dependencies]
ethers = { version = "0.4.0", path = ".." }
hex = { version = "0.4.3", default-features = false, features = ["std"] }
rand = { version = "0.8.4", default-features = false }
ethers-providers = { version = "0.4.6", path = "../ethers-providers", default-features = false, features = ["ws", "rustls"] }
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
tokio = { version = "1.5", default-features = false, features = ["rt", "macros", "time"] }
[features]
celo = ["ethers-core/celo", "ethers-providers/celo", "ethers-signers/celo"]
celo = ["ethers-core/celo", "ethers-providers/celo", "ethers-signers/celo", "ethers-contract/celo"]

View File

@ -44,12 +44,10 @@ pub enum Frequency {
/// stuck in the memory pool.
///
/// ```no_run
/// use ethers::{
/// providers::{Provider, Http},
/// middleware::{
/// gas_escalator::{GeometricGasPrice, Frequency, GasEscalatorMiddleware},
/// gas_oracle::{GasNow, GasCategory, GasOracleMiddleware},
/// },
/// use ethers_providers::{Provider, Http};
/// use ethers_middleware::{
/// gas_escalator::{GeometricGasPrice, Frequency, GasEscalatorMiddleware},
/// gas_oracle::{GasNow, GasCategory, GasOracleMiddleware},
/// };
/// use std::{convert::TryFrom, time::Duration, sync::Arc};
///

View File

@ -52,7 +52,7 @@ pub enum GasOracleError {
/// # Example
///
/// ```no_run
/// use ethers::middleware::{
/// use ethers_middleware::{
/// gas_oracle::{EthGasStation, Etherscan, GasCategory, GasOracle},
/// };
///
@ -73,7 +73,7 @@ pub trait GasOracle: Send + Sync + std::fmt::Debug {
/// # Example
///
/// ```
/// use ethers::middleware::{
/// use ethers_middleware::{
/// gas_oracle::{Etherchain, GasCategory, GasOracle},
/// };
///

View File

@ -19,17 +19,15 @@
//! ## Example of a middleware stack
//!
//! ```no_run
//! use ethers::{
//! providers::{Provider, Http},
//! signers::{LocalWallet, Signer},
//! middleware::{
//! gas_escalator::{GasEscalatorMiddleware, GeometricGasPrice, Frequency},
//! gas_oracle::{GasOracleMiddleware, GasNow, GasCategory},
//! signer::SignerMiddleware,
//! nonce_manager::NonceManagerMiddleware,
//! },
//! core::rand,
//! use ethers_providers::{Provider, Http};
//! use ethers_signers::{LocalWallet, Signer};
//! use ethers_middleware::{
//! gas_escalator::{GasEscalatorMiddleware, GeometricGasPrice, Frequency},
//! gas_oracle::{GasOracleMiddleware, GasNow, GasCategory},
//! signer::SignerMiddleware,
//! nonce_manager::NonceManagerMiddleware,
//! };
//! use ethers_core::rand;
//! use std::convert::TryFrom;
//!
//! // Start the stack

View File

@ -14,12 +14,10 @@ use thiserror::Error;
/// # Example
///
/// ```no_run
/// use ethers::{
/// providers::{Middleware, Provider, Http},
/// signers::LocalWallet,
/// middleware::SignerMiddleware,
/// types::{Address, TransactionRequest},
/// };
/// use ethers_providers::{Middleware, Provider, Http};
/// use ethers_signers::LocalWallet;
/// use ethers_middleware::SignerMiddleware;
/// use ethers_core::types::{Address, TransactionRequest};
/// use std::convert::TryFrom;
///
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
@ -250,11 +248,12 @@ where
#[cfg(all(test, not(feature = "celo"), not(target_arch = "wasm32")))]
mod tests {
use super::*;
use ethers::{providers::Provider, signers::LocalWallet};
use ethers_core::{
types::TransactionRequest,
utils::{self, keccak256, Ganache},
};
use ethers_providers::Provider;
use ethers_signers::LocalWallet;
use std::convert::TryFrom;
#[tokio::test]

View File

@ -22,10 +22,10 @@ const DS_PROXY_EXECUTE_CODE: &str =
/// # Example
///
/// ```no_run
/// use ethers::{
/// middleware::transformer::DsProxy,
/// prelude::*,
/// };
/// use ethers_middleware::{SignerMiddleware, transformer::DsProxy};
/// use ethers_signers::LocalWallet;
/// use ethers_providers::{Provider, Http};
/// use ethers_core::types::{Address, Bytes};
/// use std::{convert::TryFrom, sync::Arc};
///
/// type HttpWallet = SignerMiddleware<Provider<Http>, LocalWallet>;

View File

@ -15,7 +15,7 @@ async fn nonce_manager() {
.interval(Duration::from_millis(2000u64));
let chain_id = provider.get_chainid().await.unwrap().as_u64();
let wallet = "59c37cb6b16fa2de30675f034c8008f890f4b2696c729d6267946d29736d73e4"
let wallet = "fa4a1a79e869a96fcb42727f75e3232d6865a82ea675bb95de967a7fe6a773b2"
.parse::<LocalWallet>()
.unwrap()
.with_chain_id(chain_id);

View File

@ -1,4 +1,3 @@
#![cfg(not(target_arch = "wasm32"))]
use ethers_providers::{Http, Middleware, Provider};
use ethers_core::types::TransactionRequest;
@ -44,6 +43,106 @@ async fn send_eth() {
assert!(balance_before > balance_after);
}
#[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 chain_id = provider.get_chainid().await.unwrap();
let wallet = "59c37cb6b16fa2de30675f034c8008f890f4b2696c729d6267946d29736d73e4"
.parse::<LocalWallet>()
.unwrap()
.with_chain_id(chain_id.as_u64());
let address = wallet.address();
let provider = SignerMiddleware::new(provider, wallet);
generic_pending_txs_test(provider, address).await;
}
#[cfg(not(feature = "celo"))]
use ethers_core::types::{
transaction::eip2718::TypedTransaction, Address, Eip1559TransactionRequest,
};
// different keys to avoid nonce errors
#[tokio::test]
#[cfg(not(feature = "celo"))]
async fn websocket_pending_txs_with_confirmations_testnet() {
let provider =
Provider::connect("wss://rinkeby.infura.io/ws/v3/c60b0bb42f8a4c6481ecd229eddaca27")
.await
.unwrap()
.interval(Duration::from_millis(3000));
let chain_id = provider.get_chainid().await.unwrap();
let wallet = "ff7f80c6e9941865266ed1f481263d780169f1d98269c51167d20c630a5fdc8a"
.parse::<LocalWallet>()
.unwrap()
.with_chain_id(chain_id.as_u64());
let address = wallet.address();
let provider = SignerMiddleware::new(provider, wallet);
generic_pending_txs_test(provider, address).await;
}
#[cfg(not(feature = "celo"))]
async fn generic_pending_txs_test<M: Middleware>(provider: M, who: Address) {
let tx = TransactionRequest::new().to(who).from(who);
let pending_tx = provider.send_transaction(tx, None).await.unwrap();
let tx_hash = *pending_tx;
let receipt = pending_tx.confirmations(3).await.unwrap().unwrap();
// got the correct receipt
assert_eq!(receipt.transaction_hash, tx_hash);
}
#[tokio::test]
#[cfg(not(feature = "celo"))]
async fn typed_txs() {
let provider =
Provider::<Http>::try_from("https://rinkeby.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27")
.unwrap();
let chain_id = provider.get_chainid().await.unwrap();
let wallet = "87203087aed9246e0b2417e248752a1a0df4fdaf65085c11a2b48087ba036b41"
.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;
}
#[tokio::test]
#[cfg(feature = "celo")]
async fn test_send_transaction() {
@ -144,3 +243,60 @@ async fn send_transaction_handles_tx_from_field() {
assert_eq!(sent_tx.from, other.address());
}
#[tokio::test]
#[cfg(feature = "celo")]
async fn deploy_and_call_contract() {
use ethers_contract::ContractFactory;
use ethers_core::{
abi::Abi,
types::{BlockNumber, Bytes, H256, U256},
utils::Solc,
};
use std::sync::Arc;
fn compile_contract(name: &str, filename: &str) -> (Abi, Bytes) {
let compiled = Solc::new(&format!("./tests/solidity-contracts/{}", filename))
.build()
.unwrap();
let contract = compiled.get(name).expect("could not find contract");
(contract.abi.clone(), contract.bytecode.clone())
}
let (abi, bytecode) = compile_contract("SimpleStorage", "SimpleStorage.sol");
// Celo testnet
let provider = Provider::<Http>::try_from("https://alfajores-forno.celo-testnet.org")
.unwrap()
.interval(Duration::from_millis(6000));
let chain_id = provider.get_chainid().await.unwrap().as_u64();
// Funded with https://celo.org/developers/faucet
let wallet = "58ea5643a78c36926ad5128a6b0d8dfcc7fc705788a993b1c724be3469bc9697"
.parse::<LocalWallet>()
.unwrap()
.with_chain_id(chain_id);
let client = SignerMiddleware::new(provider, wallet);
let client = Arc::new(client);
let factory = ContractFactory::new(abi, bytecode, client);
let deployer = factory.deploy(()).unwrap().legacy();
let contract = deployer.block(BlockNumber::Pending).send().await.unwrap();
let value: U256 = contract.method("value", ()).unwrap().call().await.unwrap();
assert_eq!(value, 0.into());
// make a state mutating transaction
// gas estimation costs are sometimes under-reported on celo,
// so we manually set it to avoid failures
let call = contract
.method::<_, H256>("setValue", U256::from(1))
.unwrap()
.gas(100000);
let pending_tx = call.send().await.unwrap();
let _receipt = pending_tx.await.unwrap();
let value: U256 = contract.method("value", ()).unwrap().call().await.unwrap();
assert_eq!(value, 1.into());
}

View File

@ -53,9 +53,6 @@ wasm-timer = "0.2"
# this is currently necessary for `wasm-timer::Delay` to work
parking_lot = { version = "0.11", features = ["wasm-bindgen"] }
[dev-dependencies]
ethers = { version = "0.4.0", path = ".." }
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
tokio = { version = "1.5", default-features = false, features = ["rt", "macros"] }
tempfile = "3.2.0"

View File

@ -12,7 +12,7 @@
//! # Examples
//!
//! ```no_run
//! use ethers::providers::{Provider, Http, Middleware};
//! use ethers_providers::{Provider, Http, Middleware};
//! use std::convert::TryFrom;
//!
//! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
@ -35,7 +35,7 @@
//!
//! ```
//! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
//! # use ethers::providers::Ws;
//! # use ethers_providers::Ws;
//! let ws = Ws::connect("ws://localhost:8545").await?;
//! # Ok(())
//! # }
@ -47,7 +47,7 @@
//! to addresses (and vice versa). The default ENS address is [mainnet](https://etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e) and can be overriden by calling the [`ens`](method@crate::Provider::ens) method on the provider.
//!
//! ```no_run
//! # use ethers::providers::{Provider, Http, Middleware};
//! # use ethers_providers::{Provider, Http, Middleware};
//! # use std::convert::TryFrom;
//! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
//! # let provider = Provider::<Http>::try_from(
@ -137,7 +137,8 @@ where
/// 3. implementing any of the methods you want to override
///
/// ```rust
/// use ethers::{providers::{Middleware, FromErr}, types::{U64, TransactionRequest, U256, transaction::eip2718::TypedTransaction}};
/// use ethers_providers::{Middleware, FromErr};
/// use ethers_core::types::{U64, TransactionRequest, U256, transaction::eip2718::TypedTransaction};
/// use thiserror::Error;
/// use async_trait::async_trait;
///

View File

@ -38,7 +38,7 @@ use tracing_futures::Instrument;
///
/// ```no_run
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
/// use ethers::providers::{Middleware, Provider, Http};
/// use ethers_providers::{Middleware, Provider, Http};
/// use std::convert::TryFrom;
///
/// let provider = Provider::<Http>::try_from(
@ -905,7 +905,8 @@ impl Provider<MockProvider> {
///
/// ```
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
/// use ethers::{types::U64, providers::{Middleware, Provider}};
/// use ethers_core::types::U64;
/// use ethers_providers::{Middleware, Provider};
/// // Instantiate the provider
/// let (provider, mock) = Provider::mocked();
/// // Push the mock response

View File

@ -18,7 +18,8 @@ use super::common::{JsonRpcError, Request, Response};
/// # Example
///
/// ```no_run
/// use ethers::{types::U64, providers::{JsonRpcClient, Http}};
/// use ethers_core::types::U64;
/// use ethers_providers::{JsonRpcClient, Http};
/// use std::str::FromStr;
///
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
@ -95,7 +96,7 @@ impl Provider {
/// # Example
///
/// ```
/// use ethers::providers::Http;
/// use ethers_providers::Http;
/// use url::Url;
///
/// let url = Url::parse("http://localhost:8545").unwrap();

View File

@ -338,8 +338,7 @@ impl From<IpcError> for ProviderError {
#[cfg(not(feature = "celo"))]
mod test {
use super::*;
use ethers::utils::Geth;
use ethers_core::types::{Block, TxHash, U256};
use ethers_core::{utils::Geth, types::{Block, TxHash, U256}};
use tempfile::NamedTempFile;
#[tokio::test]

View File

@ -1,5 +1,7 @@
mod common;
// only used with WS
#[cfg(feature = "ws")]
macro_rules! if_wasm {
($($item:item)*) => {$(
#[cfg(target_arch = "wasm32")]

View File

@ -91,7 +91,7 @@ enum Incoming {
///
/// ```no_run
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
/// use ethers::providers::Ws;
/// use ethers_providers::Ws;
///
/// let ws = Ws::connect("wss://localhost:8545").await?;
/// # Ok(())

View File

@ -1,15 +1,12 @@
#![cfg(not(target_arch = "wasm32"))]
use ethers::providers::{Http, Middleware, Provider};
use ethers_providers::{Http, Middleware, Provider};
use std::{convert::TryFrom, time::Duration};
#[cfg(not(feature = "celo"))]
mod eth_tests {
use super::*;
use ethers::{
middleware::SignerMiddleware,
prelude::transaction::eip2718::TypedTransaction,
signers::{LocalWallet, Signer},
types::{BlockId, TransactionRequest, H256},
use ethers_core::{
types::{Address, BlockId, TransactionRequest, H256},
utils::Ganache,
};
@ -60,7 +57,7 @@ mod eth_tests {
// Without TLS this would error with "TLS Support not compiled in"
#[tokio::test]
async fn ssl_websocket() {
use ethers::providers::Ws;
use ethers_providers::Ws;
let ws = Ws::connect("wss://rinkeby.infura.io/ws/v3/c60b0bb42f8a4c6481ecd229eddaca27")
.await
.unwrap();
@ -70,10 +67,8 @@ mod eth_tests {
#[tokio::test]
async fn watch_blocks_websocket() {
use ethers::{
providers::{StreamExt, Ws},
types::H256,
};
use ethers_core::types::H256;
use ethers_providers::{StreamExt, Ws};
let ganache = Ganache::new().block_time(2u64).spawn();
let (ws, _) = tokio_tungstenite::connect_async(ganache.ws_endpoint())
@ -98,43 +93,8 @@ mod eth_tests {
}
#[tokio::test]
async fn pending_txs_with_confirmations_testnet() {
let provider = Provider::<Http>::try_from(
"https://rinkeby.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27",
)
.unwrap();
let chain_id = provider.get_chainid().await.unwrap();
let wallet = "59c37cb6b16fa2de30675f034c8008f890f4b2696c729d6267946d29736d73e4"
.parse::<LocalWallet>()
.unwrap()
.with_chain_id(chain_id.as_u64());
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();
let chain_id = provider.get_chainid().await.unwrap();
let wallet = "ff7f80c6e9941865266ed1f481263d780169f1d98269c51167d20c630a5fdc8a"
.parse::<LocalWallet>()
.unwrap()
.with_chain_id(chain_id.as_64());
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"))]
async fn websocket_pending_txs_with_confirmations_ganache() {
use ethers::providers::Ws;
use ethers_providers::Ws;
let ganache = Ganache::new().block_time(2u64).spawn();
let ws = Ws::connect(ganache.ws_endpoint()).await.unwrap();
let provider = Provider::new(ws);
@ -142,7 +102,7 @@ mod eth_tests {
generic_pending_txs_test(provider, accounts[0]).await;
}
async fn generic_pending_txs_test<M: Middleware>(provider: M, who: ethers::types::Address) {
async fn generic_pending_txs_test<M: Middleware>(provider: M, who: Address) {
let tx = TransactionRequest::new().to(who).from(who);
let pending_tx = provider.send_transaction(tx, None).await.unwrap();
let tx_hash = *pending_tx;
@ -151,56 +111,6 @@ mod eth_tests {
assert_eq!(receipt.transaction_hash, tx_hash);
}
#[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();
let wallet = "87203087aed9246e0b2417e248752a1a0df4fdaf65085c11a2b48087ba036b41"
.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;
}
#[tokio::test]
async fn eip1559_fee_estimation() {
let provider = Provider::<Http>::try_from(
@ -216,7 +126,7 @@ mod eth_tests {
#[cfg(feature = "celo")]
mod celo_tests {
use super::*;
use ethers::types::{Randomness, H256};
use ethers_core::types::{Randomness, H256};
use futures_util::stream::StreamExt;
#[tokio::test]

View File

@ -1,9 +1,9 @@
#![cfg(not(target_arch = "wasm32"))]
use ethers::{
providers::{Http, Middleware, Provider},
types::TransactionRequest,
use ethers_core::{
types::{TransactionRequest, U256},
utils::Geth,
};
use ethers_providers::{Http, Middleware, Provider};
use std::convert::TryFrom;
#[tokio::test]
@ -13,7 +13,7 @@ async fn txpool() {
let account = provider.get_accounts().await.unwrap()[0];
let value: u64 = 42;
let gas_price = ethers::types::U256::from_dec_str("221435145689").unwrap();
let gas_price = U256::from_dec_str("221435145689").unwrap();
let mut tx = TransactionRequest::new()
.to(account)
.from(account)

View File

@ -39,13 +39,12 @@ spki = { version = "0.4.0", optional = true }
eth-keystore = { version = "0.3.0" }
[dev-dependencies]
ethers = { version = "0.4.0", path = ".." }
tracing-subscriber = "0.2.20"
yubihsm = { version = "0.39.0", features = ["secp256k1", "usb", "mockhsm"] }
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
yubihsm = { version = "0.39.0", features = ["secp256k1", "usb", "mockhsm"] }
tokio = { version = "1.5", default-features = false, features = ["macros"] }
tokio = { version = "1.5", default-features = false, features = ["macros", "rt"] }
tempfile = "3.2.0"
[features]

View File

@ -35,7 +35,7 @@ impl LedgerEthereum {
///
/// ```
/// # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
/// use ethers::signers::{Ledger, HDPath};
/// use ethers_signers::{Ledger, HDPath};
///
/// let ledger = Ledger::new(HDPath::LedgerLive(0), 1).await?;
/// # Ok(())
@ -200,7 +200,7 @@ impl LedgerEthereum {
mod tests {
use super::*;
use crate::Signer;
use ethers::prelude::*;
use ethers_core::types::{Address, TransactionRequest};
use std::str::FromStr;
#[tokio::test]

View File

@ -13,10 +13,9 @@
//! - [AWS KMS](crate::AwsSigner)
//!
//! ```no_run
//! # use ethers::{
//! # signers::{LocalWallet, Signer},
//! # core::{k256::ecdsa::SigningKey, types::TransactionRequest},
//! # };
//! # use ethers_signers::{LocalWallet, Signer};
//! # use ethers_core::{k256::ecdsa::SigningKey, types::TransactionRequest};
//!
//! # async fn foo() -> Result<(), Box<dyn std::error::Error>> {
//! // instantiate the wallet
//! let wallet = "dcf2cbdd171a21c480aa7f53d77f31bb102282b3ff099c78e3118b37348c72f7"