ci: test on windows targets (#682)

* ci: test on windows targets

* make ipc optional

* fix: only activate ipc on unix families

* add cfg

* only check default members

* no parallel limits

Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>
This commit is contained in:
Matthias Seitz 2021-12-13 22:25:10 +01:00 committed by GitHub
parent ebf52934e4
commit f4c89c6cb1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 81 additions and 58 deletions

View File

@ -222,3 +222,52 @@ jobs:
run: | run: |
export PATH=$HOME/bin:$PATH export PATH=$HOME/bin:$PATH
./scripts/examples.sh ./scripts/examples.sh
windows-build:
runs-on: windows-latest
name: (${{ matrix.target }}, ${{ matrix.cfg_release_channel }})
env:
CFG_RELEASE_CHANNEL: ${{ matrix.cfg_release_channel }}
strategy:
fail-fast: false
matrix:
target: [
i686-pc-windows-gnu,
i686-pc-windows-msvc,
x86_64-pc-windows-gnu,
x86_64-pc-windows-msvc,
]
cfg_release_channel: [nightly]
steps:
- name: checkout
uses: actions/checkout@v2
# Run build
- name: Install Rustup using win.rustup.rs
run: |
# disable download progress bar
$ProgressPreference = "SilentlyContinue"
Invoke-WebRequest https://win.rustup.rs/ -OutFile rustup-init.exe
.\rustup-init.exe -y --default-host=x86_64-pc-windows-msvc --default-toolchain=none
del rustup-init.exe
rustup target add ${{ matrix.target }}
shell: powershell
- name: Add mingw32 to path for i686-gnu
run: |
echo "C:\msys64\mingw32\bin" >> $GITHUB_PATH
if: matrix.target == 'i686-pc-windows-gnu' && matrix.channel == 'nightly'
shell: bash
- name: Add mingw64 to path for x86_64-gnu
run: echo "C:\msys64\mingw64\bin" >> $GITHUB_PATH
if: matrix.target == 'x86_64-pc-windows-gnu' && matrix.channel == 'nightly'
shell: bash
- name: build
run: |
rustc -Vv
cargo -V
cargo check --all-features
shell: cmd

4
Cargo.lock generated
View File

@ -3306,9 +3306,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]] [[package]]
name = "svm-rs" name = "svm-rs"
version = "0.2.0" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a5e16a3a87cca053bcab26e5de589ccb5779f84dda466f96eead79a98d7de7c" checksum = "8733662d7e2c4bc2bdc5ca4102c7f8b13d1c3c12fb767089de07c2c3df3cd03d"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cfg-if 1.0.0", "cfg-if 1.0.0",

View File

