2022-09-02 00:28:12 +00:00
|
|
|
use ethers::{
|
|
|
|
abi::AbiEncode,
|
2022-09-06 17:57:47 +00:00
|
|
|
types::{Address, Transaction, TransactionReceipt, H256},
|
2022-09-02 00:28:12 +00:00
|
|
|
};
|
2022-08-26 01:18:47 +00:00
|
|
|
use eyre::Result;
|
2022-11-02 03:52:28 +00:00
|
|
|
use log::{info, warn};
|
2022-08-27 00:05:12 +00:00
|
|
|
use std::{fmt::Display, net::SocketAddr, str::FromStr, sync::Arc};
|
2022-09-22 21:30:47 +00:00
|
|
|
use tokio::sync::RwLock;
|
2022-08-26 01:18:47 +00:00
|
|
|
|
|
|
|
use jsonrpsee::{
|
2022-08-31 21:40:44 +00:00
|
|
|
core::{async_trait, server::rpc_module::Methods, Error},
|
2022-08-26 01:18:47 +00:00
|
|
|
http_server::{HttpServerBuilder, HttpServerHandle},
|
|
|
|
proc_macros::rpc,
|
|
|
|
};
|
|
|
|
|
2022-09-29 23:35:43 +00:00
|
|
|
use crate::node::Node;
|
2022-09-10 04:01:23 +00:00
|
|
|
|
2022-09-29 23:35:43 +00:00
|
|
|
use common::{
|
|
|
|
types::BlockTag,
|
|
|
|
utils::{hex_str_to_bytes, u64_to_hex_string},
|
|
|
|
};
|
2022-09-01 19:58:45 +00:00
|
|
|
use execution::types::{CallOpts, ExecutionBlock};
|
2022-08-26 01:18:47 +00:00
|
|
|
|
|
|
|
pub struct Rpc {
|
2022-09-22 21:30:47 +00:00
|
|
|
node: Arc<RwLock<Node>>,
|
2022-08-26 01:18:47 +00:00
|
|
|
handle: Option<HttpServerHandle>,
|
2022-08-29 20:54:58 +00:00
|
|
|
port: u16,
|
2022-08-26 01:18:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Rpc {
|
2022-09-22 21:30:47 +00:00
|
|
|
pub fn new(node: Arc<RwLock<Node>>, port: u16) -> Self {
|
2022-08-26 01:18:47 +00:00
|
|
|
Rpc {
|
2022-09-10 04:01:23 +00:00
|
|
|
node,
|
2022-08-26 01:18:47 +00:00
|
|
|
handle: None,
|
2022-08-29 20:54:58 +00:00
|
|
|
port,
|
2022-08-26 01:18:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn start(&mut self) -> Result<SocketAddr> {
|
|
|
|
let rpc_inner = RpcInner {
|
2022-09-10 04:01:23 +00:00
|
|
|
node: self.node.clone(),
|
2022-08-29 20:54:58 +00:00
|
|
|
port: self.port,
|
2022-08-26 01:18:47 +00:00
|
|
|
};
|
|
|
|
let (handle, addr) = start(rpc_inner).await?;
|
|
|
|
self.handle = Some(handle);
|
2022-09-09 01:34:14 +00:00
|
|
|
|
2022-09-23 03:41:17 +00:00
|
|
|
info!("rpc server started at {}", addr);
|
2022-09-09 01:34:14 +00:00
|
|
|
|
2022-08-26 01:18:47 +00:00
|
|
|
Ok(addr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-29 23:35:43 +00:00
|
|
|
#[rpc(server, namespace = "eth")]
|
2022-08-26 01:18:47 +00:00
|
|
|
trait EthRpc {
|
|
|
|
#[method(name = "getBalance")]
|
2022-09-29 23:35:43 +00:00
|
|
|
async fn get_balance(&self, address: &str, block: BlockTag) -> Result<String, Error>;
|
2022-08-26 01:18:47 +00:00
|
|
|
#[method(name = "getTransactionCount")]
|
2022-09-29 23:35:43 +00:00
|
|
|
async fn get_transaction_count(&self, address: &str, block: BlockTag) -> Result<String, Error>;
|
2022-08-26 01:18:47 +00:00
|
|
|
#[method(name = "getCode")]
|
2022-09-29 23:35:43 +00:00
|
|
|
async fn get_code(&self, address: &str, block: BlockTag) -> Result<String, Error>;
|
2022-08-26 01:18:47 +00:00
|
|
|
#[method(name = "call")]
|
2022-09-29 23:35:43 +00:00
|
|
|
async fn call(&self, opts: CallOpts, block: BlockTag) -> Result<String, Error>;
|
2022-08-27 20:43:27 +00:00
|
|
|
#[method(name = "estimateGas")]
|
|
|
|
async fn estimate_gas(&self, opts: CallOpts) -> Result<String, Error>;
|
2022-08-27 00:05:12 +00:00
|
|
|
#[method(name = "chainId")]
|
2022-08-31 00:31:58 +00:00
|
|
|
async fn chain_id(&self) -> Result<String, Error>;
|
2022-08-29 15:59:02 +00:00
|
|
|
#[method(name = "gasPrice")]
|
|
|
|
async fn gas_price(&self) -> Result<String, Error>;
|
|
|
|
#[method(name = "maxPriorityFeePerGas")]
|
|
|
|
async fn max_priority_fee_per_gas(&self) -> Result<String, Error>;
|
2022-08-29 16:06:50 +00:00
|
|
|
#[method(name = "blockNumber")]
|
|
|
|
async fn block_number(&self) -> Result<String, Error>;
|
2022-08-31 21:40:44 +00:00
|
|
|
#[method(name = "getBlockByNumber")]
|
2022-09-23 03:19:24 +00:00
|
|
|
async fn get_block_by_number(
|
|
|
|
&self,
|
2022-09-29 23:35:43 +00:00
|
|
|
block: BlockTag,
|
2022-09-23 03:19:24 +00:00
|
|
|
full_tx: bool,
|
|
|
|
) -> Result<Option<ExecutionBlock>, Error>;
|
2022-09-02 04:13:22 +00:00
|
|
|
#[method(name = "getBlockByHash")]
|
2022-09-23 03:19:24 +00:00
|
|
|
async fn get_block_by_hash(
|
|
|
|
&self,
|
|
|
|
hash: &str,
|
|
|
|
full_tx: bool,
|
|
|
|
) -> Result<Option<ExecutionBlock>, Error>;
|
2022-09-01 21:07:30 +00:00
|
|
|
#[method(name = "sendRawTransaction")]
|
|
|
|
async fn send_raw_transaction(&self, bytes: &str) -> Result<String, Error>;
|
2022-09-02 00:28:12 +00:00
|
|
|
#[method(name = "getTransactionReceipt")]
|
2022-09-23 03:19:24 +00:00
|
|
|
async fn get_transaction_receipt(
|
|
|
|
&self,
|
|
|
|
hash: &str,
|
|
|
|
) -> Result<Option<TransactionReceipt>, Error>;
|
2022-09-02 03:28:37 +00:00
|
|
|
#[method(name = "getTransactionByHash")]
|
2022-09-23 03:19:24 +00:00
|
|
|
async fn get_transaction_by_hash(&self, hash: &str) -> Result<Option<Transaction>, Error>;
|
2022-08-26 01:18:47 +00:00
|
|
|
}
|
|
|
|
|
2022-08-31 21:40:44 +00:00
|
|
|
#[rpc(client, server, namespace = "net")]
|
|
|
|
trait NetRpc {
|
|
|
|
#[method(name = "version")]
|
|
|
|
async fn version(&self) -> Result<String, Error>;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone)]
|
2022-08-26 01:18:47 +00:00
|
|
|
struct RpcInner {
|
2022-09-22 21:30:47 +00:00
|
|
|
node: Arc<RwLock<Node>>,
|
2022-08-29 20:54:58 +00:00
|
|
|
port: u16,
|
2022-08-26 01:18:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait]
|
|
|
|
impl EthRpcServer for RpcInner {
|
2022-09-29 23:35:43 +00:00
|
|
|
async fn get_balance(&self, address: &str, block: BlockTag) -> Result<String, Error> {
|
2022-08-31 21:40:44 +00:00
|
|
|
let address = convert_err(Address::from_str(address))?;
|
2022-09-22 21:30:47 +00:00
|
|
|
let node = self.node.read().await;
|
2022-09-10 04:01:23 +00:00
|
|
|
let balance = convert_err(node.get_balance(&address, &block).await)?;
|
2022-08-26 01:18:47 +00:00
|
|
|
|
2022-08-31 21:40:44 +00:00
|
|
|
Ok(balance.encode_hex())
|
2022-08-26 01:18:47 +00:00
|
|
|
}
|
|
|
|
|
2022-09-29 23:35:43 +00:00
|
|
|
async fn get_transaction_count(&self, address: &str, block: BlockTag) -> Result<String, Error> {
|
2022-08-31 21:40:44 +00:00
|
|
|
let address = convert_err(Address::from_str(address))?;
|
2022-09-22 21:30:47 +00:00
|
|
|
let node = self.node.read().await;
|
2022-09-10 04:01:23 +00:00
|
|
|
let nonce = convert_err(node.get_nonce(&address, &block).await)?;
|
2022-08-26 01:18:47 +00:00
|
|
|
|
2022-08-31 21:40:44 +00:00
|
|
|
Ok(nonce.encode_hex())
|
2022-08-26 01:18:47 +00:00
|
|
|
}
|
|
|
|
|
2022-09-29 23:35:43 +00:00
|
|
|
async fn get_code(&self, address: &str, block: BlockTag) -> Result<String, Error> {
|
2022-08-31 21:40:44 +00:00
|
|
|
let address = convert_err(Address::from_str(address))?;
|
2022-09-22 21:30:47 +00:00
|
|
|
let node = self.node.read().await;
|
2022-09-10 04:01:23 +00:00
|
|
|
let code = convert_err(node.get_code(&address, &block).await)?;
|
2022-08-26 01:18:47 +00:00
|
|
|
|
2022-08-31 21:40:44 +00:00
|
|
|
Ok(hex::encode(code))
|
2022-08-26 01:18:47 +00:00
|
|
|
}
|
|
|
|
|
2022-09-29 23:35:43 +00:00
|
|
|
async fn call(&self, opts: CallOpts, block: BlockTag) -> Result<String, Error> {
|
2022-09-22 21:30:47 +00:00
|
|
|
let node = self.node.read().await;
|
2022-09-10 04:01:23 +00:00
|
|
|
let res = convert_err(node.call(&opts, &block))?;
|
2022-08-31 21:40:44 +00:00
|
|
|
|
2022-09-01 19:58:45 +00:00
|
|
|
Ok(format!("0x{}", hex::encode(res)))
|
2022-08-26 01:18:47 +00:00
|
|
|
}
|
2022-08-27 00:05:12 +00:00
|
|
|
|
2022-08-27 20:43:27 +00:00
|
|
|
async fn estimate_gas(&self, opts: CallOpts) -> Result<String, Error> {
|
2022-09-22 21:30:47 +00:00
|
|
|
let node = self.node.read().await;
|
2022-09-10 04:01:23 +00:00
|
|
|
let gas = convert_err(node.estimate_gas(&opts))?;
|
2022-09-01 19:58:45 +00:00
|
|
|
|
2022-08-27 20:43:27 +00:00
|
|
|
Ok(u64_to_hex_string(gas))
|
|
|
|
}
|
|
|
|
|
2022-08-31 00:31:58 +00:00
|
|
|
async fn chain_id(&self) -> Result<String, Error> {
|
2022-09-22 21:30:47 +00:00
|
|
|
let node = self.node.read().await;
|
2022-09-10 04:01:23 +00:00
|
|
|
let id = node.chain_id();
|
2022-08-27 00:05:12 +00:00
|
|
|
Ok(u64_to_hex_string(id))
|
|
|
|
}
|
2022-08-29 15:59:02 +00:00
|
|
|
|
|
|
|
async fn gas_price(&self) -> Result<String, Error> {
|
2022-09-22 21:30:47 +00:00
|
|
|
let node = self.node.read().await;
|
2022-09-10 04:01:23 +00:00
|
|
|
let gas_price = convert_err(node.get_gas_price())?;
|
2022-08-29 15:59:02 +00:00
|
|
|
Ok(gas_price.encode_hex())
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn max_priority_fee_per_gas(&self) -> Result<String, Error> {
|
2022-09-22 21:30:47 +00:00
|
|
|
let node = self.node.read().await;
|
2022-09-10 04:01:23 +00:00
|
|
|
let tip = convert_err(node.get_priority_fee())?;
|
2022-08-29 15:59:02 +00:00
|
|
|
Ok(tip.encode_hex())
|
|
|
|
}
|
2022-08-29 16:06:50 +00:00
|
|
|
|
|
|
|
async fn block_number(&self) -> Result<String, Error> {
|
2022-09-22 21:30:47 +00:00
|
|
|
let node = self.node.read().await;
|
2022-09-10 04:01:23 +00:00
|
|
|
let num = convert_err(node.get_block_number())?;
|
2022-08-29 16:06:50 +00:00
|
|
|
Ok(u64_to_hex_string(num))
|
|
|
|
}
|
2022-08-31 21:40:44 +00:00
|
|
|
|
|
|
|
async fn get_block_by_number(
|
|
|
|
&self,
|
2022-09-29 23:35:43 +00:00
|
|
|
block: BlockTag,
|
2022-10-27 17:46:32 +00:00
|
|
|
full_tx: bool,
|
2022-09-23 03:19:24 +00:00
|
|
|
) -> Result<Option<ExecutionBlock>, Error> {
|
2022-09-22 21:30:47 +00:00
|
|
|
let node = self.node.read().await;
|
2022-10-27 17:46:32 +00:00
|
|
|
let block = convert_err(node.get_block_by_number(&block, full_tx).await)?;
|
2022-08-31 21:40:44 +00:00
|
|
|
Ok(block)
|
|
|
|
}
|
2022-09-01 21:07:30 +00:00
|
|
|
|
2022-09-23 03:19:24 +00:00
|
|
|
async fn get_block_by_hash(
|
|
|
|
&self,
|
|
|
|
hash: &str,
|
2022-10-27 17:46:32 +00:00
|
|
|
full_tx: bool,
|
2022-09-23 03:19:24 +00:00
|
|
|
) -> Result<Option<ExecutionBlock>, Error> {
|
2022-09-02 04:13:22 +00:00
|
|
|
let hash = convert_err(hex_str_to_bytes(hash))?;
|
2022-09-22 21:30:47 +00:00
|
|
|
let node = self.node.read().await;
|
2022-10-27 17:46:32 +00:00
|
|
|
let block = convert_err(node.get_block_by_hash(&hash, full_tx).await)?;
|
2022-09-02 04:13:22 +00:00
|
|
|
Ok(block)
|
|
|
|
}
|
|
|
|
|
2022-09-01 21:07:30 +00:00
|
|
|
async fn send_raw_transaction(&self, bytes: &str) -> Result<String, Error> {
|
2022-09-22 21:30:47 +00:00
|
|
|
let node = self.node.read().await;
|
2022-09-01 21:07:30 +00:00
|
|
|
let bytes = convert_err(hex_str_to_bytes(bytes))?;
|
2022-09-10 04:01:23 +00:00
|
|
|
let tx_hash = convert_err(node.send_raw_transaction(&bytes).await)?;
|
2022-09-01 21:07:30 +00:00
|
|
|
Ok(hex::encode(tx_hash))
|
|
|
|
}
|
2022-09-02 00:28:12 +00:00
|
|
|
|
2022-09-23 03:19:24 +00:00
|
|
|
async fn get_transaction_receipt(
|
|
|
|
&self,
|
|
|
|
hash: &str,
|
|
|
|
) -> Result<Option<TransactionReceipt>, Error> {
|
2022-09-22 21:30:47 +00:00
|
|
|
let node = self.node.read().await;
|
2022-09-06 17:57:47 +00:00
|
|
|
let hash = H256::from_slice(&convert_err(hex_str_to_bytes(hash))?);
|
2022-09-10 04:01:23 +00:00
|
|
|
let receipt = convert_err(node.get_transaction_receipt(&hash).await)?;
|
2022-09-23 03:19:24 +00:00
|
|
|
Ok(receipt)
|
2022-09-02 00:28:12 +00:00
|
|
|
}
|
2022-09-02 03:28:37 +00:00
|
|
|
|
2022-09-23 03:19:24 +00:00
|
|
|
async fn get_transaction_by_hash(&self, hash: &str) -> Result<Option<Transaction>, Error> {
|
2022-09-22 21:30:47 +00:00
|
|
|
let node = self.node.read().await;
|
2022-09-06 17:57:47 +00:00
|
|
|
let hash = H256::from_slice(&convert_err(hex_str_to_bytes(hash))?);
|
2022-09-23 03:19:24 +00:00
|
|
|
convert_err(node.get_transaction_by_hash(&hash).await)
|
2022-09-02 03:28:37 +00:00
|
|
|
}
|
2022-08-31 21:40:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[async_trait]
|
|
|
|
impl NetRpcServer for RpcInner {
|
|
|
|
async fn version(&self) -> Result<String, Error> {
|
2022-09-22 21:30:47 +00:00
|
|
|
let node = self.node.read().await;
|
2022-09-10 04:01:23 +00:00
|
|
|
Ok(node.chain_id().to_string())
|
2022-08-31 21:40:44 +00:00
|
|
|
}
|
2022-08-26 01:18:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async fn start(rpc: RpcInner) -> Result<(HttpServerHandle, SocketAddr)> {
|
2022-08-29 20:54:58 +00:00
|
|
|
let addr = format!("127.0.0.1:{}", rpc.port);
|
|
|
|
let server = HttpServerBuilder::default().build(addr).await?;
|
2022-08-26 01:18:47 +00:00
|
|
|
|
|
|
|
let addr = server.local_addr()?;
|
2022-08-31 21:40:44 +00:00
|
|
|
|
|
|
|
let mut methods = Methods::new();
|
|
|
|
let eth_methods: Methods = EthRpcServer::into_rpc(rpc.clone()).into();
|
|
|
|
let net_methods: Methods = NetRpcServer::into_rpc(rpc).into();
|
|
|
|
|
|
|
|
methods.merge(eth_methods)?;
|
|
|
|
methods.merge(net_methods)?;
|
|
|
|
|
|
|
|
let handle = server.start(methods)?;
|
2022-08-26 01:18:47 +00:00
|
|
|
|
|
|
|
Ok((handle, addr))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn convert_err<T, E: Display>(res: Result<T, E>) -> Result<T, Error> {
|
2022-08-31 21:40:44 +00:00
|
|
|
res.map_err(|err| {
|
2022-09-10 04:01:23 +00:00
|
|
|
warn!("{}", err);
|
2022-08-31 21:40:44 +00:00
|
|
|
Error::Custom(err.to_string())
|
|
|
|
})
|
|
|
|
}
|