expose basic rpc api
This commit is contained in:
parent
072142b88f
commit
e18aa704e1
|
@ -1,14 +1,16 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ethers::prelude::{Address, U256};
|
use ethers::prelude::{Address, U256};
|
||||||
use eyre::Result;
|
use eyre::Result;
|
||||||
|
|
||||||
use crate::consensus::types::Header;
|
use crate::consensus::types::Header;
|
||||||
use crate::consensus::ConsensusClient;
|
use crate::consensus::ConsensusClient;
|
||||||
use crate::execution::ExecutionClient;
|
|
||||||
use crate::execution::evm::Evm;
|
use crate::execution::evm::Evm;
|
||||||
|
use crate::execution::ExecutionClient;
|
||||||
|
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
consensus: ConsensusClient,
|
consensus: ConsensusClient,
|
||||||
execution: ExecutionClient,
|
execution: Arc<ExecutionClient>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
|
@ -22,7 +24,7 @@ impl Client {
|
||||||
|
|
||||||
Ok(Client {
|
Ok(Client {
|
||||||
consensus,
|
consensus,
|
||||||
execution,
|
execution: Arc::new(execution),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,30 +32,30 @@ impl Client {
|
||||||
self.consensus.sync().await
|
self.consensus.sync().await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn call(&mut self, to: &Address, calldata: &Vec<u8>, value: U256) -> Result<Vec<u8>> {
|
pub async fn call(&self, to: &Address, calldata: &Vec<u8>, value: U256) -> Result<Vec<u8>> {
|
||||||
let payload = self.consensus.get_execution_payload().await?;
|
let payload = self.consensus.get_execution_payload().await?;
|
||||||
let mut evm = Evm::new(self.execution.clone(), payload);
|
let mut evm = Evm::new(self.execution.clone(), payload);
|
||||||
evm.call(to, calldata, value)
|
evm.call(to, calldata, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_balance(&mut self, address: &Address) -> Result<U256> {
|
pub async fn get_balance(&self, address: &Address) -> Result<U256> {
|
||||||
let payload = self.consensus.get_execution_payload().await?;
|
let payload = self.consensus.get_execution_payload().await?;
|
||||||
let account = self.execution.get_account(&address, None, &payload).await?;
|
let account = self.execution.get_account(&address, None, &payload).await?;
|
||||||
Ok(account.balance)
|
Ok(account.balance)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_nonce(&mut self, address: &Address) -> Result<U256> {
|
pub async fn get_nonce(&self, address: &Address) -> Result<U256> {
|
||||||
let payload = self.consensus.get_execution_payload().await?;
|
let payload = self.consensus.get_execution_payload().await?;
|
||||||
let account = self.execution.get_account(&address, None, &payload).await?;
|
let account = self.execution.get_account(&address, None, &payload).await?;
|
||||||
Ok(account.nonce)
|
Ok(account.nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_code(&mut self, address: &Address) -> Result<Vec<u8>> {
|
pub async fn get_code(&self, address: &Address) -> Result<Vec<u8>> {
|
||||||
let payload = self.consensus.get_execution_payload().await?;
|
let payload = self.consensus.get_execution_payload().await?;
|
||||||
self.execution.get_code(&address, &payload).await
|
self.execution.get_code(&address, &payload).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_storage_at(&mut self, address: &Address, slot: U256) -> Result<U256> {
|
pub async fn get_storage_at(&self, address: &Address, slot: U256) -> Result<U256> {
|
||||||
let payload = self.consensus.get_execution_payload().await?;
|
let payload = self.consensus.get_execution_payload().await?;
|
||||||
let account = self
|
let account = self
|
||||||
.execution
|
.execution
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
mod client;
|
mod client;
|
||||||
pub use client::*;
|
pub use client::*;
|
||||||
|
|
||||||
|
pub mod rpc;
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
use ethers::{abi::AbiEncode, types::{Address, U256}};
|
||||||
|
use eyre::Result;
|
||||||
|
use std::{fmt::Display, net::SocketAddr, str::FromStr, sync::Arc};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use jsonrpsee::{
|
||||||
|
core::{async_trait, Error},
|
||||||
|
http_server::{HttpServerBuilder, HttpServerHandle},
|
||||||
|
proc_macros::rpc,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::common::utils::hex_str_to_bytes;
|
||||||
|
|
||||||
|
use super::Client;
|
||||||
|
|
||||||
|
pub struct Rpc {
|
||||||
|
client: Arc<Client>,
|
||||||
|
handle: Option<HttpServerHandle>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rpc {
|
||||||
|
pub fn new(client: Arc<Client>) -> Self {
|
||||||
|
Rpc {
|
||||||
|
client,
|
||||||
|
handle: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn start(&mut self) -> Result<SocketAddr> {
|
||||||
|
let rpc_inner = RpcInner {
|
||||||
|
client: self.client.clone(),
|
||||||
|
};
|
||||||
|
let (handle, addr) = start(rpc_inner).await?;
|
||||||
|
self.handle = Some(handle);
|
||||||
|
Ok(addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rpc(client, server, namespace = "eth")]
|
||||||
|
trait EthRpc {
|
||||||
|
#[method(name = "getBalance")]
|
||||||
|
async fn get_balance(&self, address: &str, block: &str) -> Result<String, Error>;
|
||||||
|
#[method(name = "getTransactionCount")]
|
||||||
|
async fn get_transaction_count(&self, address: &str, block: &str) -> Result<String, Error>;
|
||||||
|
#[method(name = "getCode")]
|
||||||
|
async fn get_code(&self, address: &str, block: &str) -> Result<String, Error>;
|
||||||
|
#[method(name = "call")]
|
||||||
|
async fn call(&self, opts: CallOpts, block: &str) -> Result<String, Error>;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RpcInner {
|
||||||
|
pub client: Arc<Client>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl EthRpcServer for RpcInner {
|
||||||
|
async fn get_balance(&self, address: &str, block: &str) -> Result<String, Error> {
|
||||||
|
match block {
|
||||||
|
"latest" => {
|
||||||
|
let address = convert_err(Address::from_str(address))?;
|
||||||
|
let balance = convert_err(self.client.get_balance(&address).await)?;
|
||||||
|
|
||||||
|
Ok(balance.encode_hex())
|
||||||
|
}
|
||||||
|
_ => Err(Error::Custom("Invalid Block Number".to_string())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_transaction_count(&self, address: &str, block: &str) -> Result<String, Error> {
|
||||||
|
match block {
|
||||||
|
"latest" => {
|
||||||
|
let address = convert_err(Address::from_str(address))?;
|
||||||
|
let nonce = convert_err(self.client.get_nonce(&address).await)?;
|
||||||
|
|
||||||
|
Ok(nonce.encode_hex())
|
||||||
|
}
|
||||||
|
_ => Err(Error::Custom("Invalid Block Number".to_string())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_code(&self, address: &str, block: &str) -> Result<String, Error> {
|
||||||
|
match block {
|
||||||
|
"latest" => {
|
||||||
|
let address = convert_err(Address::from_str(address))?;
|
||||||
|
let code = convert_err(self.client.get_code(&address).await)?;
|
||||||
|
|
||||||
|
Ok(hex::encode(code))
|
||||||
|
}
|
||||||
|
_ => Err(Error::Custom("Invalid Block Number".to_string())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn call(&self, opts: CallOpts, block: &str) -> Result<String, Error> {
|
||||||
|
match block {
|
||||||
|
"latest" => {
|
||||||
|
let to = convert_err(Address::from_str(&opts.to))?;
|
||||||
|
let data = convert_err(hex_str_to_bytes(&opts.data.unwrap_or("0x".to_string())))?;
|
||||||
|
let value = convert_err(U256::from_str_radix(&opts.value.unwrap_or("0x0".to_string()), 16))?;
|
||||||
|
|
||||||
|
let res = convert_err(self.client.call(&to, &data, value).await)?;
|
||||||
|
Ok(hex::encode(res))
|
||||||
|
},
|
||||||
|
_ => Err(Error::Custom("Invalid Block Number".to_string())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn start(rpc: RpcInner) -> Result<(HttpServerHandle, SocketAddr)> {
|
||||||
|
let server = HttpServerBuilder::default().build("127.0.0.1:8545").await?;
|
||||||
|
|
||||||
|
let addr = server.local_addr()?;
|
||||||
|
let handle = server.start(rpc.into_rpc())?;
|
||||||
|
|
||||||
|
Ok((handle, addr))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_err<T, E: Display>(res: Result<T, E>) -> Result<T, Error> {
|
||||||
|
res.map_err(|err| Error::Custom(err.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct CallOpts {
|
||||||
|
from: Option<String>,
|
||||||
|
to: String,
|
||||||
|
gas: Option<String>,
|
||||||
|
value: Option<String>,
|
||||||
|
data: Option<String>,
|
||||||
|
}
|
|
@ -47,11 +47,11 @@ impl ConsensusClient {
|
||||||
Ok(ConsensusClient { rpc, store })
|
Ok(ConsensusClient { rpc, store })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_execution_payload(&mut self) -> Result<ExecutionPayload> {
|
pub async fn get_execution_payload(&self) -> Result<ExecutionPayload> {
|
||||||
let slot = self.store.header.slot;
|
let slot = self.store.header.slot;
|
||||||
let mut block = self.rpc.get_block(slot).await?;
|
let mut block = self.rpc.get_block(slot).await?.clone();
|
||||||
let block_hash = block.hash_tree_root()?;
|
let block_hash = block.hash_tree_root()?;
|
||||||
let verified_block_hash = self.store.header.hash_tree_root()?;
|
let verified_block_hash = self.store.header.clone().hash_tree_root()?;
|
||||||
|
|
||||||
if verified_block_hash != block_hash {
|
if verified_block_hash != block_hash {
|
||||||
Err(eyre::eyre!("Block Root Mismatch"))
|
Err(eyre::eyre!("Block Root Mismatch"))
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub type Address = Vector<u8, 20>;
|
||||||
pub type LogsBloom = Vector<u8, 256>;
|
pub type LogsBloom = Vector<u8, 256>;
|
||||||
pub type Transaction = List<u8, 1073741824>;
|
pub type Transaction = List<u8, 1073741824>;
|
||||||
|
|
||||||
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize)]
|
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
|
||||||
pub struct BeaconBlock {
|
pub struct BeaconBlock {
|
||||||
#[serde(deserialize_with = "u64_deserialize")]
|
#[serde(deserialize_with = "u64_deserialize")]
|
||||||
pub slot: u64,
|
pub slot: u64,
|
||||||
|
@ -24,7 +24,7 @@ pub struct BeaconBlock {
|
||||||
pub body: BeaconBlockBody,
|
pub body: BeaconBlockBody,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize)]
|
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
|
||||||
pub struct BeaconBlockBody {
|
pub struct BeaconBlockBody {
|
||||||
#[serde(deserialize_with = "signature_deserialize")]
|
#[serde(deserialize_with = "signature_deserialize")]
|
||||||
randao_reveal: SignatureBytes,
|
randao_reveal: SignatureBytes,
|
||||||
|
@ -44,7 +44,7 @@ pub struct BeaconBlockBody {
|
||||||
pub execution_payload: ExecutionPayload,
|
pub execution_payload: ExecutionPayload,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize)]
|
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
|
||||||
pub struct ExecutionPayload {
|
pub struct ExecutionPayload {
|
||||||
#[serde(deserialize_with = "bytes32_deserialize")]
|
#[serde(deserialize_with = "bytes32_deserialize")]
|
||||||
parent_hash: Bytes32,
|
parent_hash: Bytes32,
|
||||||
|
@ -76,7 +76,7 @@ pub struct ExecutionPayload {
|
||||||
transactions: List<Transaction, 1048576>,
|
transactions: List<Transaction, 1048576>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize)]
|
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
|
||||||
struct Attestation {
|
struct Attestation {
|
||||||
aggregation_bits: Bitlist<2048>,
|
aggregation_bits: Bitlist<2048>,
|
||||||
data: AttestationData,
|
data: AttestationData,
|
||||||
|
@ -84,7 +84,7 @@ struct Attestation {
|
||||||
signature: SignatureBytes,
|
signature: SignatureBytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize)]
|
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
|
||||||
struct AttestationData {
|
struct AttestationData {
|
||||||
#[serde(deserialize_with = "u64_deserialize")]
|
#[serde(deserialize_with = "u64_deserialize")]
|
||||||
slot: u64,
|
slot: u64,
|
||||||
|
@ -96,7 +96,7 @@ struct AttestationData {
|
||||||
target: Checkpoint,
|
target: Checkpoint,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize)]
|
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
|
||||||
struct Checkpoint {
|
struct Checkpoint {
|
||||||
#[serde(deserialize_with = "u64_deserialize")]
|
#[serde(deserialize_with = "u64_deserialize")]
|
||||||
epoch: u64,
|
epoch: u64,
|
||||||
|
@ -104,12 +104,12 @@ struct Checkpoint {
|
||||||
root: Bytes32,
|
root: Bytes32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize)]
|
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
|
||||||
struct Dummy {
|
struct Dummy {
|
||||||
t: u64,
|
t: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize)]
|
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
|
||||||
pub struct Eth1Data {
|
pub struct Eth1Data {
|
||||||
#[serde(deserialize_with = "bytes32_deserialize")]
|
#[serde(deserialize_with = "bytes32_deserialize")]
|
||||||
deposit_root: Bytes32,
|
deposit_root: Bytes32,
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
use std::str::FromStr;
|
use std::{str::FromStr, sync::Arc, thread};
|
||||||
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
use ethers::prelude::{Address, H160, H256, U256};
|
||||||
use eyre::Result;
|
use eyre::Result;
|
||||||
use ethers::prelude::{U256, H256, H160, Address};
|
use revm::{AccountInfo, Bytecode, Database, Env, TransactOut, TransactTo, EVM};
|
||||||
use revm::{Database, Bytecode, AccountInfo, EVM, Env, TransactTo, TransactOut};
|
use tokio::runtime::Runtime;
|
||||||
use futures::executor::block_on;
|
|
||||||
|
|
||||||
use crate::consensus::types::ExecutionPayload;
|
|
||||||
use super::ExecutionClient;
|
use super::ExecutionClient;
|
||||||
|
use crate::consensus::types::ExecutionPayload;
|
||||||
|
|
||||||
pub struct Evm {
|
pub struct Evm {
|
||||||
evm: EVM<ProofDB>
|
evm: EVM<ProofDB>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Evm {
|
impl Evm {
|
||||||
pub fn new(execution: ExecutionClient, payload: ExecutionPayload) -> Self {
|
pub fn new(execution: Arc<ExecutionClient>, payload: ExecutionPayload) -> Self {
|
||||||
let mut evm: EVM<ProofDB> = EVM::new();
|
let mut evm: EVM<ProofDB> = EVM::new();
|
||||||
let db = ProofDB::new(execution, payload);
|
let db = ProofDB::new(execution, payload);
|
||||||
evm.database(db);
|
evm.database(db);
|
||||||
|
@ -23,7 +23,6 @@ impl Evm {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call(&mut self, to: &Address, calldata: &Vec<u8>, value: U256) -> Result<Vec<u8>> {
|
pub fn call(&mut self, to: &Address, calldata: &Vec<u8>, value: U256) -> Result<Vec<u8>> {
|
||||||
|
|
||||||
let mut env = Env::default();
|
let mut env = Env::default();
|
||||||
let mut tx = revm::TxEnv::default();
|
let mut tx = revm::TxEnv::default();
|
||||||
tx.transact_to = TransactTo::Call(*to);
|
tx.transact_to = TransactTo::Call(*to);
|
||||||
|
@ -48,13 +47,13 @@ impl Evm {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProofDB {
|
struct ProofDB {
|
||||||
execution: ExecutionClient,
|
execution: Arc<ExecutionClient>,
|
||||||
payload: ExecutionPayload,
|
payload: ExecutionPayload,
|
||||||
error: Option<String>,
|
error: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProofDB {
|
impl ProofDB {
|
||||||
pub fn new(execution: ExecutionClient, payload: ExecutionPayload) -> Self {
|
pub fn new(execution: Arc<ExecutionClient>, payload: ExecutionPayload) -> Self {
|
||||||
ProofDB {
|
ProofDB {
|
||||||
execution,
|
execution,
|
||||||
payload,
|
payload,
|
||||||
|
@ -68,7 +67,7 @@ impl ProofDB {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
self.error = Some(err.to_string());
|
self.error = Some(err.to_string());
|
||||||
T::default()
|
T::default()
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,14 +76,32 @@ impl Database for ProofDB {
|
||||||
fn basic(&mut self, address: H160) -> AccountInfo {
|
fn basic(&mut self, address: H160) -> AccountInfo {
|
||||||
|
|
||||||
if is_precompile(&address) {
|
if is_precompile(&address) {
|
||||||
return AccountInfo::default()
|
return AccountInfo::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
let account_future = self.execution.get_account(&address, None, &self.payload);
|
let execution = self.execution.clone();
|
||||||
let account = self.safe_unwrap(block_on(account_future));
|
let addr = address.clone();
|
||||||
|
let payload = self.payload.clone();
|
||||||
|
|
||||||
let bytecode_future = self.execution.get_code(&address, &self.payload);
|
let handle = thread::spawn(move || {
|
||||||
let bytecode = self.safe_unwrap(block_on(bytecode_future));
|
let account_fut = execution.get_account(&addr, None, &payload);
|
||||||
|
let runtime = Runtime::new()?;
|
||||||
|
runtime.block_on(account_fut)
|
||||||
|
});
|
||||||
|
|
||||||
|
let account = self.safe_unwrap(handle.join().unwrap());
|
||||||
|
|
||||||
|
let execution = self.execution.clone();
|
||||||
|
let addr = address.clone();
|
||||||
|
let payload = self.payload.clone();
|
||||||
|
|
||||||
|
let handle = thread::spawn(move || {
|
||||||
|
let code_fut = execution.get_code(&addr, &payload);
|
||||||
|
let runtime = Runtime::new()?;
|
||||||
|
runtime.block_on(code_fut)
|
||||||
|
});
|
||||||
|
|
||||||
|
let bytecode = self.safe_unwrap(handle.join().unwrap());
|
||||||
let bytecode = Bytecode::new_raw(Bytes::from(bytecode));
|
let bytecode = Bytecode::new_raw(Bytes::from(bytecode));
|
||||||
|
|
||||||
AccountInfo::new(account.balance, account.nonce.as_u64(), bytecode)
|
AccountInfo::new(account.balance, account.nonce.as_u64(), bytecode)
|
||||||
|
@ -95,10 +112,19 @@ impl Database for ProofDB {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn storage(&mut self, address: H160, slot: U256) -> U256 {
|
fn storage(&mut self, address: H160, slot: U256) -> U256 {
|
||||||
let slots = [slot];
|
|
||||||
let account_future = self.execution.get_account(&address, Some(&slots), &self.payload);
|
|
||||||
let account = self.safe_unwrap(block_on(account_future));
|
|
||||||
|
|
||||||
|
let execution = self.execution.clone();
|
||||||
|
let addr = address.clone();
|
||||||
|
let slots = [slot];
|
||||||
|
let payload = self.payload.clone();
|
||||||
|
|
||||||
|
let handle = thread::spawn(move || {
|
||||||
|
let account_fut = execution.get_account(&addr, Some(&slots), &payload);
|
||||||
|
let runtime = Runtime::new()?;
|
||||||
|
runtime.block_on(account_fut)
|
||||||
|
});
|
||||||
|
|
||||||
|
let account = self.safe_unwrap(handle.join().unwrap());
|
||||||
*account.slots.get(&slot).unwrap()
|
*account.slots.get(&slot).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ impl ExecutionClient {
|
||||||
payload: &ExecutionPayload,
|
payload: &ExecutionPayload,
|
||||||
) -> Result<Account> {
|
) -> Result<Account> {
|
||||||
let slots = slots.unwrap_or(&[]);
|
let slots = slots.unwrap_or(&[]);
|
||||||
|
|
||||||
let proof = self
|
let proof = self
|
||||||
.rpc
|
.rpc
|
||||||
.get_proof(&address, slots, payload.block_number)
|
.get_proof(&address, slots, payload.block_number)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
pub mod types;
|
|
||||||
pub mod evm;
|
pub mod evm;
|
||||||
|
pub mod types;
|
||||||
|
|
||||||
mod execution;
|
mod execution;
|
||||||
pub use execution::*;
|
pub use execution::*;
|
||||||
|
|
|
@ -29,7 +29,7 @@ pub struct StorageProof {
|
||||||
pub proof: Vec<Vec<u8>>,
|
pub proof: Vec<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Debug)]
|
||||||
pub struct Account {
|
pub struct Account {
|
||||||
pub balance: U256,
|
pub balance: U256,
|
||||||
pub nonce: U256,
|
pub nonce: U256,
|
||||||
|
|
29
src/main.rs
29
src/main.rs
|
@ -1,11 +1,9 @@
|
||||||
use std::str::FromStr;
|
use std::{sync::Arc, time::Duration};
|
||||||
|
|
||||||
use ethers::prelude::{Address, U256};
|
|
||||||
use eyre::Result;
|
use eyre::Result;
|
||||||
|
|
||||||
use client::Client;
|
use client::{rpc::Rpc, Client};
|
||||||
|
use tokio::time::sleep;
|
||||||
use crate::common::utils::hex_str_to_bytes;
|
|
||||||
|
|
||||||
pub mod client;
|
pub mod client;
|
||||||
pub mod common;
|
pub mod common;
|
||||||
|
@ -21,24 +19,11 @@ async fn main() -> Result<()> {
|
||||||
let mut client = Client::new(consensus_rpc, execution_rpc, checkpoint).await?;
|
let mut client = Client::new(consensus_rpc, execution_rpc, checkpoint).await?;
|
||||||
client.sync().await?;
|
client.sync().await?;
|
||||||
|
|
||||||
let header = client.get_header();
|
let mut rpc = Rpc::new(Arc::new(client));
|
||||||
println!("synced up to slot: {}", header.slot);
|
let addr = rpc.start().await?;
|
||||||
|
println!("{}", addr);
|
||||||
|
|
||||||
let address = Address::from_str("0x14f9D4aF749609c1438528C0Cce1cC3f6D411c47")?;
|
sleep(Duration::from_secs(300)).await;
|
||||||
let balance = client.get_balance(&address).await?;
|
|
||||||
let nonce = client.get_nonce(&address).await?;
|
|
||||||
let code = client.get_code(&address).await?;
|
|
||||||
let storage_value = client.get_storage_at(&address, U256::from(0)).await?;
|
|
||||||
|
|
||||||
let owner_calldata = hex_str_to_bytes("0x8da5cb5b")?;
|
|
||||||
let value = U256::from(0);
|
|
||||||
let owner = client.call(&address, &owner_calldata, value).await?;
|
|
||||||
|
|
||||||
println!("balance: {}", balance);
|
|
||||||
println!("nonce: {}", nonce);
|
|
||||||
println!("code: 0x{}...", hex::encode(code[..5].to_vec()));
|
|
||||||
println!("value at slot 0: 0x{:x}", storage_value);
|
|
||||||
println!("result of calling owner() on address: {}", hex::encode(owner));
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue