feat: add tx length rpc methods (#142)
* adding documentation for rpc.md * adding rpc methods in table for rpc.md * adjusting readme to link to rpc.md * fixing grammar * grammar * adding RPC Methods according to documentation and listing column as Client Function * adding more description space * undoing description spacing * adding get block transaction count by hash to node.rs and rpc.rs * functioning getblocktransactioncountbyhash function * removing documentation * adding second rpc method and simplifying logic * adjusting example and node.rs * formatting * fixing clippy errors * adding to client and to rpc.md * formatting * integrating into client * u64 return types, rpc.md updated to get_nonce, get_transaction_count -> get_nonce revert * cargo fmt
This commit is contained in:
parent
94bf458d94
commit
c26e393b7d
|
@ -340,6 +340,20 @@ impl<DB: Database> Client<DB> {
|
||||||
self.node.read().await.get_nonce(address, block).await
|
self.node.read().await.get_nonce(address, block).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_block_transaction_count_by_hash(&self, hash: &Vec<u8>) -> Result<u64> {
|
||||||
|
self.node
|
||||||
|
.read()
|
||||||
|
.await
|
||||||
|
.get_block_transaction_count_by_hash(hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_block_transaction_count_by_number(&self, block: BlockTag) -> Result<u64> {
|
||||||
|
self.node
|
||||||
|
.read()
|
||||||
|
.await
|
||||||
|
.get_block_transaction_count_by_number(block)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_code(&self, address: &Address, block: BlockTag) -> Result<Vec<u8>> {
|
pub async fn get_code(&self, address: &Address, block: BlockTag) -> Result<Vec<u8>> {
|
||||||
self.node.read().await.get_code(address, block).await
|
self.node.read().await.get_code(address, block).await
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,6 +155,20 @@ impl Node {
|
||||||
Ok(account.nonce)
|
Ok(account.nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_block_transaction_count_by_hash(&self, hash: &Vec<u8>) -> Result<u64> {
|
||||||
|
let payload = self.get_payload_by_hash(hash)?;
|
||||||
|
let transaction_count = payload.1.transactions.len();
|
||||||
|
|
||||||
|
Ok(transaction_count as u64)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_block_transaction_count_by_number(&self, block: BlockTag) -> Result<u64> {
|
||||||
|
let payload = self.get_payload(block)?;
|
||||||
|
let transaction_count = payload.transactions.len();
|
||||||
|
|
||||||
|
Ok(transaction_count as u64)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_code(&self, address: &Address, block: BlockTag) -> Result<Vec<u8>> {
|
pub async fn get_code(&self, address: &Address, block: BlockTag) -> Result<Vec<u8>> {
|
||||||
self.check_blocktag_age(&block)?;
|
self.check_blocktag_age(&block)?;
|
||||||
|
|
||||||
|
@ -248,19 +262,11 @@ impl Node {
|
||||||
hash: &Vec<u8>,
|
hash: &Vec<u8>,
|
||||||
full_tx: bool,
|
full_tx: bool,
|
||||||
) -> Result<Option<ExecutionBlock>> {
|
) -> Result<Option<ExecutionBlock>> {
|
||||||
let payloads = self
|
let payload = self.get_payload_by_hash(hash);
|
||||||
.payloads
|
|
||||||
.iter()
|
|
||||||
.filter(|entry| &entry.1.block_hash.to_vec() == hash)
|
|
||||||
.collect::<Vec<(&u64, &ExecutionPayload)>>();
|
|
||||||
|
|
||||||
if let Some(payload_entry) = payloads.get(0) {
|
match payload {
|
||||||
self.execution
|
Ok(payload) => self.execution.get_block(payload.1, full_tx).await.map(Some),
|
||||||
.get_block(payload_entry.1, full_tx)
|
Err(_) => Ok(None),
|
||||||
.await
|
|
||||||
.map(Some)
|
|
||||||
} else {
|
|
||||||
Ok(None)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,6 +302,19 @@ impl Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_payload_by_hash(&self, hash: &Vec<u8>) -> Result<(&u64, &ExecutionPayload)> {
|
||||||
|
let payloads = self
|
||||||
|
.payloads
|
||||||
|
.iter()
|
||||||
|
.filter(|entry| &entry.1.block_hash.to_vec() == hash)
|
||||||
|
.collect::<Vec<(&u64, &ExecutionPayload)>>();
|
||||||
|
|
||||||
|
payloads
|
||||||
|
.get(0)
|
||||||
|
.cloned()
|
||||||
|
.ok_or(eyre!("Block not found by hash"))
|
||||||
|
}
|
||||||
|
|
||||||
fn check_head_age(&self) -> Result<(), NodeError> {
|
fn check_head_age(&self) -> Result<(), NodeError> {
|
||||||
let synced_slot = self.consensus.get_header().slot;
|
let synced_slot = self.consensus.get_header().slot;
|
||||||
let expected_slot = self.consensus.expected_current_slot();
|
let expected_slot = self.consensus.expected_current_slot();
|
||||||
|
|
|
@ -57,6 +57,11 @@ trait EthRpc {
|
||||||
async fn get_balance(&self, address: &str, block: BlockTag) -> Result<String, Error>;
|
async fn get_balance(&self, address: &str, block: BlockTag) -> Result<String, Error>;
|
||||||
#[method(name = "getTransactionCount")]
|
#[method(name = "getTransactionCount")]
|
||||||
async fn get_transaction_count(&self, address: &str, block: BlockTag) -> Result<String, Error>;
|
async fn get_transaction_count(&self, address: &str, block: BlockTag) -> Result<String, Error>;
|
||||||
|
#[method(name = "getBlockTransactionCountByHash")]
|
||||||
|
async fn get_block_transaction_count_by_hash(&self, hash: &str) -> Result<String, Error>;
|
||||||
|
#[method(name = "getBlockTransactionCountByNumber")]
|
||||||
|
async fn get_block_transaction_count_by_number(&self, block: BlockTag)
|
||||||
|
-> Result<String, Error>;
|
||||||
#[method(name = "getCode")]
|
#[method(name = "getCode")]
|
||||||
async fn get_code(&self, address: &str, block: BlockTag) -> Result<String, Error>;
|
async fn get_code(&self, address: &str, block: BlockTag) -> Result<String, Error>;
|
||||||
#[method(name = "call")]
|
#[method(name = "call")]
|
||||||
|
@ -133,6 +138,23 @@ impl EthRpcServer for RpcInner {
|
||||||
Ok(format!("0x{nonce:x}"))
|
Ok(format!("0x{nonce:x}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_block_transaction_count_by_hash(&self, hash: &str) -> Result<String, Error> {
|
||||||
|
let hash = convert_err(hex_str_to_bytes(hash))?;
|
||||||
|
let node = self.node.read().await;
|
||||||
|
let transaction_count = convert_err(node.get_block_transaction_count_by_hash(&hash))?;
|
||||||
|
|
||||||
|
Ok(u64_to_hex_string(transaction_count))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_block_transaction_count_by_number(
|
||||||
|
&self,
|
||||||
|
block: BlockTag,
|
||||||
|
) -> Result<String, Error> {
|
||||||
|
let node = self.node.read().await;
|
||||||
|
let transaction_count = convert_err(node.get_block_transaction_count_by_number(block))?;
|
||||||
|
Ok(u64_to_hex_string(transaction_count))
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_code(&self, address: &str, block: BlockTag) -> Result<String, Error> {
|
async fn get_code(&self, address: &str, block: BlockTag) -> Result<String, Error> {
|
||||||
let address = convert_err(Address::from_str(address))?;
|
let address = convert_err(Address::from_str(address))?;
|
||||||
let node = self.node.read().await;
|
let node = self.node.read().await;
|
||||||
|
|
|
@ -9,7 +9,7 @@ use helios::{client::ClientBuilder, config::networks::Network, types::BlockTag};
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
|
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
|
||||||
|
|
||||||
let untrusted_rpc_url = "https://mainnet.infura.io/v3/<YOUR_API_KEY>";
|
let untrusted_rpc_url = "https://eth-mainnet.g.alchemy.com/v2/<YOUR_API_KEY>";
|
||||||
log::info!("Using untrusted RPC URL [REDACTED]");
|
log::info!("Using untrusted RPC URL [REDACTED]");
|
||||||
|
|
||||||
let consensus_rpc = "https://www.lightclientdata.org";
|
let consensus_rpc = "https://www.lightclientdata.org";
|
||||||
|
|
6
rpc.md
6
rpc.md
|
@ -7,7 +7,7 @@ Helios provides a variety of RPC methods for interacting with the Ethereum netwo
|
||||||
| RPC Method | Client Function | Description | Example |
|
| RPC Method | Client Function | Description | Example |
|
||||||
| ---------- | --------------- | ----------- | ------- |
|
| ---------- | --------------- | ----------- | ------- |
|
||||||
| `eth_getBalance` | `get_balance` | Returns the balance of the account given an address. | `client.get_balance(&self, address: &str, block: BlockTag)` |
|
| `eth_getBalance` | `get_balance` | Returns the balance of the account given an address. | `client.get_balance(&self, address: &str, block: BlockTag)` |
|
||||||
| `eth_getTransactionCount` | `get_transaction_count` | Returns the number of transactions sent from the given address. | `client.get_transaction_count(&self, address: &str, block: BlockTag)` |
|
| `eth_getTransactionCount` | `get_nonce` | Returns the number of transactions sent from the given address. | `client.get_nonce(&self, address: &str, block: BlockTag)` |
|
||||||
| `eth_getCode` | `get_code` | Returns the code at a given address. | `client.get_code(&self, address: &str, block: BlockTag)` |
|
| `eth_getCode` | `get_code` | Returns the code at a given address. | `client.get_code(&self, address: &str, block: BlockTag)` |
|
||||||
| `eth_call` | `call` | Executes a new message call immediately without creating a transaction on the blockchain. | `client.call(&self, opts: CallOpts, block: BlockTag)` |
|
| `eth_call` | `call` | Executes a new message call immediately without creating a transaction on the blockchain. | `client.call(&self, opts: CallOpts, block: BlockTag)` |
|
||||||
| `eth_estimateGas` | `estimate_gas` | Generates and returns an estimate of how much gas is necessary to allow the transaction to complete. | `client.estimate_gas(&self, opts: CallOpts)` |
|
| `eth_estimateGas` | `estimate_gas` | Generates and returns an estimate of how much gas is necessary to allow the transaction to complete. | `client.estimate_gas(&self, opts: CallOpts)` |
|
||||||
|
@ -20,4 +20,6 @@ Helios provides a variety of RPC methods for interacting with the Ethereum netwo
|
||||||
| `eth_sendRawTransaction` | `send_raw_transaction` | Submits a raw transaction to the network. | `client.send_raw_transaction(&self, bytes: &str)` |
|
| `eth_sendRawTransaction` | `send_raw_transaction` | Submits a raw transaction to the network. | `client.send_raw_transaction(&self, bytes: &str)` |
|
||||||
| `eth_getTransactionReceipt` | `get_transaction_receipt` | Returns the receipt of a transaction by transaction hash. | `client.get_transaction_receipt(&self, hash: &str)` |
|
| `eth_getTransactionReceipt` | `get_transaction_receipt` | Returns the receipt of a transaction by transaction hash. | `client.get_transaction_receipt(&self, hash: &str)` |
|
||||||
| `eth_getLogs` | `get_logs` | Returns an array of logs matching the filter. | `client.get_logs(&self, filter: Filter)` |
|
| `eth_getLogs` | `get_logs` | Returns an array of logs matching the filter. | `client.get_logs(&self, filter: Filter)` |
|
||||||
| `eth_getStorageAt` | `get_storage_at` | Returns the value from a storage position at a given address. | `client.get_storage_at(&self, address: &str, slot: H256, block: BlockTag)` |
|
| `eth_getStorageAt` | `get_storage_at` | Returns the value from a storage position at a given address. | `client.get_storage_at(&self, address: &str, slot: H256, block: BlockTag)` |
|
||||||
|
| `eth_getBlockTransactionCountByHash` | `get_block_transaction_count_by_hash` | Returns the number of transactions in a block from a block matching the transaction hash. | `client.get_block_transaction_count_by_hash(&self, hash: &str)` |
|
||||||
|
| `eth_getBlockTransactionCountByNumber` | `get_block_transaction_count_by_number` | Returns the number of transactions in a block from a block matching the block number. | `client.get_block_transaction_count_by_number(&self, block: BlockTag)` |
|
Loading…
Reference in New Issue