@ -91,8 +91,12 @@ ethers-etherscan = { version = "^0.2.0", default-features = false, path = "./eth
[dev-dependencies] [dev-dependencies]
ethers-contract = { version = "^0.6.0", default-features = false, path = "./ethers-contract", features = ["abigen", "eip712"] } ethers-contract = { version = "^0.6.0", default-features = false, path = "./ethers-contract", features = ["abigen", "eip712"] }
ethers-providers = { version = "^0.6.0", default-features = false, path = "./ethers-providers", features = ["ws"] }
[target.'cfg(target_family = "unix")'.dev-dependencies]
ethers-providers = { version = "^0.6.0", default-features = false, path = "./ethers-providers", features = ["ws", "ipc"] } ethers-providers = { version = "^0.6.0", default-features = false, path = "./ethers-providers", features = ["ws", "ipc"] }
anyhow = "1.0.39" anyhow = "1.0.39"
rand = "0.8.4" rand = "0.8.4"
serde = { version = "1.0.124", features = ["derive"] } serde = { version = "1.0.124", features = ["derive"] }

View File

@ -58,7 +58,7 @@ tokio = { version = "1.5", default-features = false, features = ["rt", "macros"]
tempfile = "3.2.0" tempfile = "3.2.0"
[features] [features]
default = ["ws", "ipc", "rustls"] default = ["ws", "rustls"]
celo = ["ethers-core/celo"] celo = ["ethers-core/celo"]
ws = ["tokio", "tokio-tungstenite"] ws = ["tokio", "tokio-tungstenite"]
ipc = ["tokio", "tokio/io-util", "tokio-util", "bytes"] ipc = ["tokio", "tokio/io-util", "tokio-util", "bytes"]

View File

@ -949,8 +949,7 @@ impl Provider<crate::Ws> {
} }
} }
#[cfg(not(target_arch = "wasm32"))] #[cfg(all(target_family = "unix", feature = "ipc"))]
#[cfg(feature = "ipc")]
impl Provider<crate::Ipc> { impl Provider<crate::Ipc> {
/// Direct connection to an IPC socket. /// Direct connection to an IPC socket.
pub async fn connect_ipc(path: impl AsRef<std::path::Path>) -> Result<Self, ProviderError> { pub async fn connect_ipc(path: impl AsRef<std::path::Path>) -> Result<Self, ProviderError> {

View File

@ -10,11 +10,13 @@ use futures_channel::mpsc;
use futures_util::stream::{Fuse, StreamExt}; use futures_util::stream::{Fuse, StreamExt};
use oneshot::error::RecvError; use oneshot::error::RecvError;
use serde::{de::DeserializeOwned, Serialize}; use serde::{de::DeserializeOwned, Serialize};
use std::sync::atomic::Ordering;
use std::{ use std::{
collections::HashMap, collections::HashMap,
path::Path, path::Path,
sync::{atomic::AtomicU64, Arc}, sync::{
atomic::{AtomicU64, Ordering},
Arc,
},
}; };
use thiserror::Error; use thiserror::Error;
use tokio::{ use tokio::{
@ -37,18 +39,9 @@ type Subscription = mpsc::UnboundedSender<serde_json::Value>;
#[derive(Debug)] #[derive(Debug)]
enum TransportMessage { enum TransportMessage {
Request { Request { id: u64, request: String, sender: Pending },
id: u64, Subscribe { id: U256, sink: Subscription },
request: String, Unsubscribe { id: U256 },
sender: Pending,
},
Subscribe {
id: U256,
sink: Subscription,
},
Unsubscribe {
id: U256,
},
} }
impl Ipc { impl Ipc {
@ -112,10 +105,7 @@ impl PubsubClient for Ipc {
fn subscribe<T: Into<U256>>(&self, id: T) -> Result<Self::NotificationStream, IpcError> { fn subscribe<T: Into<U256>>(&self, id: T) -> Result<Self::NotificationStream, IpcError> {
let (sink, stream) = mpsc::unbounded(); let (sink, stream) = mpsc::unbounded();
self.send(TransportMessage::Subscribe { self.send(TransportMessage::Subscribe { id: id.into(), sink })?;
id: id.into(),
sink,
})?;
Ok(stream) Ok(stream)
} }
@ -157,12 +147,9 @@ where
let f = async move { let f = async move {
let mut read_buffer = Vec::new(); let mut read_buffer = Vec::new();
loop { loop {
let closed = self let closed = self.process(&mut read_buffer).await.expect("WS Server panic");
.process(&mut read_buffer)
.await
.expect("WS Server panic");
if closed && self.pending.is_empty() { if closed && self.pending.is_empty() {
break; break
} }
} }
}; };
@ -197,11 +184,7 @@ where
async fn handle_request(&mut self, msg: TransportMessage) -> Result<(), IpcError> { async fn handle_request(&mut self, msg: TransportMessage) -> Result<(), IpcError> {
match msg { match msg {
TransportMessage::Request { TransportMessage::Request { id, request, sender } => {
id,
request,
sender,
} => {
if self.pending.insert(id, sender).is_some() { if self.pending.insert(id, sender).is_some() {
warn!("Replacing a pending request with id {:?}", id); warn!("Replacing a pending request with id {:?}", id);
} }
@ -218,10 +201,7 @@ where
} }
TransportMessage::Unsubscribe { id } => { TransportMessage::Unsubscribe { id } => {
if self.subscriptions.remove(&id).is_none() { if self.subscriptions.remove(&id).is_none() {
warn!( warn!("Unsubscribing from non-existent subscription with id {:?}", id);
"Unsubscribing from non-existent subscription with id {:?}",
id
);
} }
} }
}; };
@ -287,7 +267,8 @@ where
} }
/// Sends JSON response through the channel based on the ID in that response. /// Sends JSON response through the channel based on the ID in that response.
/// This handles RPC calls with only one response, and the channel entry is dropped after sending. /// This handles RPC calls with only one response, and the channel entry is dropped after
/// sending.
fn respond(&mut self, output: Response<serde_json::Value>) -> Result<(), IpcError> { fn respond(&mut self, output: Response<serde_json::Value>) -> Result<(), IpcError> {
let id = output.id; let id = output.id;
@ -338,7 +319,10 @@ impl From<IpcError> for ProviderError {
#[cfg(not(feature = "celo"))] #[cfg(not(feature = "celo"))]
mod test { mod test {
use super::*; use super::*;
use ethers_core::{utils::Geth, types::{Block, TxHash, U256}}; use ethers_core::{
types::{Block, TxHash, U256},
utils::Geth,
};
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
#[tokio::test] #[tokio::test]
@ -366,11 +350,7 @@ mod test {
// Subscribing requires sending the sub request and then subscribing to // Subscribing requires sending the sub request and then subscribing to
// the returned sub_id // the returned sub_id
let block_num: u64 = ipc let block_num: u64 = ipc.request::<_, U256>("eth_blockNumber", ()).await.unwrap().as_u64();
.request::<_, U256>("eth_blockNumber", ())
.await
.unwrap()
.as_u64();
let mut blocks = Vec::new(); let mut blocks = Vec::new();
for _ in 0..3 { for _ in 0..3 {
let item = stream.next().await.unwrap(); let item = stream.next().await.unwrap();
@ -378,13 +358,6 @@ mod test {
blocks.push(block.number.unwrap_or_default().as_u64()); blocks.push(block.number.unwrap_or_default().as_u64());
} }
let offset = blocks[0] - block_num; let offset = blocks[0] - block_num;
assert_eq!( assert_eq!(blocks, &[block_num + offset, block_num + offset + 1, block_num + offset + 2])
blocks,
&[
block_num + offset,
block_num + offset + 1,
block_num + offset + 2
]
)
} }
} }

View File

@ -16,12 +16,10 @@ macro_rules! if_not_wasm {
)*} )*}
} }
if_not_wasm! { #[cfg(all(target_family = "unix", feature = "ipc"))]
#[cfg(feature = "ipc")]
mod ipc; mod ipc;
#[cfg(feature = "ipc")] #[cfg(all(target_family = "unix", feature = "ipc"))]
pub use ipc::Ipc; pub use ipc::Ipc;
}
mod http; mod http;
pub use http::{ClientError as HttpClientError, Provider as Http}; pub use http::{ClientError as HttpClientError, Provider as Http};