ci: run examples in CI (#421)

* ci: run examples in CI

* fix(ens): set the resolved ens addr for gas estimation

* fix(contract-examples): use legacy sends with ganache

* fix(ens-example): ensure test runs when forking from mainnet

* fix(watch-blocks-example): run our own provider with preset blocktime
This commit is contained in:
Georgios Konstantopoulos 2021-08-30 14:00:30 +03:00 committed by GitHub
parent 824bedbd42
commit b5909d05b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 96 additions and 22 deletions

View File

@ -158,4 +158,45 @@ jobs:
- name: Wasm-pack test chrome
run: |
cd examples/ethers-wasm
wasm-pack test --headless --chrome
wasm-pack test --headless --chrome
examples:
name: Examples
runs-on: ubuntu-latest
steps:
- name: Checkout sources
uses: actions/checkout@v2
- name: Install ganache-cli
uses: actions/setup-node@v1
with:
node-version: 10
- name: Install ganache
run: npm install -g ganache-cli
- name: Install Solc
run: |
mkdir -p "$HOME/bin"
wget -q https://github.com/ethereum/solidity/releases/download/v0.6.6/solc-static-linux -O $HOME/bin/solc
chmod u+x "$HOME/bin/solc"
export PATH=$HOME/bin:$PATH
solc --version
- name: Install geth
run: |
mkdir -p "$HOME/bin"
wget -q https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.9.23-8c2f2715.tar.gz
tar -xvf geth-linux-amd64-1.9.23-8c2f2715.tar.gz
mv geth-linux-amd64-1.9.23-8c2f2715/geth $HOME/bin/geth
chmod u+x "$HOME/bin/geth"
export PATH=$HOME/bin:$PATH
geth version
- name: Install stable toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- name: cargo test
run: |
export PATH=$HOME/bin:$PATH
./scripts/examples.sh

View File

@ -10,6 +10,8 @@ Extensive documentation and examples are available [here](https://docs.rs/ethers
Alternatively, you may clone the repository and run `cd ethers/ && cargo doc --open`
You can also run any of the examples by executing: `cargo run -p ethers --example <name>`
## Add ethers-rs to your repository
```toml

View File

@ -215,7 +215,7 @@ pub trait Middleware: Sync + Send + Debug {
tx: &mut TypedTransaction,
block: Option<BlockId>,
) -> Result<(), Self::Error> {
let tx_clone = tx.clone();
let mut tx_clone = tx.clone();
// TODO: Maybe deduplicate the code in a nice way
match tx {
@ -223,6 +223,7 @@ pub trait Middleware: Sync + Send + Debug {
if let Some(NameOrAddress::Name(ref ens_name)) = inner.to {
let addr = self.resolve_name(ens_name).await?;
inner.to = Some(addr.into());
tx_clone.set_to(addr);
};
if inner.from.is_none() {
@ -244,6 +245,7 @@ pub trait Middleware: Sync + Send + Debug {
if let Some(NameOrAddress::Name(ref ens_name)) = inner.tx.to {
let addr = self.resolve_name(ens_name).await?;
inner.tx.to = Some(addr.into());
tx_clone.set_to(addr);
};
if inner.tx.from.is_none() {
@ -265,6 +267,7 @@ pub trait Middleware: Sync + Send + Debug {
if let Some(NameOrAddress::Name(ref ens_name)) = inner.to {
let addr = self.resolve_name(ens_name).await?;
inner.to = Some(addr.into());
tx_clone.set_to(addr);
};
if inner.from.is_none() {

View File

@ -4,8 +4,8 @@ fn main() -> anyhow::Result<()> {
let mut args = std::env::args();
args.next().unwrap(); // skip program name
let contract_name = args.next().unwrap();
let contract: String = args.next().unwrap();
let contract_name = args.next().unwrap_or("SimpleStorage".to_owned());
let contract: String = args.next().unwrap_or("examples/contract.sol".to_owned());
println!("Generating bindings for {}\n", contract);

View File

@ -45,7 +45,11 @@ async fn main() -> Result<()> {
);
// 6. deploy it with the constructor arguments
let contract = factory.deploy("initial value".to_string())?.send().await?;
let contract = factory
.deploy("initial value".to_string())?
.legacy()
.send()
.await?;
// 7. get the contract's address
let addr = contract.address();
@ -55,7 +59,12 @@ async fn main() -> Result<()> {
// 9. call the `setValue` method
// (first `await` returns a PendingTransaction, second one waits for it to be mined)
let _receipt = contract.set_value("hi".to_owned()).send().await?.await?;
let _receipt = contract
.set_value("hi".to_owned())
.legacy()
.send()
.await?
.await?;
// 10. get all events
let logs = contract

View File

@ -43,7 +43,11 @@ async fn main() -> Result<()> {
);
// 6. deploy it with the constructor arguments
let contract = factory.deploy("initial value".to_string())?.send().await?;
let contract = factory
.deploy("initial value".to_string())?
.legacy()
.send()
.await?;
// 7. get the contract's address
let addr = contract.address();
@ -53,7 +57,12 @@ async fn main() -> Result<()> {
// 9. call the `setValue` method
// (first `await` returns a PendingTransaction, second one waits for it to be mined)
let _receipt = contract.set_value("hi".to_owned()).send().await?.await?;
let _receipt = contract
.set_value("hi".to_owned())
.legacy()
.send()
.await?
.await?;
// 10. get all events
let logs = contract

View File

@ -1,29 +1,29 @@
use anyhow::Result;
use ethers::prelude::*;
use ethers::{prelude::*, utils::Ganache};
use std::convert::TryFrom;
#[tokio::main]
async fn main() -> Result<()> {
// fork mainnet
let ganache = Ganache::new()
.fork("https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27")
.spawn();
let from = ganache.addresses()[0].clone();
// connect to the network
let provider = Provider::<Http>::try_from(
"https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27",
)?;
// create a wallet and connect it to the provider
let wallet = "dcf2cbdd171a21c480aa7f53d77f31bb102282b3ff099c78e3118b37348c72f7"
.parse::<LocalWallet>()?;
let client = SignerMiddleware::new(provider, wallet);
let provider = Provider::<Http>::try_from(ganache.endpoint())
.unwrap()
.with_sender(from);
// craft the transaction
let tx = TransactionRequest::new().to("vitalik.eth").value(100_000);
// send it!
let receipt = client
let receipt = provider
.send_transaction(tx, None)
.await?
.await?
.ok_or_else(|| anyhow::format_err!("tx dropped from mempool"))?;
let tx = client.get_transaction(receipt.transaction_hash).await?;
let tx = provider.get_transaction(receipt.transaction_hash).await?;
println!("{}", serde_json::to_string(&tx)?);
println!("{}", serde_json::to_string(&receipt)?);

View File

@ -2,6 +2,7 @@ use ethers::prelude::*;
use std::time::Duration;
#[tokio::main]
#[cfg(feature = "ipc")]
async fn main() -> anyhow::Result<()> {
let provider = Provider::connect_ipc("~/.ethereum/geth.ipc")
.await?
@ -15,3 +16,6 @@ async fn main() -> anyhow::Result<()> {
Ok(())
}
#[cfg(not(feature = "ipc"))]
fn main() {}

View File

@ -1,11 +1,12 @@
use ethers::prelude::*;
use ethers::{prelude::*, utils::Ganache};
use std::time::Duration;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let ws = Ws::connect("ws://localhost:8546").await?;
let ganache = Ganache::new().block_time(1u64).spawn();
let ws = Ws::connect(ganache.ws_endpoint()).await?;
let provider = Provider::new(ws).interval(Duration::from_millis(2000));
let mut stream = provider.watch_blocks().await?.stream();
let mut stream = provider.watch_blocks().await?.take(5);
while let Some(block) = stream.next().await {
dbg!(block);
}

5
scripts/examples.sh Executable file
View File

@ -0,0 +1,5 @@
# run all examples
for file in examples/*.rs; do
name=`echo $file | cut -f 1 -d '.'`
cargo r -p ethers --example `basename $name`
done