Skip to content

Commit

Permalink
add test
Browse files Browse the repository at this point in the history
  • Loading branch information
pgherveou committed Oct 23, 2024
1 parent 80182e3 commit bf00157
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 13 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions substrate/frame/revive/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,8 @@ dev = []
example = ["hex", "hex-literal", "rlp", "secp256k1", "subxt-signer"]

[dev-dependencies]
pallet-revive = { workspace = true, default-features = true, features = ["riscv"] }
hex-literal = { workspace = true }
pallet-revive-fixtures = { workspace = true }
substrate-cli-test-utils = { workspace = true }
assert_cmd = { workspace = true }
10 changes: 6 additions & 4 deletions substrate/frame/revive/rpc/src/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//! Example utilities
#![cfg(feature = "example")]
#![cfg(any(feature = "example", test))]

use crate::{EthRpcClient, ReceiptInfo};
use anyhow::Context;
use jsonrpsee::http_client::HttpClient;
use pallet_revive::evm::{
rlp::*, Account, BlockTag, Bytes, GenericTransaction, TransactionLegacyUnsigned, H160, H256,
U256,
};

/// Wait for a transaction receipt.
pub async fn wait_for_receipt(client: &HttpClient, hash: H256) -> anyhow::Result<ReceiptInfo> {
pub async fn wait_for_receipt(
client: &(impl EthRpcClient + Send + Sync),
hash: H256,
) -> anyhow::Result<ReceiptInfo> {
for _ in 0..6 {
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
let receipt = client.get_transaction_receipt(hash).await?;
Expand All @@ -41,7 +43,7 @@ pub async fn wait_for_receipt(client: &HttpClient, hash: H256) -> anyhow::Result
/// Send a transaction.
pub async fn send_transaction(
signer: &Account,
client: &HttpClient,
client: &(impl EthRpcClient + Send + Sync),
value: U256,
input: Bytes,
to: Option<H160>,
Expand Down
3 changes: 3 additions & 0 deletions substrate/frame/revive/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ pub mod client;
pub mod example;
pub mod subxt_client;

#[cfg(test)]
mod tests;

mod rpc_methods_gen;
pub use rpc_methods_gen::*;

Expand Down
18 changes: 9 additions & 9 deletions substrate/frame/revive/rpc/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ use tracing_subscriber::{util::SubscriberInitExt, EnvFilter, FmtSubscriber};
#[clap(author, about, version)]
struct CliCommand {
/// The server address to bind to
#[clap(long, default_value = "127.0.0.1:9090")]
url: String,
#[clap(long, default_value = "9090")]
rpc_port: String,

/// The node url to connect to
#[clap(long, default_value = "ws://127.0.0.1:9944")]
node_url: String,
node_rpc_url: String,
}

/// Initialize tracing
Expand All @@ -56,20 +56,20 @@ fn init_tracing() {

#[tokio::main]
async fn main() -> anyhow::Result<()> {
let CliCommand { url, node_url } = CliCommand::parse();
let CliCommand { rpc_port, node_rpc_url } = CliCommand::parse();
init_tracing();

let client = Client::from_url(&node_url).await?;
let client = Client::from_url(&node_rpc_url).await?;
let mut updates = client.updates.clone();

let server_addr = run_server(client, &url).await?;
log::info!(target: LOG_TARGET, "Server started on: {}", server_addr);
let server_addr = run_server(client, &format!("127.0.0.1:{rpc_port}")).await?;
log::info!("Running JSON-RPC server: addr={server_addr},");

let url = format!("http://{}", server_addr);
let client = HttpClientBuilder::default().build(url)?;

let response = client.block_number().await?;
log::info!(target: LOG_TARGET, "client initialized with block number {:?}", response);
log::info!(target: LOG_TARGET, "Client initialized with block number {:?}", response);

// keep running server until ctrl-c or client subscription fails
let _ = updates.wait_for(|_| false).await;
Expand Down Expand Up @@ -99,7 +99,7 @@ mod dev {
let params = req.params.clone().unwrap_or_default();

async move {
log::info!(target: LOG_TARGET, "method: {method} params: {params}");
log::info!(target: LOG_TARGET, "Method: {method} params: {params}");
let resp = service.call(req).await;
if resp.is_success() {
log::info!(target: LOG_TARGET, "✅ rpc: {method}");
Expand Down
79 changes: 79 additions & 0 deletions substrate/frame/revive/rpc/src/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use crate::{
example::{send_transaction, wait_for_receipt},
EthRpcClient,
};
use assert_cmd::cargo::cargo_bin;
use jsonrpsee::ws_client::WsClientBuilder;
use pallet_revive::{
create1,
evm::{Account, BlockTag, Bytes, U256},
};
use std::{
io::{BufRead, BufReader},
process::{self, Child, Command},
};
use substrate_cli_test_utils::*;

/// Start eth-rpc server, and return the child process and the WebSocket URL.
fn start_eth_rpc_server(node_ws_url: &str) -> (Child, String) {
let mut child = Command::new(cargo_bin("eth-rpc"))
.stdout(process::Stdio::piped())
.stderr(process::Stdio::piped())
.env("RUST_LOG", "info,eth-rpc=debug")
.args(&["--rpc-port=45788", &format!("--node-rpc-url={node_ws_url}")])
.spawn()
.unwrap();

let mut data = String::new();
let ws_url = BufReader::new(child.stdout.take().unwrap())
.lines()
.find_map(|line| {
let line = line.expect("failed to obtain next line while extracting node info");
data.push_str(&line);
data.push_str("\n");

// does the line contain our port (we expect this specific output from eth-rpc).
let sock_addr = match line.split_once("Running JSON-RPC server: addr=") {
None => return None,
Some((_, after)) => after.split_once(",").unwrap().0,
};

Some(format!("ws://{}", sock_addr))
})
.unwrap_or_else(|| {
eprintln!("Observed eth-rpc output:\n{}", data);
panic!("We should get a WebSocket address")
});

(child, ws_url)
}

#[tokio::test]
async fn test_jsonrpsee_server() -> anyhow::Result<()> {
let mut node_child = substrate_cli_test_utils::start_node();
let (info, _) = extract_info_from_output(node_child.stderr.take().unwrap());
let (_rpc_child, ws_url) = start_eth_rpc_server(&info.ws_url);

let data = b"hello world".to_vec();
let (bytes, _) = pallet_revive_fixtures::compile_module("dummy")?;
let input = bytes.into_iter().chain(data.clone()).collect::<Vec<u8>>();

let account = Account::default();
let client = WsClientBuilder::default().build(ws_url).await?;

// Deploy contract
let nonce = client.get_transaction_count(account.address(), BlockTag::Latest.into()).await?;
let hash = send_transaction(&account, &client, U256::zero(), input.into(), None).await?;
let receipt = wait_for_receipt(&client, hash).await?;
let contract_address = create1(&account.address(), nonce.try_into().unwrap());
assert_eq!(contract_address, receipt.contract_address.unwrap());

// Call contract
let hash =
send_transaction(&account, &client, U256::zero(), Bytes::default(), Some(contract_address))
.await?;
let receipt = wait_for_receipt(&client, hash).await?;
assert_eq!(contract_address, receipt.to.unwrap());

Ok(())
}

0 comments on commit bf00157

Please sign in to comment.