mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-04-08 03:01:12 -04:00
feat: integrate newPayload into ethstats (#20584)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
@@ -3,8 +3,8 @@ use crate::{
|
||||
credentials::EthstatsCredentials,
|
||||
error::EthStatsError,
|
||||
events::{
|
||||
AuthMsg, BlockMsg, BlockStats, HistoryMsg, LatencyMsg, NodeInfo, NodeStats, PendingMsg,
|
||||
PendingStats, PingMsg, StatsMsg, TxStats, UncleStats,
|
||||
AuthMsg, BlockMsg, BlockStats, HistoryMsg, LatencyMsg, NodeInfo, NodeStats, PayloadMsg,
|
||||
PayloadStats, PendingMsg, PendingStats, PingMsg, StatsMsg, TxStats, UncleStats,
|
||||
},
|
||||
};
|
||||
use alloy_consensus::{BlockHeader, Sealable};
|
||||
@@ -50,7 +50,7 @@ const READ_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
/// authentication, stats reporting, block notifications, and connection management.
|
||||
/// It maintains a persistent `WebSocket` connection and automatically reconnects
|
||||
/// when the connection is lost.
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct EthStatsService<Network, Provider, Pool> {
|
||||
/// Authentication credentials for the `EthStats` server
|
||||
credentials: EthstatsCredentials,
|
||||
@@ -347,6 +347,42 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Report new payload information to the `EthStats` server
|
||||
///
|
||||
/// Sends information about payload processing time and block details
|
||||
/// to the server for monitoring purposes.
|
||||
pub async fn report_new_payload(
|
||||
&self,
|
||||
block_hash: alloy_primitives::B256,
|
||||
block_number: u64,
|
||||
processing_time: Duration,
|
||||
) -> Result<(), EthStatsError> {
|
||||
let conn = self.conn.read().await;
|
||||
let conn = conn.as_ref().ok_or(EthStatsError::NotConnected)?;
|
||||
|
||||
let payload_stats = PayloadStats {
|
||||
number: U256::from(block_number),
|
||||
hash: block_hash,
|
||||
processing_time: processing_time.as_millis() as u64,
|
||||
};
|
||||
|
||||
let payload_msg =
|
||||
PayloadMsg { id: self.credentials.node_id.clone(), payload: payload_stats };
|
||||
|
||||
debug!(
|
||||
target: "ethstats",
|
||||
"Reporting new payload: block={}, hash={:?}, processing_time={}ms",
|
||||
block_number,
|
||||
block_hash,
|
||||
processing_time.as_millis()
|
||||
);
|
||||
|
||||
let message = payload_msg.generate_new_payload_message();
|
||||
conn.write_json(&message).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Convert a block to `EthStats` block statistics format
|
||||
///
|
||||
/// Extracts relevant information from a block and formats it according
|
||||
|
||||
@@ -281,3 +281,66 @@ impl PingMsg {
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// Information reported about a new payload processing event.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PayloadStats {
|
||||
/// Block number of the payload
|
||||
pub number: U256,
|
||||
|
||||
/// Hash of the payload block
|
||||
pub hash: B256,
|
||||
|
||||
/// Time taken to validate the payload in milliseconds
|
||||
#[serde(rename = "processingTime")]
|
||||
pub processing_time: u64,
|
||||
}
|
||||
|
||||
/// Message containing new payload information to be reported to the ethstats monitoring server.
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PayloadMsg {
|
||||
/// The node's unique identifier
|
||||
pub id: String,
|
||||
|
||||
/// The payload information to report
|
||||
pub payload: PayloadStats,
|
||||
}
|
||||
|
||||
impl PayloadMsg {
|
||||
/// Generate a new payload message for the ethstats monitoring server.
|
||||
pub fn generate_new_payload_message(&self) -> String {
|
||||
serde_json::json!({
|
||||
"emit": ["new-payload", self]
|
||||
})
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use alloy_primitives::{B256, U256};
|
||||
|
||||
#[test]
|
||||
fn test_payload_msg_generation() {
|
||||
let payload_stats = PayloadStats {
|
||||
number: U256::from(12345),
|
||||
hash: B256::from_slice(&[1u8; 32]),
|
||||
processing_time: 150,
|
||||
};
|
||||
|
||||
let payload_msg = PayloadMsg { id: "test-node".to_string(), payload: payload_stats };
|
||||
|
||||
let message = payload_msg.generate_new_payload_message();
|
||||
let parsed: serde_json::Value = serde_json::from_str(&message).expect("Valid JSON");
|
||||
|
||||
assert_eq!(parsed["emit"][0], "new-payload");
|
||||
assert_eq!(parsed["emit"][1]["id"], "test-node");
|
||||
assert_eq!(parsed["emit"][1]["payload"]["number"], "0x3039"); // 12345 in hex
|
||||
assert_eq!(parsed["emit"][1]["payload"]["processingTime"], 150);
|
||||
|
||||
// Verify the structure contains all expected fields
|
||||
assert!(parsed["emit"][1]["payload"]["hash"].is_string());
|
||||
assert!(parsed["emit"][1]["payload"]["processingTime"].is_number());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user