Skip to content

Commit 1abef98

Browse files
authored
migrate: ethers to alloy (#194)
* migrate: ethers to alloy * update alloy to 0.6.4 * fix ci * add RetryBackoffLayer * fix missing field * fix calculate * add missing n_rlp_bytes
1 parent eba6192 commit 1abef98

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+3540
-2969
lines changed

Cargo.lock

Lines changed: 2222 additions & 1930 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@ cryo_cli = { version = "0.3.2", path = "./crates/cli" }
1919
cryo_freeze = { version = "0.3.2", path = "./crates/freeze" }
2020
cryo_to_df = { version = "0.3.2", path = "./crates/to_df" }
2121

22+
alloy = { version = "0.6.4", features = [
23+
"full",
24+
"rpc-types-trace",
25+
"provider-ws",
26+
"provider-ipc",
27+
"provider-debug-api",
28+
"provider-trace-api",
29+
"transport-ipc-mock",
30+
] }
2231
anstyle = "1.0.4"
2332
async-trait = "0.1.74"
2433
chrono = { version = "0.4.31", features = ["serde"] }
@@ -29,8 +38,6 @@ clap_cryo = { version = "4.3.21-cryo", features = [
2938
] }
3039
colored = "2.0.4"
3140
color-print = "0.3.5"
32-
ethers = { version = "2.0.10", features = ["rustls", "ws", "ipc"] }
33-
ethers-core = "2.0.10"
3441
eyre = "0.6.8"
3542
futures = "0.3.29"
3643
governor = "0.6.0"

crates/cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ path = "src/main.rs"
1818
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1919

2020
[dependencies]
21+
alloy = { workspace = true }
2122
anstyle = { workspace = true }
2223
clap_cryo = { workspace = true }
2324
color-print = { workspace = true }
2425
colored = { workspace = true }
2526
cryo_freeze = { workspace = true }
26-
ethers = { workspace = true }
2727
eyre = { workspace = true }
2828
governor = { workspace = true }
2929
hex = { workspace = true }

crates/cli/src/args.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ pub struct Args {
106106
#[arg(long, default_value_t = 500, value_name = "B", help_heading = "Acquisition Options")]
107107
pub initial_backoff: u64,
108108

109+
/// The number of compute units per second for this provider
110+
#[arg(long, default_value_t = 50, value_name = "U", help_heading = "Acquisition Options")]
111+
pub compute_units_per_second: u64,
112+
109113
/// Global number of concurrent requests
110114
#[arg(long, value_name = "M", help_heading = "Acquisition Options")]
111115
pub max_concurrent_requests: Option<u64>,

crates/cli/src/parse/blocks.rs

Lines changed: 73 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ async fn parse_block_inputs(
168168
}
169169
}
170170

171+
#[derive(Clone, Debug)]
171172
enum RangePosition {
172173
First,
173174
Last,
@@ -322,15 +323,14 @@ async fn parse_block_number(
322323
source: Arc<Source>,
323324
) -> Result<u64, ParseError> {
324325
match (block_ref, range_position) {
325-
("latest", _) => source.get_block_number().await.map(|n| n.as_u64()).map_err(|_e| {
326+
("latest", _) => source.get_block_number().await.map_err(|_e| {
326327
ParseError::ParseError("Error retrieving latest block number".to_string())
327328
}),
328329
("", RangePosition::First) => Ok(0),
329-
("", RangePosition::Last) => {
330-
source.get_block_number().await.map(|n| n.as_u64()).map_err(|_e| {
331-
ParseError::ParseError("Error retrieving last block number".to_string())
332-
})
333-
}
330+
("", RangePosition::Last) => source
331+
.get_block_number()
332+
.await
333+
.map_err(|_e| ParseError::ParseError("Error retrieving last block number".to_string())),
334334
("", RangePosition::None) => Err(ParseError::ParseError("invalid input".to_string())),
335335
_ if block_ref.ends_with('B') | block_ref.ends_with('b') => {
336336
let s = &block_ref[..block_ref.len() - 1];
@@ -366,7 +366,7 @@ async fn apply_reorg_buffer(
366366
0 => Ok(block_chunks),
367367
reorg_filter => {
368368
let latest_block = match source.get_block_number().await {
369-
Ok(result) => result.as_u64(),
369+
Ok(result) => result,
370370
Err(_e) => {
371371
return Err(ParseError::ParseError("reorg buffer parse error".to_string()))
372372
}
@@ -387,24 +387,34 @@ pub(crate) async fn get_latest_block_number(source: Arc<Source>) -> Result<u64,
387387
source
388388
.get_block_number()
389389
.await
390-
.map(|n| n.as_u64())
391390
.map_err(|_e| ParseError::ParseError("Error retrieving latest block number".to_string()))
392391
}
393392

394393
#[cfg(test)]
395394
mod tests {
395+
use std::path::PathBuf;
396+
397+
use alloy::{
398+
providers::{IpcConnect, ProviderBuilder},
399+
transports::ipc::MockIpcServer,
400+
};
401+
396402
use super::*;
397-
use ethers::prelude::*;
398403

404+
#[derive(Clone, Debug)]
399405
enum BlockTokenTest<'a> {
400406
WithoutMock((&'a str, BlockChunk)), // Token | Expected
401407
WithMock((&'a str, BlockChunk, u64)), // Token | Expected | Mock Block Response
402408
}
403409

404-
async fn block_token_test_helper(tests: Vec<(BlockTokenTest<'_>, bool)>) {
405-
let (provider, mock) = Provider::mocked();
410+
async fn block_token_test_helper(
411+
tests: Vec<(BlockTokenTest<'_>, bool)>,
412+
mock_ipc_path: PathBuf,
413+
) {
414+
let ipc = IpcConnect::new(mock_ipc_path);
415+
let provider = ProviderBuilder::new().on_ipc(ipc).await.unwrap().boxed();
406416
let source = Source {
407-
provider: provider.into(),
417+
provider,
408418
semaphore: Arc::new(None),
409419
rate_limiter: Arc::new(None),
410420
chain_id: 1,
@@ -416,8 +426,7 @@ mod tests {
416426
let source = Arc::new(source);
417427
for (test, res) in tests {
418428
match test {
419-
BlockTokenTest::WithMock((token, expected, latest)) => {
420-
mock.push(U64::from(latest)).unwrap();
429+
BlockTokenTest::WithMock((token, expected, _latest)) => {
421430
assert_eq!(
422431
block_token_test_executor(token, expected, source.clone()).await,
423432
res
@@ -458,15 +467,20 @@ mod tests {
458467
}
459468
}
460469

470+
#[derive(Clone, Debug)]
461471
enum BlockInputTest<'a> {
462472
WithoutMock((&'a String, Vec<BlockChunk>)), // Token | Expected
463473
WithMock((&'a String, Vec<BlockChunk>, u64)), // Token | Expected | Mock Block Response
464474
}
465475

466-
async fn block_input_test_helper(tests: Vec<(BlockInputTest<'_>, bool)>) {
467-
let (provider, mock) = Provider::mocked();
476+
async fn block_input_test_helper(
477+
tests: Vec<(BlockInputTest<'_>, bool)>,
478+
mock_ipc_path: PathBuf,
479+
) {
480+
let ipc = IpcConnect::new(mock_ipc_path);
481+
let provider = ProviderBuilder::new().on_ipc(ipc).await.unwrap().boxed();
468482
let source = Arc::new(Source {
469-
provider: provider.into(),
483+
provider,
470484
chain_id: 1,
471485
rpc_url: "".to_string(),
472486
inner_request_size: 1,
@@ -477,8 +491,7 @@ mod tests {
477491
});
478492
for (test, res) in tests {
479493
match test {
480-
BlockInputTest::WithMock((inputs, expected, latest)) => {
481-
mock.push(U64::from(latest)).unwrap();
494+
BlockInputTest::WithMock((inputs, expected, _latest)) => {
482495
assert_eq!(
483496
block_input_test_executor(inputs, expected, source.clone()).await,
484497
res
@@ -531,15 +544,20 @@ mod tests {
531544
true
532545
}
533546

547+
#[derive(Clone, Debug)]
534548
enum BlockNumberTest<'a> {
535549
WithoutMock((&'a str, RangePosition, u64)),
536550
WithMock((&'a str, RangePosition, u64, u64)),
537551
}
538552

539-
async fn block_number_test_helper(tests: Vec<(BlockNumberTest<'_>, bool)>) {
540-
let (provider, mock) = Provider::mocked();
553+
async fn block_number_test_helper(
554+
tests: Vec<(BlockNumberTest<'_>, bool)>,
555+
mock_ipc_path: PathBuf,
556+
) {
557+
let provider =
558+
ProviderBuilder::new().on_ipc(IpcConnect::new(mock_ipc_path)).await.unwrap().boxed();
541559
let source = Source {
542-
provider: provider.into(),
560+
provider,
543561
semaphore: Arc::new(None),
544562
rate_limiter: Arc::new(None),
545563
chain_id: 1,
@@ -551,8 +569,7 @@ mod tests {
551569
let source = Arc::new(source);
552570
for (test, res) in tests {
553571
match test {
554-
BlockNumberTest::WithMock((block_ref, range_position, expected, latest)) => {
555-
mock.push(U64::from(latest)).unwrap();
572+
BlockNumberTest::WithMock((block_ref, range_position, expected, _latest)) => {
556573
assert_eq!(
557574
block_number_test_executor(
558575
block_ref,
@@ -604,7 +621,18 @@ mod tests {
604621
// Number type
605622
(BlockTokenTest::WithoutMock((r"1", BlockChunk::Numbers(vec![1]))), true), /* Single block */
606623
];
607-
block_token_test_helper(tests).await;
624+
let mut mock_server = MockIpcServer::new();
625+
let mock_ipc_path = mock_server.path().clone();
626+
for (test, _) in tests.clone().into_iter() {
627+
match test {
628+
BlockTokenTest::WithoutMock(_) => {}
629+
BlockTokenTest::WithMock((_, _, mock_response)) => {
630+
mock_server.add_reply(mock_response)
631+
}
632+
}
633+
}
634+
mock_server.spawn().await;
635+
block_token_test_helper(tests, mock_ipc_path).await;
608636
}
609637

610638
#[tokio::test]
@@ -648,7 +676,16 @@ mod tests {
648676
true,
649677
), // Multi input complex
650678
];
651-
block_input_test_helper(tests).await;
679+
let mut mock_server = MockIpcServer::new();
680+
let mock_ipc_path = mock_server.path().clone();
681+
for (test, _) in tests.clone() {
682+
match test {
683+
BlockInputTest::WithMock((_, _, expected)) => mock_server.add_reply(expected),
684+
BlockInputTest::WithoutMock(_) => {}
685+
}
686+
}
687+
mock_server.spawn().await;
688+
block_input_test_helper(tests, mock_ipc_path).await;
652689
}
653690

654691
#[tokio::test]
@@ -666,6 +703,15 @@ mod tests {
666703
(BlockNumberTest::WithoutMock((r"1m", RangePosition::None, 1000000)), true), // m
667704
(BlockNumberTest::WithoutMock((r"1k", RangePosition::None, 1000)), true), // k
668705
];
669-
block_number_test_helper(tests).await;
706+
let mut mock_server = MockIpcServer::new();
707+
let mock_ipc_path = mock_server.path().clone();
708+
for (test, _) in tests.clone() {
709+
match test {
710+
BlockNumberTest::WithMock((_, _, _, expected)) => mock_server.add_reply(expected),
711+
BlockNumberTest::WithoutMock(_) => {}
712+
}
713+
}
714+
mock_server.spawn().await;
715+
block_number_test_helper(tests, mock_ipc_path).await;
670716
}
671717
}

crates/cli/src/parse/file_output.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ fn parse_row_group_size(
142142
) -> Option<usize> {
143143
match (row_group_size, n_row_groups, chunk_size) {
144144
(Some(row_group_size), _, _) => Some(row_group_size),
145-
(_, Some(n_row_groups), Some(cs)) => Some((cs + n_row_groups - 1) / n_row_groups),
145+
(_, Some(n_row_groups), Some(cs)) => Some(cs.div_ceil(n_row_groups)),
146146
_ => None,
147147
}
148148
}

crates/cli/src/parse/parse_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use cryo_freeze::ParseError;
22
use std::collections::HashMap;
33

4-
pub(crate) fn hex_string_to_binary(hex_string: &String) -> Result<Vec<u8>, ParseError> {
4+
pub(crate) fn hex_string_to_binary(hex_string: &str) -> Result<Vec<u8>, ParseError> {
55
let hex_string = hex_string.strip_prefix("0x").unwrap_or(hex_string);
66
hex::decode(hex_string)
77
.map_err(|_| ParseError::ParseError("could not parse data as hex".to_string()))

crates/cli/src/parse/partitions.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use cryo_freeze::{
88
AddressChunk, CallDataChunk, Datatype, Dim, ParseError, Partition, PartitionLabels, SlotChunk,
99
Source, Table, TimeDimension, TopicChunk, TransactionChunk,
1010
};
11-
use ethers::prelude::*;
1211
use rand::{seq::SliceRandom, thread_rng};
1312
use std::{collections::HashMap, str::FromStr, sync::Arc};
1413

crates/cli/src/parse/source.rs

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,33 @@
11
use std::env;
22

33
use crate::args::Args;
4-
use cryo_freeze::{sources::ProviderWrapper, ParseError, Source, SourceLabels};
5-
use ethers::prelude::*;
4+
use alloy::{
5+
providers::{Provider, ProviderBuilder, RootProvider},
6+
rpc::client::{BuiltInConnectionString, ClientBuilder, RpcClient},
7+
transports::{layers::RetryBackoffLayer, BoxTransport},
8+
};
9+
use cryo_freeze::{ParseError, Source, SourceLabels};
610
use governor::{Quota, RateLimiter};
711
use polars::prelude::*;
812
use std::num::NonZeroU32;
913

1014
pub(crate) async fn parse_source(args: &Args) -> Result<Source, ParseError> {
1115
// parse network info
1216
let rpc_url = parse_rpc_url(args)?;
13-
let (provider, chain_id): (ProviderWrapper, u64) = if rpc_url.starts_with("http") {
14-
let provider = Provider::<RetryClient<Http>>::new_client(
15-
&rpc_url,
16-
args.max_retries,
17-
args.initial_backoff,
18-
)
19-
.map_err(|_e| ParseError::ParseError("could not connect to provider".to_string()))?;
20-
let chain_id = provider.get_chainid().await.map_err(ParseError::ProviderError)?.as_u64();
21-
(provider.into(), chain_id)
22-
} else if rpc_url.starts_with("ws") {
23-
let provider = Provider::<Ws>::connect(&rpc_url).await.map_err(|_| {
24-
ParseError::ParseError("could not instantiate HTTP Provider".to_string())
25-
})?;
26-
let chain_id = provider.get_chainid().await.map_err(ParseError::ProviderError)?.as_u64();
27-
(provider.into(), chain_id)
28-
} else if rpc_url.ends_with(".ipc") {
29-
let provider: Provider<Ipc> = Provider::connect_ipc(&rpc_url).await.map_err(|_| {
30-
ParseError::ParseError("could not instantiate HTTP Provider".to_string())
31-
})?;
32-
let chain_id = provider.get_chainid().await.map_err(ParseError::ProviderError)?.as_u64();
33-
(provider.into(), chain_id)
34-
} else {
35-
return Err(ParseError::ParseError(format!("invalid rpc url: {}", rpc_url)));
36-
};
37-
17+
let retry_layer = RetryBackoffLayer::new(
18+
args.max_retries,
19+
args.initial_backoff,
20+
args.compute_units_per_second,
21+
);
22+
let connect: BuiltInConnectionString = rpc_url.parse().map_err(ParseError::ProviderError)?;
23+
let client: RpcClient<BoxTransport> = ClientBuilder::default()
24+
.layer(retry_layer)
25+
.connect_boxed(connect)
26+
.await
27+
.map_err(ParseError::ProviderError)?
28+
.boxed();
29+
let provider: RootProvider<BoxTransport> = ProviderBuilder::default().on_client(client);
30+
let chain_id = provider.get_chain_id().await.map_err(ParseError::ProviderError)?;
3831
let rate_limiter = match args.requests_per_second {
3932
Some(rate_limit) => match (NonZeroU32::new(1), NonZeroU32::new(rate_limit)) {
4033
(Some(one), Some(value)) => {

0 commit comments

Comments
 (0)