mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: hl-node compliant mode
hl-node compliant mode removes all system transactions from rpc responses like eth_getBlock, eth_getLogs and eth_subscribe.
This commit is contained in:
@ -31,6 +31,15 @@ struct HyperliquidExtArgs {
|
|||||||
/// Forward eth_call and eth_estimateGas to the upstream RPC.
|
/// Forward eth_call and eth_estimateGas to the upstream RPC.
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub forward_call: bool,
|
pub forward_call: bool,
|
||||||
|
|
||||||
|
/// Enable hl-node compliant mode.
|
||||||
|
///
|
||||||
|
/// This option
|
||||||
|
/// 1. filters out system transactions from block transaction list.
|
||||||
|
/// 2. filters out logs that are not from the block's transactions.
|
||||||
|
/// 3. filters out logs and transactions from subscription.
|
||||||
|
#[arg(long, default_value = "false")]
|
||||||
|
pub hl_node_compliant: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -46,6 +55,11 @@ fn main() {
|
|||||||
|
|
||||||
if let Err(err) = Cli::<EthereumChainSpecParser, HyperliquidExtArgs>::parse().run(
|
if let Err(err) = Cli::<EthereumChainSpecParser, HyperliquidExtArgs>::parse().run(
|
||||||
|builder, ext_args| async move {
|
|builder, ext_args| async move {
|
||||||
|
if ext_args.hl_node_compliant {
|
||||||
|
info!(target: "reth::cli", "hl-node compliant mode enabled");
|
||||||
|
std::env::set_var("HL_NODE_COMPLIANT", "true");
|
||||||
|
}
|
||||||
|
|
||||||
let ingest_dir = builder.config().ingest_dir.clone().expect("ingest dir not set");
|
let ingest_dir = builder.config().ingest_dir.clone().expect("ingest dir not set");
|
||||||
let local_ingest_dir = builder.config().local_ingest_dir.clone();
|
let local_ingest_dir = builder.config().local_ingest_dir.clone();
|
||||||
info!(target: "reth::cli", "Launching node");
|
info!(target: "reth::cli", "Launching node");
|
||||||
|
|||||||
@ -27,9 +27,14 @@ where
|
|||||||
let mut all_logs = Vec::new();
|
let mut all_logs = Vec::new();
|
||||||
// Tracks the index of a log in the entire block.
|
// Tracks the index of a log in the entire block.
|
||||||
let mut log_index: u64 = 0;
|
let mut log_index: u64 = 0;
|
||||||
|
let is_in_hl_node_compliant_mode = is_in_hl_node_compliant_mode();
|
||||||
// Iterate over transaction hashes and receipts and append matching logs.
|
// Iterate over transaction hashes and receipts and append matching logs.
|
||||||
for (receipt_idx, (tx_hash, receipt)) in tx_hashes_and_receipts.into_iter().enumerate() {
|
for (receipt_idx, (tx_hash, receipt)) in tx_hashes_and_receipts.into_iter().enumerate() {
|
||||||
for log in receipt.logs() {
|
for log in receipt.logs() {
|
||||||
|
if is_in_hl_node_compliant_mode && receipt.cumulative_gas_used() == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if log_matches_filter(block_num_hash, log, filter) {
|
if log_matches_filter(block_num_hash, log, filter) {
|
||||||
let log = Log {
|
let log = Log {
|
||||||
inner: log.clone(),
|
inner: log.clone(),
|
||||||
@ -59,6 +64,10 @@ pub enum ProviderOrBlock<'a, P: BlockReader> {
|
|||||||
Block(Arc<RecoveredBlock<ProviderBlock<P>>>),
|
Block(Arc<RecoveredBlock<ProviderBlock<P>>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_in_hl_node_compliant_mode() -> bool {
|
||||||
|
std::env::var("HL_NODE_COMPLIANT").is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
/// Appends all matching logs of a block's receipts.
|
/// Appends all matching logs of a block's receipts.
|
||||||
/// If the log matches, look up the corresponding transaction hash.
|
/// If the log matches, look up the corresponding transaction hash.
|
||||||
pub fn append_matching_block_logs<P>(
|
pub fn append_matching_block_logs<P>(
|
||||||
@ -81,12 +90,18 @@ where
|
|||||||
// prevents re-querying the block body indices.
|
// prevents re-querying the block body indices.
|
||||||
let mut loaded_first_tx_num = None;
|
let mut loaded_first_tx_num = None;
|
||||||
|
|
||||||
|
let is_in_hl_node_compliant_mode = is_in_hl_node_compliant_mode();
|
||||||
|
|
||||||
// Iterate over receipts and append matching logs.
|
// Iterate over receipts and append matching logs.
|
||||||
for (receipt_idx, receipt) in receipts.iter().enumerate() {
|
for (receipt_idx, receipt) in receipts.iter().enumerate() {
|
||||||
// The transaction hash of the current receipt.
|
// The transaction hash of the current receipt.
|
||||||
let mut transaction_hash = None;
|
let mut transaction_hash = None;
|
||||||
|
|
||||||
for log in receipt.logs() {
|
for log in receipt.logs() {
|
||||||
|
if is_in_hl_node_compliant_mode && receipt.cumulative_gas_used() == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if log_matches_filter(block_num_hash, log, filter) {
|
if log_matches_filter(block_num_hash, log, filter) {
|
||||||
// if this is the first match in the receipt's logs, look up the transaction hash
|
// if this is the first match in the receipt's logs, look up the transaction hash
|
||||||
if transaction_hash.is_none() {
|
if transaction_hash.is_none() {
|
||||||
@ -146,13 +161,13 @@ pub fn log_matches_filter(
|
|||||||
log: &alloy_primitives::Log,
|
log: &alloy_primitives::Log,
|
||||||
params: &FilteredParams,
|
params: &FilteredParams,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if params.filter.is_some() &&
|
if params.filter.is_some()
|
||||||
(!params.filter_block_range(block.number) ||
|
&& (!params.filter_block_range(block.number)
|
||||||
!params.filter_block_hash(block.hash) ||
|
|| !params.filter_block_hash(block.hash)
|
||||||
!params.filter_address(&log.address) ||
|
|| !params.filter_address(&log.address)
|
||||||
!params.filter_topics(log.topics()))
|
|| !params.filter_topics(log.topics()))
|
||||||
{
|
{
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
//! Compatibility functions for rpc `Block` type.
|
//! Compatibility functions for rpc `Block` type.
|
||||||
|
|
||||||
use crate::transaction::TransactionCompat;
|
use crate::transaction::TransactionCompat;
|
||||||
use alloy_consensus::{BlockHeader, Sealable};
|
use alloy_consensus::{BlockHeader, Sealable, Transaction as _};
|
||||||
use alloy_primitives::U256;
|
use alloy_primitives::U256;
|
||||||
use alloy_rpc_types_eth::{
|
use alloy_rpc_types_eth::{
|
||||||
Block, BlockTransactions, BlockTransactionsKind, Header, TransactionInfo,
|
Block, BlockTransactions, BlockTransactionsKind, Header, TransactionInfo,
|
||||||
@ -38,7 +38,18 @@ pub fn from_block_with_tx_hashes<T, B>(block: RecoveredBlock<B>) -> Block<T, Hea
|
|||||||
where
|
where
|
||||||
B: BlockTrait,
|
B: BlockTrait,
|
||||||
{
|
{
|
||||||
let transactions = block.body().transaction_hashes_iter().copied().collect();
|
let transactions = block
|
||||||
|
.body()
|
||||||
|
.transactions_iter()
|
||||||
|
.filter(move |&tx| {
|
||||||
|
if is_in_hl_node_compliant_mode() {
|
||||||
|
return !matches!(tx.gas_price(), Some(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
})
|
||||||
|
.map(|tx| *tx.tx_hash())
|
||||||
|
.collect();
|
||||||
let rlp_length = block.rlp_length();
|
let rlp_length = block.rlp_length();
|
||||||
let (header, body) = block.into_sealed_block().split_sealed_header_body();
|
let (header, body) = block.into_sealed_block().split_sealed_header_body();
|
||||||
from_block_with_transactions::<T, B>(
|
from_block_with_transactions::<T, B>(
|
||||||
@ -68,8 +79,18 @@ where
|
|||||||
let block_length = block.rlp_length();
|
let block_length = block.rlp_length();
|
||||||
let block_hash = Some(block.hash());
|
let block_hash = Some(block.hash());
|
||||||
|
|
||||||
|
let is_in_hl_node_compliant_mode = is_in_hl_node_compliant_mode();
|
||||||
|
|
||||||
let transactions = block
|
let transactions = block
|
||||||
.transactions_recovered()
|
.transactions_recovered()
|
||||||
|
.filter(move |tx| {
|
||||||
|
if is_in_hl_node_compliant_mode {
|
||||||
|
let gas_price = tx.clone_tx().gas_price();
|
||||||
|
return !matches!(gas_price, Some(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
})
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(idx, tx)| {
|
.map(|(idx, tx)| {
|
||||||
let tx_info = TransactionInfo {
|
let tx_info = TransactionInfo {
|
||||||
@ -93,6 +114,10 @@ where
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_in_hl_node_compliant_mode() -> bool {
|
||||||
|
std::env::var("HL_NODE_COMPLIANT").is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from_block_with_transactions<T, B: BlockTrait>(
|
fn from_block_with_transactions<T, B: BlockTrait>(
|
||||||
block_length: usize,
|
block_length: usize,
|
||||||
|
|||||||
Reference in New Issue
Block a user