mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: Support erc20 system tx from address
This commit is contained in:
@ -23,7 +23,7 @@ use reth_execution_types::BlockExecutionResult;
|
|||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
EthPrimitives, Receipt, Recovered, RecoveredBlock, SealedBlock, TransactionSigned,
|
EthPrimitives, Receipt, Recovered, RecoveredBlock, SealedBlock, TransactionSigned,
|
||||||
};
|
};
|
||||||
use reth_primitives_traits::{transaction::signed::HL_SYSTEM_TX_FROM_ADDR, NodePrimitives};
|
use reth_primitives_traits::{transaction::signed::is_impersonated_tx, NodePrimitives};
|
||||||
use reth_revm::{context_interface::result::ResultAndState, db::State, DatabaseCommit};
|
use reth_revm::{context_interface::result::ResultAndState, db::State, DatabaseCommit};
|
||||||
|
|
||||||
/// Factory for [`EthExecutionStrategy`].
|
/// Factory for [`EthExecutionStrategy`].
|
||||||
@ -191,7 +191,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
let hash = tx.hash();
|
let hash = tx.hash();
|
||||||
let is_system_transaction = tx.signer() == HL_SYSTEM_TX_FROM_ADDR;
|
let is_system_transaction = is_impersonated_tx(tx.signature(), tx.gas_price()).is_some();
|
||||||
|
|
||||||
// Execute transaction.
|
// Execute transaction.
|
||||||
let result_and_state =
|
let result_and_state =
|
||||||
|
|||||||
@ -21,7 +21,7 @@ use reth_primitives_traits::{
|
|||||||
sync::OnceLock,
|
sync::OnceLock,
|
||||||
transaction::{
|
transaction::{
|
||||||
error::TransactionConversionError,
|
error::TransactionConversionError,
|
||||||
signed::{is_impersonated_tx, RecoveryError, HL_SYSTEM_TX_FROM_ADDR},
|
signed::{is_impersonated_tx, RecoveryError},
|
||||||
},
|
},
|
||||||
InMemorySize, SignedTransaction,
|
InMemorySize, SignedTransaction,
|
||||||
};
|
};
|
||||||
@ -836,8 +836,8 @@ impl SignedTransaction for TransactionSigned {
|
|||||||
|
|
||||||
fn recover_signer(&self) -> Result<Address, RecoveryError> {
|
fn recover_signer(&self) -> Result<Address, RecoveryError> {
|
||||||
let signature = self.signature();
|
let signature = self.signature();
|
||||||
if is_impersonated_tx(signature, self.gas_price()) {
|
if let Some(address) = is_impersonated_tx(signature, self.gas_price()) {
|
||||||
return Ok(HL_SYSTEM_TX_FROM_ADDR);
|
return Ok(address);
|
||||||
}
|
}
|
||||||
let signature_hash = self.signature_hash();
|
let signature_hash = self.signature_hash();
|
||||||
recover_signer(&self.signature, signature_hash)
|
recover_signer(&self.signature, signature_hash)
|
||||||
|
|||||||
@ -15,7 +15,7 @@ pub mod shanghai;
|
|||||||
use alloy_rpc_types_engine::{ExecutionData, PayloadError};
|
use alloy_rpc_types_engine::{ExecutionData, PayloadError};
|
||||||
use reth_chainspec::EthereumHardforks;
|
use reth_chainspec::EthereumHardforks;
|
||||||
use reth_primitives::SealedBlock;
|
use reth_primitives::SealedBlock;
|
||||||
use reth_primitives_traits::transaction::signed::HL_SYSTEM_TX_FROM_ADDR;
|
use reth_primitives_traits::transaction::signed::is_impersonated_tx;
|
||||||
use reth_primitives_traits::{Block, SignedTransaction};
|
use reth_primitives_traits::{Block, SignedTransaction};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -94,9 +94,7 @@ impl<ChainSpec: EthereumHardforks> ExecutionPayloadValidator<ChainSpec> {
|
|||||||
let (normal, system) = transactions.into_iter().partition(|tx| {
|
let (normal, system) = transactions.into_iter().partition(|tx| {
|
||||||
let tx = T::decode_2718(&mut tx.iter().as_slice());
|
let tx = T::decode_2718(&mut tx.iter().as_slice());
|
||||||
match tx {
|
match tx {
|
||||||
Ok(tx) => {
|
Ok(tx) => is_impersonated_tx(tx.signature(), tx.gas_price()).is_none(),
|
||||||
!matches!(tx.recover_signer(), Ok(address) if HL_SYSTEM_TX_FROM_ADDR == address)
|
|
||||||
}
|
|
||||||
Err(_) => true,
|
Err(_) => true,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
//! Block body abstraction.
|
//! Block body abstraction.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
transaction::signed::{RecoveryError, HL_SYSTEM_TX_FROM_ADDR},
|
transaction::signed::{is_impersonated_tx, RecoveryError},
|
||||||
BlockHeader, FullSignedTx, InMemorySize, MaybeSerde, MaybeSerdeBincodeCompat,
|
BlockHeader, FullSignedTx, InMemorySize, MaybeSerde, MaybeSerdeBincodeCompat,
|
||||||
SignedTransaction,
|
SignedTransaction,
|
||||||
};
|
};
|
||||||
@ -85,7 +85,7 @@ pub trait BlockBody:
|
|||||||
let transactions: Vec<Self::Transaction> = self
|
let transactions: Vec<Self::Transaction> = self
|
||||||
.transactions()
|
.transactions()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|tx| !matches!(tx.recover_signer(), Ok(address) if HL_SYSTEM_TX_FROM_ADDR == address))
|
.filter(|&tx| is_impersonated_tx(tx.signature(), tx.gas_price()).is_none())
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
alloy_consensus::proofs::calculate_transaction_root(transactions.as_slice())
|
alloy_consensus::proofs::calculate_transaction_root(transactions.as_slice())
|
||||||
|
|||||||
@ -10,9 +10,10 @@ use alloy_consensus::{
|
|||||||
SignableTransaction, Transaction,
|
SignableTransaction, Transaction,
|
||||||
};
|
};
|
||||||
use alloy_eips::eip2718::{Decodable2718, Encodable2718};
|
use alloy_eips::eip2718::{Decodable2718, Encodable2718};
|
||||||
use alloy_primitives::{keccak256, Address, PrimitiveSignature as Signature, TxHash, B256};
|
use alloy_primitives::{keccak256, Address, PrimitiveSignature as Signature, TxHash, B256, U160};
|
||||||
use core::hash::Hash;
|
use core::hash::Hash;
|
||||||
use revm_primitives::{address, U256};
|
use revm_primitives::{address, U256};
|
||||||
|
use std::ops::Add;
|
||||||
|
|
||||||
/// Helper trait that unifies all behaviour required by block to support full node operations.
|
/// Helper trait that unifies all behaviour required by block to support full node operations.
|
||||||
pub trait FullSignedTx: SignedTransaction + MaybeCompact + MaybeSerdeBincodeCompat {}
|
pub trait FullSignedTx: SignedTransaction + MaybeCompact + MaybeSerdeBincodeCompat {}
|
||||||
@ -23,11 +24,20 @@ pub const HL_SYSTEM_TX_FROM_ADDR: Address = address!("22222222222222222222222222
|
|||||||
|
|
||||||
/// Check if the transaction is impersonated.
|
/// Check if the transaction is impersonated.
|
||||||
/// Signature part is introduced in block_ingest, while the gas_price is trait of hyperliquid system transactions.
|
/// Signature part is introduced in block_ingest, while the gas_price is trait of hyperliquid system transactions.
|
||||||
pub fn is_impersonated_tx(signature: &Signature, gas_price: Option<u128>) -> bool {
|
pub fn is_impersonated_tx(signature: &Signature, gas_price: Option<u128>) -> Option<Address> {
|
||||||
signature.r() == U256::from(1)
|
if signature.r() == U256::from(1) && signature.v() == true && gas_price == Some(0u128) {
|
||||||
&& signature.s() == U256::from(1)
|
if signature.s() == U256::from(1) {
|
||||||
&& signature.v() == true
|
Some(HL_SYSTEM_TX_FROM_ADDR)
|
||||||
&& gas_price == Some(0u128)
|
} else {
|
||||||
|
let s = signature.s().reduce_mod(U256::from(U160::MAX).add(U256::from(1)));
|
||||||
|
let s = U160::from(s);
|
||||||
|
let s: [u8; 20] = s.to_be_bytes();
|
||||||
|
let s = Address::from_slice(&s);
|
||||||
|
Some(s)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A signed transaction.
|
/// A signed transaction.
|
||||||
@ -89,8 +99,8 @@ pub trait SignedTransaction:
|
|||||||
/// Returns `None` if the transaction's signature is invalid, see also
|
/// Returns `None` if the transaction's signature is invalid, see also
|
||||||
/// `reth_primitives::transaction::recover_signer_unchecked`.
|
/// `reth_primitives::transaction::recover_signer_unchecked`.
|
||||||
fn recover_signer_unchecked(&self) -> Result<Address, RecoveryError> {
|
fn recover_signer_unchecked(&self) -> Result<Address, RecoveryError> {
|
||||||
if is_impersonated_tx(self.signature(), self.gas_price()) {
|
if let Some(address) = is_impersonated_tx(self.signature(), self.gas_price()) {
|
||||||
return Ok(HL_SYSTEM_TX_FROM_ADDR);
|
return Ok(address);
|
||||||
}
|
}
|
||||||
self.recover_signer_unchecked_with_buf(&mut Vec::new()).map_err(|_| RecoveryError)
|
self.recover_signer_unchecked_with_buf(&mut Vec::new()).map_err(|_| RecoveryError)
|
||||||
}
|
}
|
||||||
@ -183,8 +193,8 @@ impl SignedTransaction for PooledTransaction {
|
|||||||
buf: &mut Vec<u8>,
|
buf: &mut Vec<u8>,
|
||||||
) -> Result<Address, RecoveryError> {
|
) -> Result<Address, RecoveryError> {
|
||||||
let signature = self.signature();
|
let signature = self.signature();
|
||||||
if is_impersonated_tx(signature, self.gas_price()) {
|
if let Some(address) = is_impersonated_tx(signature, self.gas_price()) {
|
||||||
return Ok(HL_SYSTEM_TX_FROM_ADDR);
|
return Ok(address);
|
||||||
}
|
}
|
||||||
match self {
|
match self {
|
||||||
Self::Legacy(tx) => tx.tx().encode_for_signing(buf),
|
Self::Legacy(tx) => tx.tx().encode_for_signing(buf),
|
||||||
|
|||||||
Reference in New Issue
Block a user