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:
parent
ebf52934e4
commit
f4c89c6cb1
|
@ -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
|
|
@ -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",
|
||||||
|
|
|
@ -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"] }
|
||||||
|
|
|
@ -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"]
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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
|
|
||||||
]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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};
|
||||||
|
|
Loading…
Reference in New Issue