Skip to content
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
79 changes: 78 additions & 1 deletion crates/networking/rpc/mempool.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::HashMap;

use ethrex_common::Address;
use ethrex_common::{Address, types::TxKind};
use ethrex_crypto::NativeCrypto;
use serde::{Deserialize, Serialize};
use serde_json::Value;
Expand All @@ -24,6 +24,22 @@ struct MempoolStatus {
queued: String,
}

type MempoolContentByNonce = HashMap<u64, RpcTransaction>;

#[derive(Serialize, Deserialize)]
pub struct MempoolContentFrom {
pub pending: MempoolContentByNonce,
pub queued: MempoolContentByNonce,
}

type MempoolInspectEntry = HashMap<Address, HashMap<u64, String>>;

#[derive(Serialize, Deserialize)]
pub struct MempoolInspect {
pub pending: MempoolInspectEntry,
pub queued: MempoolInspectEntry,
}

/// Handling of rpc endpoint `mempool_content`
pub fn content(context: RpcApiContext) -> Result<Value, RpcErr> {
let transactions = context.blockchain.mempool.content()?;
Expand Down Expand Up @@ -55,3 +71,64 @@ pub fn status(context: RpcApiContext) -> Result<Value, RpcErr> {

Ok(serde_json::to_value(response)?)
}

/// Handling of rpc endpoint `txpool_contentFrom`
pub fn content_from(params: &Option<Vec<Value>>, context: RpcApiContext) -> Result<Value, RpcErr> {
let params = params
.as_ref()
.ok_or(RpcErr::BadParams("No params provided".to_owned()))?;
if params.len() != 1 {
return Err(RpcErr::BadParams(format!(
"Expected one param and {} were provided",
params.len()
)));
}
let address: Address = serde_json::from_value(params[0].clone())?;
let transactions = context.blockchain.mempool.content()?;
let mut by_nonce: MempoolContentByNonce = HashMap::new();
for tx in transactions {
if tx.sender(&NativeCrypto)? == address {
by_nonce.insert(tx.nonce(), RpcTransaction::build(tx, None, None, None)?);
}
}
let response = MempoolContentFrom {
pending: by_nonce,
// We have no concept of "queued" transactions yet so we will leave this empty
queued: HashMap::new(),
};
Ok(serde_json::to_value(response)?)
}

/// Handling of rpc endpoint `txpool_inspect`
pub fn inspect(context: RpcApiContext) -> Result<Value, RpcErr> {
let transactions = context.blockchain.mempool.content()?;
let mut pending: MempoolInspectEntry = HashMap::new();
for tx in transactions {
let sender = tx.sender(&NativeCrypto)?;
let gas_price = tx.gas_price();
let summary = match tx.to() {
TxKind::Call(to) => format!(
"{to:#x}: {} wei + {} gas × {} wei",
tx.value(),
tx.gas_limit(),
gas_price
),
TxKind::Create => format!(
"contract creation: {} wei + {} gas × {} wei",
tx.value(),
tx.gas_limit(),
gas_price
),
};
pending
.entry(sender)
.or_default()
.insert(tx.nonce(), summary);
}
let response = MempoolInspect {
pending,
// We have no concept of "queued" transactions yet so we will leave this empty
queued: HashMap::new(),
};
Ok(serde_json::to_value(response)?)
}
2 changes: 2 additions & 0 deletions crates/networking/rpc/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -896,7 +896,9 @@ pub fn map_mempool_requests(req: &RpcRequest, contex: RpcApiContext) -> Result<V
match req.method.as_str() {
// TODO: The endpoint name matches geth's endpoint for compatibility, consider changing it in the future
"txpool_content" => mempool::content(contex),
"txpool_contentFrom" => mempool::content_from(&req.params, contex),
"txpool_status" => mempool::status(contex),
"txpool_inspect" => mempool::inspect(contex),
unknown_mempool_method => Err(RpcErr::MethodNotFound(unknown_mempool_method.to_owned())),
}
}
Expand Down
Loading