Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix certified data endpoint name #141

Merged
merged 1 commit into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions src/ethereum-json-rpc-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::future::Future;
use std::pin::Pin;

use anyhow::Context;
use did::certified::CertifiedResult;
use did::transaction::StorableExecutionResult;
use ethers_core::types::{
Block, BlockNumber, Log, Transaction, TransactionReceipt, H160, H256, U256, U64,
Expand Down Expand Up @@ -30,6 +31,7 @@ const ETH_SEND_RAW_TRANSACTION_METHOD: &str = "eth_sendRawTransaction";
const ETH_GET_LOGS_METHOD: &str = "eth_getLogs";
const IC_GET_TX_EXECUTION_RESULT_BY_HASH_METHOD: &str = "ic_getExeResultByHash";
const IC_GET_GENESIS_BALANCES: &str = "ic_getGenesisBalances";
const IC_GET_LAST_CERTIFIED_BLOCK: &str = "ic_getLastCertifiedBlock";

macro_rules! make_params_array {
($($items:expr),*) => {
Expand Down Expand Up @@ -58,7 +60,7 @@ impl<C: Client> EthJsonRpcClient<C> {
ETH_GET_BLOCK_BY_NUMBER_METHOD.to_string(),
make_params_array!(block, false),
// For some reason some JSON RPC services fail to parse requests with null id
Id::Str("get_block_by_number".to_string()),
Id::Str(ETH_GET_BLOCK_BY_NUMBER_METHOD.to_string()),
)
.await
}
Expand All @@ -72,7 +74,7 @@ impl<C: Client> EthJsonRpcClient<C> {
ETH_GET_BLOCK_BY_NUMBER_METHOD.to_string(),
make_params_array!(block, true),
// For some reason some JSON RPC services fail to parse requests with null id
Id::Str("get_full_block_by_number".to_string()),
Id::Str(ETH_GET_BLOCK_BY_NUMBER_METHOD.to_string()),
)
.await
}
Expand Down Expand Up @@ -133,7 +135,7 @@ impl<C: Client> EthJsonRpcClient<C> {
self.single_request::<U64>(
ETH_BLOCK_NUMBER_METHOD.to_string(),
make_params_array!(),
Id::Str("eth_blockNumber".to_string()),
Id::Str(ETH_BLOCK_NUMBER_METHOD.to_string()),
)
.await
.map(|v| v.as_u64())
Expand All @@ -144,7 +146,7 @@ impl<C: Client> EthJsonRpcClient<C> {
self.single_request::<U64>(
ETH_CHAIN_ID_METHOD.to_string(),
Params::Array(vec![]),
Id::Str("eth_chainId".to_string()),
Id::Str(ETH_CHAIN_ID_METHOD.to_string()),
)
.await
.map(|v| v.as_u64())
Expand All @@ -155,7 +157,7 @@ impl<C: Client> EthJsonRpcClient<C> {
self.single_request(
ETH_GET_BALANCE_METHOD.to_string(),
make_params_array!(address, block),
Id::Str("eth_getBalance".to_string()),
Id::Str(ETH_GET_BALANCE_METHOD.to_string()),
)
.await
}
Expand All @@ -169,7 +171,7 @@ impl<C: Client> EthJsonRpcClient<C> {
self.single_request::<U64>(
ETH_GET_TRANSACTION_COUNT_METHOD.to_string(),
make_params_array!(address, block),
Id::Str("eth_getTransactionCount".to_string()),
Id::Str(ETH_GET_TRANSACTION_COUNT_METHOD.to_string()),
)
.await
.map(|v| v.as_u64())
Expand All @@ -183,7 +185,7 @@ impl<C: Client> EthJsonRpcClient<C> {
self.single_request::<H256>(
ETH_SEND_RAW_TRANSACTION_METHOD.to_string(),
make_params_array!(transaction),
Id::Str("send_rawTransaction".to_string()),
Id::Str(ETH_SEND_RAW_TRANSACTION_METHOD.to_string()),
)
.await
}
Expand All @@ -193,7 +195,7 @@ impl<C: Client> EthJsonRpcClient<C> {
self.single_request(
ETH_GET_LOGS_METHOD.to_string(),
make_params_array!(params),
Id::Str("ETH_GET_LOGS_METHOD".to_string()),
Id::Str(ETH_GET_LOGS_METHOD.to_string()),
)
.await
}
Expand Down Expand Up @@ -251,6 +253,16 @@ impl<C: Client> EthJsonRpcClient<C> {
.await
}

/// Returns the last certified block
pub async fn get_last_certified_block(&self) -> anyhow::Result<CertifiedResult<Block<H256>>> {
self.single_request(
IC_GET_LAST_CERTIFIED_BLOCK.to_string(),
make_params_array!(),
Id::Str(IC_GET_LAST_CERTIFIED_BLOCK.to_string()),
)
.await
}

/// Performs a request.
pub async fn request(&self, request: Request) -> anyhow::Result<Response> {
self.client.send_rpc_request(request).await
Expand Down
2 changes: 1 addition & 1 deletion src/evm-block-extractor/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub trait IC {
#[method(name = "getGenesisBalances")]
async fn get_genesis_balances(&self) -> RpcResult<Vec<(H160, U256)>>;

#[method(name = "getLastBlockCertifiedData")]
#[method(name = "getLastCertifiedBlock")]
async fn get_last_block_certified_data(&self) -> RpcResult<CertifiedBlock>;
}

Expand Down
17 changes: 6 additions & 11 deletions src/evm-block-extractor/src/task/block_extractor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,18 +135,13 @@ impl BlockExtractor {

/// Collects last certified block
async fn collect_last_certified_block(&self) -> anyhow::Result<()> {
const JSON_RPC_METHOD_LAST_CERTIFIED_BLOCK: &str = "ic_getLastCertifiedBlock";

let certified_block = self
.client
.single_request::<CertifiedBlock>(
JSON_RPC_METHOD_LAST_CERTIFIED_BLOCK.to_string(),
jsonrpc_core::Params::Array(vec![]),
jsonrpc_core::Id::Null,
)
.await?;
let certified_block = self.client.get_last_certified_block().await?;
self.blockchain
.insert_certified_block_data(certified_block)
.insert_certified_block_data(CertifiedBlock {
data: certified_block.data.into(),
witness: certified_block.witness,
certificate: certified_block.certificate,
})
.await?;

Ok(())
Expand Down
50 changes: 16 additions & 34 deletions src/evm-block-extractor/tests/tests/server_it.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,7 @@ async fn with_filled_db<Func: Fn(Arc<dyn DatabaseClient>) -> Fut, Fut: Future<Ou
#[tokio::test]
async fn test_get_blocks() {
with_filled_db(|db_client| async {
let (port, handle) = new_server(db_client).await;

let http_client =
EthJsonRpcClient::new(ReqwestClient::new(format!("http://127.0.0.1:{port}")));
let (http_client, _port, handle) = new_server(db_client).await;

let block_count = http_client.get_block_number().await.unwrap();
assert_eq!(block_count, BLOCK_COUNT - 1);
Expand Down Expand Up @@ -88,9 +85,10 @@ async fn test_get_blocks() {
#[tokio::test]
async fn test_get_blocks_rlp() {
with_filled_db(|db_client| async {
let (port, handle) = new_server(db_client).await;
let (_http_client, port, handle) = new_server(db_client).await;

let http_client = ReqwestClient::new(format!("http://127.0.0.1:{port}"));

// Test first five blocks
let request = Request::Single(Call::MethodCall(MethodCall {
jsonrpc: Some(Version::V2),
Expand Down Expand Up @@ -144,7 +142,7 @@ async fn test_get_blocks_rlp() {
#[tokio::test]
async fn test_batched_request() {
with_filled_db(|db_client| async {
let (port, handle) = new_server(db_client).await;
let (_http_client, port, handle) = new_server(db_client).await;

let http_client = ReqwestClient::new(format!("http://127.0.0.1:{port}"));
let request = Request::Batch(vec![
Expand Down Expand Up @@ -196,10 +194,7 @@ async fn test_get_genesis_accounts() {
// Arrange
db_client.init(None, false).await.unwrap();

let (port, handle) = new_server(db_client.clone()).await;

let http_client =
EthJsonRpcClient::new(ReqwestClient::new(format!("http://127.0.0.1:{port}")));
let (http_client, _port, handle) = new_server(db_client.clone()).await;

// Test on empty database
{
Expand Down Expand Up @@ -257,10 +252,7 @@ async fn test_get_chain_id() {
// Arrange
db_client.init(None, false).await.unwrap();

let (port, handle) = new_server(db_client.clone()).await;

let http_client =
EthJsonRpcClient::new(ReqwestClient::new(format!("http://127.0.0.1:{port}")));
let (http_client, _port, handle) = new_server(db_client.clone()).await;

let chain_id: u64 = random();
db_client.insert_chain_id(chain_id).await.unwrap();
Expand All @@ -282,7 +274,7 @@ async fn test_get_chain_id() {
#[tokio::test]
async fn test_get_block_by_number_variants() {
with_filled_db(|db_client| async {
let (port, handle) = new_server(db_client).await;
let (_http_client, port, handle) = new_server(db_client).await;

let http_client = ReqwestClient::new(format!("http://127.0.0.1:{port}"));
let request = Request::Batch(vec![
Expand Down Expand Up @@ -360,29 +352,15 @@ async fn test_get_last_certified_block() {
.await
.unwrap();

let (port, handle) = new_server(db_client.clone()).await;

let http_client = ReqwestClient::new(format!("http://127.0.0.1:{port}"));
let (http_client, _port, handle) = new_server(db_client.clone()).await;

// Act
let request = Request::Single(Call::MethodCall(MethodCall {
jsonrpc: Some(Version::V2),
method: "ic_getLastBlockCertifiedData".to_string(),
params: Params::Array(vec![]),
id: Id::Null,
}));

let Response::Single(Output::Success(result)) =
http_client.send_rpc_request(request).await.unwrap()
else {
panic!("unexpected return type")
};
let certified_block = http_client.get_last_certified_block().await.unwrap();

// Assert
let certified_block: CertifiedBlock = serde_json::from_value(result.result).unwrap();
assert_eq!(certified_block.certificate, vec![1, 2, 3]);
assert_eq!(certified_block.witness, vec![5, 6, 7]);
assert_eq!(certified_block.data, block);
assert_eq!(certified_block.data, block.into());

{
handle.stop().unwrap();
Expand All @@ -392,7 +370,9 @@ async fn test_get_last_certified_block() {
.await
}

async fn new_server(db_client: Arc<dyn DatabaseClient>) -> (u16, ServerHandle) {
async fn new_server(
db_client: Arc<dyn DatabaseClient>,
) -> (EthJsonRpcClient<ReqwestClient>, u16, ServerHandle) {
let eth = EthImpl::new(db_client);
let mut module = RpcModule::new(());
module.merge(EthServer::into_rpc(eth.clone())).unwrap();
Expand All @@ -401,7 +381,9 @@ async fn new_server(db_client: Arc<dyn DatabaseClient>) -> (u16, ServerHandle) {
loop {
let port = port_check::free_local_port().unwrap();
if let Ok(server) = Server::builder().build(format!("0.0.0.0:{port}")).await {
return (port, server.start(module));
let client =
EthJsonRpcClient::new(ReqwestClient::new(format!("http://127.0.0.1:{port}")));
return (client, port, server.start(module));
}
}
}