Skip to content

Commit

Permalink
EPROD-865 optional fields in mint order (#184)
Browse files Browse the repository at this point in the history
  • Loading branch information
veeso authored Jul 22, 2024
1 parent 8e98582 commit 1cec9d7
Show file tree
Hide file tree
Showing 5 changed files with 247 additions and 60 deletions.
6 changes: 2 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ homepage = "https://github.com/bitfinity-network/bitfinity-evm-sdk"
include = ["src/**/*", "LICENSE", "README.md"]
license = "MIT"
repository = "https://github.com/bitfinity-network/bitfinity-evm-sdk"
version = "0.27.0"


version = "0.28.0"

[workspace.dependencies]
alloy-primitives = { version = "0.7", default-features = false }
Expand Down Expand Up @@ -62,6 +60,7 @@ port_check = "0.2"
rand = { version = "0.8", features = ["std_rng", "small_rng"] }
reqwest = { version = "0.12", default-features = false }
rlp = "0.5"
serial_test = "3"
serde = "1.0"
serde_bytes = "0.11"
serde_json = "1.0"
Expand All @@ -82,6 +81,5 @@ thiserror = "1.0"
tokio = { version = "1.24", features = ["macros", "rt", "signal"] }
url = "2.5"


[profile.dev]
debug = false
2 changes: 2 additions & 0 deletions src/ethereum-json-rpc-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,6 @@ url = { workspace = true, optional = true }
[dev-dependencies]
env_logger = { workspace = true }
hex = { workspace = true }
rand = { workspace = true }
serial_test = { workspace = true }
tokio = { workspace = true }
191 changes: 144 additions & 47 deletions src/ethereum-json-rpc-client/tests/reqwest/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
use std::time::Duration;

use ethereum_json_rpc_client::reqwest::ReqwestClient;
use ethereum_json_rpc_client::{EthGetLogsParams, EthJsonRpcClient};
use ethereum_json_rpc_client::{Client, EthGetLogsParams, EthJsonRpcClient};
use ethers_core::abi::{Function, Param, ParamType, StateMutability, Token};
use ethers_core::types::{BlockNumber, Log, TransactionRequest, H160, H256, U256};

const ETHEREUM_JSON_API_URL: &str = "https://cloudflare-eth.com/";
use jsonrpc_core::{Output, Response};
use rand::SeedableRng as _;
use serial_test::serial;

const ETHEREUM_JSON_API_ENDPOINTS: &[&str] = &[
"https://cloudflare-eth.com/",
"https://ethereum.publicnode.com",
"https://rpc.ankr.com/eth",
"https://nodes.mewapi.io/rpc/eth",
"https://eth-mainnet.gateway.pokt.network/v1/5f3453978e354ab992c4da79",
"https://eth-mainnet.nodereal.io/v1/1659dfb40aa24bbb8153a677b98064d7",
"https://eth.llamarpc.com",
"https://eth-mainnet.public.blastapi.io",
];
const MAX_BATCH_SIZE: usize = 5;

fn to_hash(string: &str) -> H256 {
Expand All @@ -14,17 +28,75 @@ fn to_hash(string: &str) -> H256 {
)
}

fn reqwest_client() -> EthJsonRpcClient<ReqwestClient> {
EthJsonRpcClient::new(ReqwestClient::new(ETHEREUM_JSON_API_URL.to_string()))
/// This client randomly shuffle RPC providers and tries to send the request to each one of them
/// until it gets a successful response.
///
/// This was necessary because some RPC providers have rate limits and running the CI was more like a nightmare.
#[derive(Clone)]
pub struct MultiRpcReqwestClient;

impl Client for MultiRpcReqwestClient {
fn send_rpc_request(
&self,
request: jsonrpc_core::Request,
) -> std::pin::Pin<
Box<dyn std::future::Future<Output = anyhow::Result<jsonrpc_core::Response>> + Send>,
> {
Box::pin(async move {
let mut rng = rand::rngs::StdRng::from_entropy();

use rand::seq::SliceRandom;
let mut err = None;
let mut endpoints = ETHEREUM_JSON_API_ENDPOINTS.to_vec();
endpoints.shuffle(&mut rng);
for rpc_endpoint in endpoints {
let client = ReqwestClient::new_with_client(
rpc_endpoint.to_string(),
reqwest::ClientBuilder::new()
.timeout(Duration::from_secs(10))
.build()
.unwrap(),
);
let result = client.send_rpc_request(request.clone()).await;

match result {
Ok(Response::Single(Output::Success(_))) => return result,
Ok(Response::Batch(batch))
if batch
.iter()
.all(|output| matches!(output, Output::Success(_))) =>
{
return Ok(Response::Batch(batch))
}
Ok(result) => {
println!("call failed: {result:?}");
err = Some(anyhow::anyhow!("call failed: {result:?}"));
}
Err(e) => {
println!("call failed: {e}");
err = Some(e);
}
}
}

Err(err.unwrap())
})
}
}

fn reqwest_client() -> EthJsonRpcClient<MultiRpcReqwestClient> {
EthJsonRpcClient::new(MultiRpcReqwestClient)
}

#[tokio::test]
#[serial]
async fn should_get_block_number() {
let result = reqwest_client().get_block_number().await.unwrap();
assert!(result > 16896634);
}

#[tokio::test]
#[serial]
async fn should_get_balance() {
let erc_1820_deployer_address = "0xa990077c3205cbDf861e17Fa532eeB069cE9fF96"
.parse()
Expand All @@ -37,12 +109,14 @@ async fn should_get_balance() {
}

#[tokio::test]
#[serial]
async fn should_get_gas_price() {
let price = reqwest_client().gas_price().await.unwrap();
assert!(price > U256::zero());
}

#[tokio::test]
#[serial]
async fn should_get_code() {
let erc_1820_address = "0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24"
.parse()
Expand All @@ -60,6 +134,7 @@ async fn should_get_code() {
/// function getManager(address _addr) public view returns(address)
///```
#[tokio::test]
#[serial]
async fn should_perform_eth_call() {
let erc_1820_address = "0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24"
.parse::<H160>()
Expand Down Expand Up @@ -114,6 +189,7 @@ async fn should_perform_eth_call() {
}

#[tokio::test]
#[serial]
async fn should_get_transaction_count() {
let erc_1820_deployer_address = "0xa990077c3205cbDf861e17Fa532eeB069cE9fF96"
.parse()
Expand All @@ -126,6 +202,7 @@ async fn should_get_transaction_count() {
}

#[tokio::test]
#[serial]
async fn should_get_block_by_number() {
let result = reqwest_client()
.get_block_by_number(BlockNumber::Number(11588465.into()))
Expand All @@ -143,6 +220,7 @@ async fn should_get_block_by_number() {
}

#[tokio::test]
#[serial]
async fn should_get_full_block_by_number() {
let result = reqwest_client()
.get_full_block_by_number(BlockNumber::Number(11588465.into()))
Expand All @@ -165,6 +243,7 @@ async fn should_get_full_block_by_number() {
}

#[tokio::test]
#[serial]
async fn should_get_full_blocks_by_number() {
let result = reqwest_client()
.get_full_blocks_by_number(
Expand Down Expand Up @@ -205,35 +284,37 @@ async fn should_get_full_blocks_by_number() {
}

#[tokio::test]
#[serial]
async fn should_get_logs() {
let params = EthGetLogsParams {
address: Some(vec!["0xb59f67a8bff5d8cd03f6ac17265c550ed8f33907"
.parse()
.unwrap()]),
from_block: "0x429d3b".parse().unwrap(),
to_block: BlockNumber::Latest,
topics: Some(vec![
vec![
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
.parse()
.unwrap(),
],
vec![
"0x00000000000000000000000000b46c2526e227482e2ebb8f4c69e4674d262e75"
.parse()
.unwrap(),
],
vec![
"0x00000000000000000000000054a2d42a40f51259dedd1978f6c118a0f0eff078"
.parse()
.unwrap(),
],
]),
};

let result = reqwest_client().get_logs(params).await.unwrap();
// this test is flaky for some reasons, so we try multiple times
for _ in 0..3 {
let params = EthGetLogsParams {
address: Some(vec!["0xb59f67a8bff5d8cd03f6ac17265c550ed8f33907"
.parse()
.unwrap()]),
from_block: "0x429d3b".parse().unwrap(),
to_block: BlockNumber::Latest,
topics: Some(vec![
vec![
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
.parse()
.unwrap(),
],
vec![
"0x00000000000000000000000000b46c2526e227482e2ebb8f4c69e4674d262e75"
.parse()
.unwrap(),
],
vec![
"0x00000000000000000000000054a2d42a40f51259dedd1978f6c118a0f0eff078"
.parse()
.unwrap(),
],
]),
};

let expected_result: Vec<Log> = serde_json::from_str(
if let Ok(result) = reqwest_client().get_logs(params).await {
let expected_result: Vec<Log> = serde_json::from_str(
r#"[
{
"address": "0xb59f67a8bff5d8cd03f6ac17265c550ed8f33907",
Expand All @@ -253,25 +334,41 @@ async fn should_get_logs() {
]"#
).unwrap();

assert_eq!(result, expected_result);
assert_eq!(result, expected_result);
return;
} else {
tokio::time::sleep(Duration::from_secs(5)).await;
}
}

panic!("Failed to get logs");
}

#[tokio::test]
#[serial]
async fn should_get_transaction_receipts() {
let block = reqwest_client()
.get_block_by_number(BlockNumber::Number(11588465.into()))
.await
.unwrap();

let receipts = reqwest_client()
.get_receipts_by_hash(
vec![block.transactions[0], block.transactions[1]],
MAX_BATCH_SIZE,
)
.await
.unwrap();
assert_eq!(receipts[0].gas_used, Some(21000.into()));
assert_eq!(receipts[1].gas_used, Some(52358.into()));
// this test is flaky for some reasons, so we try multiple times
for _ in 0..3 {
let block = reqwest_client()
.get_block_by_number(BlockNumber::Number(11588465.into()))
.await
.unwrap();
if let Ok(receipts) = reqwest_client()
.get_receipts_by_hash(
vec![block.transactions[0], block.transactions[1]],
MAX_BATCH_SIZE,
)
.await
{
assert_eq!(receipts[0].gas_used, Some(21000.into()));
assert_eq!(receipts[1].gas_used, Some(52358.into()));
return;
} else {
tokio::time::sleep(Duration::from_secs(5)).await;
}
}

panic!("Failed to get transaction receipts");
}

const ERC_1820_EXPECTED_CODE: &str = "0x608060405234801561001057600080fd5b50600436106100a557600035\
Expand Down
1 change: 1 addition & 0 deletions src/minter-did/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ serde = { workspace = true }
thiserror = { workspace = true }

[dev-dependencies]
hex = { workspace = true }
rand = { workspace = true }
tokio = { workspace = true }
Loading

0 comments on commit 1cec9d7

Please sign in to comment.