Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

feat: Relax Clone requirements when Arc<M> is used #1183

Merged
merged 1 commit into from
Apr 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@

### Unreleased

- Relax Clone requirements when Arc<Middleware> is used
[#1183](https://github.com/gakonst/ethers-rs/pull/1183)
- Generate a deploy function if bytecode is provided in the abigen! input (json artifact)
[#1030](https://github.com/gakonst/ethers-rs/pull/1030).
- Generate correct bindings of struct's field names that are reserved words
Expand Down Expand Up @@ -192,6 +194,8 @@

### Unreleased

- Relax Clone requirements when Arc<Middleware> is used
[#1183](https://github.com/gakonst/ethers-rs/pull/1183)
- Add `EventStream::select` to combine streams with different event types
[#725](https://github.com/gakonst/ethers-rs/pull/725)
- Substitute output tuples with rust struct types for function calls
Expand Down Expand Up @@ -235,6 +239,8 @@

### Unreleased

- Relax Clone requirements when Arc<Middleware> is used
[#1183](https://github.com/gakonst/ethers-rs/pull/1183)
- Ensure a consistent chain ID between a Signer and Provider in SignerMiddleware
[#1095](https://gakonst/ethers-rs/pull/1095)
- Add BlockNative gas oracle [#1175](https://github.com/gakonst/ethers-rs/pull/1175)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,13 @@ pub(crate) fn struct_declaration(cx: &Context) -> TokenStream {
#bytecode

// Struct declaration
#[derive(Clone)]
pub struct #name<M>(#ethers_contract::Contract<M>);

impl<M> Clone for #name<M> {
fn clone(&self) -> Self {
#name(self.0.clone())
}
}

// Deref to the inner contract in order to access more specific functions functions
impl<M> std::ops::Deref for #name<M> {
Expand Down
14 changes: 13 additions & 1 deletion ethers-contract/src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub enum ContractError<M: Middleware> {
ContractNotDeployed,
}

#[derive(Debug, Clone)]
#[derive(Debug)]
#[must_use = "contract calls do nothing unless you `send` or `call` them"]
/// Helper for managing a transaction before submitting it to a node
pub struct ContractCall<M, D> {
Expand All @@ -77,6 +77,18 @@ pub struct ContractCall<M, D> {
pub(crate) datatype: PhantomData<D>,
}

impl<M, D> Clone for ContractCall<M, D> {
fn clone(&self) -> Self {
ContractCall {
tx: self.tx.clone(),
function: self.function.clone(),
block: self.block,
client: self.client.clone(),
datatype: self.datatype,
}
}
}

impl<M, D: Detokenize> ContractCall<M, D> {
/// Sets the `from` field in the transaction to the provided value
pub fn from<T: Into<Address>>(mut self, from: T) -> Self {
Expand Down
12 changes: 11 additions & 1 deletion ethers-contract/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,23 @@ use std::{fmt::Debug, marker::PhantomData, sync::Arc};
/// [`Abigen` builder]: crate::Abigen
/// [`event`]: method@crate::Contract::event
/// [`method`]: method@crate::Contract::method
#[derive(Debug, Clone)]
#[derive(Debug)]
pub struct Contract<M> {
base_contract: BaseContract,
client: Arc<M>,
address: Address,
}

impl<M> Clone for Contract<M> {
fn clone(&self) -> Self {
Contract {
base_contract: self.base_contract.clone(),
client: self.client.clone(),
address: self.address,
}
}
}

impl<M: Middleware> Contract<M> {
/// Creates a new contract from the provided client, abi and address
pub fn new(address: Address, abi: impl Into<BaseContract>, client: impl Into<Arc<M>>) -> Self {
Expand Down
34 changes: 31 additions & 3 deletions ethers-contract/src/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use std::sync::Arc;
///
/// This is just a wrapper type for [Deployer] with an additional type to convert the [Contract]
/// that the deployer returns when sending the transaction.
#[derive(Debug, Clone)]
#[derive(Debug)]
#[must_use = "Deployer does nothing unless you `send` it"]
pub struct ContractDeployer<M, C> {
/// the actual deployer, exposed for overriding the defaults
Expand All @@ -30,6 +30,12 @@ pub struct ContractDeployer<M, C> {
_contract: PhantomData<C>,
}

impl<M, C> Clone for ContractDeployer<M, C> {
fn clone(&self) -> Self {
ContractDeployer { deployer: self.deployer.clone(), _contract: self._contract }
}
}

impl<M: Middleware, C: From<Contract<M>>> ContractDeployer<M, C> {
/// Create a new instance of this [ContractDeployer]
pub fn new(deployer: Deployer<M>) -> Self {
Expand Down Expand Up @@ -89,7 +95,7 @@ impl<M: Middleware, C: From<Contract<M>>> ContractDeployer<M, C> {
}

/// Helper which manages the deployment transaction of a smart contract
#[derive(Debug, Clone)]
#[derive(Debug)]
#[must_use = "Deployer does nothing unless you `send` it"]
pub struct Deployer<M> {
/// The deployer's transaction, exposed for overriding the defaults
Expand All @@ -100,6 +106,18 @@ pub struct Deployer<M> {
block: BlockNumber,
}

impl<M> Clone for Deployer<M> {
fn clone(&self) -> Self {
Deployer {
tx: self.tx.clone(),
abi: self.abi.clone(),
client: self.client.clone(),
confs: self.confs,
block: self.block,
}
}
}

impl<M: Middleware> Deployer<M> {
/// Sets the number of confirmations to wait for the contract deployment transaction
pub fn confirmations<T: Into<usize>>(mut self, confirmations: T) -> Self {
Expand Down Expand Up @@ -222,13 +240,23 @@ impl<M: Middleware> Deployer<M> {
/// println!("{}", contract.address());
/// # Ok(())
/// # }
#[derive(Debug, Clone)]
#[derive(Debug)]
pub struct ContractFactory<M> {
client: Arc<M>,
abi: Abi,
bytecode: Bytes,
}

impl<M> Clone for ContractFactory<M> {
fn clone(&self) -> Self {
ContractFactory {
client: self.client.clone(),
abi: self.abi.clone(),
bytecode: self.bytecode.clone(),
}
}
}

impl<M: Middleware> ContractFactory<M> {
/// Creates a factory for deployment of the Contract with bytecode, and the
/// constructor defined in the abi. The client will be used to send any deployment
Expand Down
12 changes: 11 additions & 1 deletion ethers-contract/src/multicall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,14 +120,24 @@ pub static ADDRESS_BOOK: Lazy<HashMap<U256, Address>> = Lazy::new(|| {
/// [`new`]: method@crate::Multicall::new
/// [`block`]: method@crate::Multicall::block
/// [`add_call`]: method@crate::Multicall::add_call
#[derive(Clone)]
pub struct Multicall<M> {
calls: Vec<Call>,
block: Option<BlockNumber>,
contract: MulticallContract<M>,
legacy: bool,
}

impl<M> Clone for Multicall<M> {
fn clone(&self) -> Self {
Multicall {
calls: self.calls.clone(),
block: self.block,
contract: self.contract.clone(),
legacy: self.legacy,
}
}
}

#[derive(Clone)]
/// Helper struct for managing calls to be made to the `function` in smart contract `target`
/// with `data`
Expand Down
6 changes: 5 additions & 1 deletion ethers-contract/src/multicall/multicall_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ mod multicallcontract_mod {
pub static MULTICALLCONTRACT_ABI: Lazy<Abi> = Lazy::new(|| {
serde_json :: from_str ( "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct MulticallContract.Call[]\",\"name\":\"calls\",\"type\":\"tuple[]\"}],\"name\":\"aggregate\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bytes[]\",\"name\":\"returnData\",\"type\":\"bytes[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"getBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockCoinbase\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"coinbase\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockDifficulty\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"difficulty\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockGasLimit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"gaslimit\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getCurrentBlockTimestamp\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"getEthBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"balance\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLastBlockHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"blockHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]" ) . expect ( "invalid abi" )
});
#[derive(Clone)]
pub struct MulticallContract<M>(Contract<M>);
impl<M> Clone for MulticallContract<M> {
fn clone(&self) -> Self {
MulticallContract(self.0.clone())
}
}
impl<M> std::ops::Deref for MulticallContract<M> {
type Target = Contract<M>;
fn deref(&self) -> &Self::Target {
Expand Down
13 changes: 12 additions & 1 deletion ethers-middleware/src/gas_escalator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub enum Frequency {
Duration(u64),
}

#[derive(Debug, Clone)]
#[derive(Debug)]
/// A Gas escalator allows bumping transactions' gas price to avoid getting them
/// stuck in the memory pool.
///
Expand Down Expand Up @@ -72,6 +72,17 @@ pub struct GasEscalatorMiddleware<M, E> {
frequency: Frequency,
}

impl<M, E: Clone> Clone for GasEscalatorMiddleware<M, E> {
fn clone(&self) -> Self {
GasEscalatorMiddleware {
inner: self.inner.clone(),
escalator: self.escalator.clone(),
txs: self.txs.clone(),
frequency: self.frequency.clone(),
}
}
}

#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
impl<M, E> Middleware for GasEscalatorMiddleware<M, E>
Expand Down
6 changes: 5 additions & 1 deletion ethers-middleware/src/transformer/ds_proxy/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,12 @@ mod dsproxyfactory_mod {
pub static DSPROXYFACTORY_ABI: Lazy<Abi> = Lazy::new(|| {
serde_json :: from_str ("[{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"isProxy\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"cache\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"build\",\"outputs\":[{\"name\":\"proxy\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"build\",\"outputs\":[{\"name\":\"proxy\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"proxy\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"cache\",\"type\":\"address\"}],\"name\":\"Created\",\"type\":\"event\"}]\n") . expect ("invalid abi")
});
#[derive(Clone)]
pub struct DsProxyFactory<M>(Contract<M>);
impl<M> Clone for DsProxyFactory<M> {
fn clone(&self) -> Self {
DsProxyFactory(self.0.clone())
}
}
impl<M> std::ops::Deref for DsProxyFactory<M> {
type Target = Contract<M>;
fn deref(&self) -> &Self::Target {
Expand Down