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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions bin/reth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ revm-primitives.workspace = true
reth-db-common.workspace = true
reth-db = { workspace = true, features = ["mdbx", "test-utils"] }
serial_test.workspace = true
reth-discv5.workspace = true
reth-transaction-pool = { workspace = true, features = ["test-utils"] }

[features]
default = ["jemalloc"]
Expand Down
97 changes: 84 additions & 13 deletions bin/reth/tests/commands/bitfinity_node_it.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use reth::{
};
use reth_consensus::FullConsensus;
use reth_db::{init_db, test_utils::tempdir_path, DatabaseEnv};
use reth_discv5::discv5::enr::secp256k1::{Keypair, Secp256k1};
use reth_network::NetworkHandle;
use reth_node_api::{FullNodeTypesAdapter, NodeTypesWithDBAdapter};
use reth_node_builder::{
Expand All @@ -25,21 +26,24 @@ use reth_node_ethereum::{
node::EthereumEngineValidatorBuilder, BasicBlockExecutorProvider, EthEvmConfig,
EthExecutionStrategyFactory, EthereumNode,
};
use reth_primitives::{Transaction, TransactionSigned};
use reth_provider::providers::BlockchainProvider;
use reth_rpc::EthApi;
use reth_tasks::TaskManager;
use reth_transaction_pool::blobstore::DiskFileBlobStore;
use reth_transaction_pool::test_utils::MockTransaction;
use reth_transaction_pool::{
blobstore::DiskFileBlobStore, CoinbaseTipOrdering, EthPooledTransaction,
EthTransactionValidator, Pool, TransactionValidationTaskExecutor,
CoinbaseTipOrdering, EthPooledTransaction, EthTransactionValidator, Pool,
TransactionValidationTaskExecutor,
};
use revm_primitives::{hex, Address, U256};
use revm_primitives::{hex, Address, B256, U256};
use std::{net::SocketAddr, str::FromStr, sync::Arc};

#[tokio::test]
async fn bitfinity_test_should_start_local_reth_node() {
// Arrange
let _log = init_logs();
let (reth_client, _reth_node) = start_reth_node(None, None).await;
let (reth_client, _reth_node, _tasks) = start_reth_node(None, None).await;

// Act & Assert
assert!(reth_client.get_chain_id().await.is_ok());
Expand All @@ -53,7 +57,7 @@ async fn bitfinity_test_lb_lag_check() {
let eth_server = EthImpl::new();
let (_server, eth_server_address) =
mock_eth_server_start(EthServer::into_rpc(eth_server)).await;
let (reth_client, _reth_node) =
let (reth_client, _reth_node, _tasks) =
start_reth_node(Some(format!("http://{}", eth_server_address)), None).await;

// Try `eth_lbLagCheck`
Expand Down Expand Up @@ -107,7 +111,7 @@ async fn bitfinity_test_lb_lag_check() {

#[tokio::test]
async fn bitfinity_test_lb_lag_check_fail_safe() {
let (reth_client, _reth_node) =
let (reth_client, _reth_node, _tasks) =
start_reth_node(Some("http://local_host:11".to_string()), None).await;

let message: String = reth_client
Expand All @@ -132,7 +136,7 @@ async fn bitfinity_test_node_forward_ic_or_eth_get_last_certified_block() {
let eth_server = EthImpl::new();
let (_server, eth_server_address) =
mock_eth_server_start(EthServer::into_rpc(eth_server)).await;
let (reth_client, _reth_node) =
let (reth_client, _reth_node, _tasks) =
start_reth_node(Some(format!("http://{}", eth_server_address)), None).await;

// Act
Expand Down Expand Up @@ -163,7 +167,7 @@ async fn bitfinity_test_node_forward_get_gas_price_requests() {
let gas_price = eth_server.gas_price;
let (_server, eth_server_address) =
mock_eth_server_start(EthServer::into_rpc(eth_server)).await;
let (reth_client, _reth_node) =
let (reth_client, _reth_node, _tasks) =
start_reth_node(Some(format!("http://{}", eth_server_address)), None).await;

// Act
Expand All @@ -182,7 +186,7 @@ async fn bitfinity_test_node_forward_max_priority_fee_per_gas_requests() {
let max_priority_fee_per_gas = eth_server.max_priority_fee_per_gas;
let (_server, eth_server_address) =
mock_eth_server_start(EthServer::into_rpc(eth_server)).await;
let (reth_client, _reth_node) =
let (reth_client, _reth_node, _tasks) =
start_reth_node(Some(format!("http://{}", eth_server_address)), None).await;

// Act
Expand All @@ -204,7 +208,7 @@ async fn bitfinity_test_node_forward_eth_get_genesis_balances() {
]);
let (_server, eth_server_address) =
mock_eth_server_start(EthServer::into_rpc(eth_server)).await;
let (reth_client, _reth_node) =
let (reth_client, _reth_node, _tasks) =
start_reth_node(Some(format!("http://{}", eth_server_address)), None).await;

// Act
Expand Down Expand Up @@ -242,7 +246,7 @@ async fn bitfinity_test_node_forward_ic_get_genesis_balances() {
]);
let (_server, eth_server_address) =
mock_eth_server_start(EthServer::into_rpc(eth_server)).await;
let (reth_client, _reth_node) =
let (reth_client, _reth_node, _tasks) =
start_reth_node(Some(format!("http://{}", eth_server_address)), None).await;

// Act
Expand All @@ -269,7 +273,7 @@ async fn bitfinity_test_node_forward_send_raw_transaction_requests() {
let eth_server = EthImpl::new();
let (_server, eth_server_address) =
mock_eth_server_start(EthServer::into_rpc(eth_server)).await;
let (reth_client, _reth_node) =
let (reth_client, _reth_node, _tasks) =
start_reth_node(Some(format!("http://{}", eth_server_address)), None).await;

// Create a random transaction
Expand All @@ -284,6 +288,44 @@ async fn bitfinity_test_node_forward_send_raw_transaction_requests() {
assert_eq!(result.unwrap(), expected_tx_hash);
}

#[tokio::test]
async fn bitfinity_test_node_forward_get_transaction_by_hash() {
// Arrange
let _log = init_logs();

let eth_server = EthImpl::new();
let last_get_tx_hash = eth_server.last_get_tx_by_hash.clone();

let (_server, eth_server_address) =
mock_eth_server_start(EthServer::into_rpc(eth_server)).await;
let (reth_client, _reth_node, _tasks) =
start_reth_node(Some(format!("http://{}", eth_server_address)), None).await;

let hash = B256::random();

// Act
let tx_result = reth_client.get_transaction_by_hash(hash.into()).await;

// Assert
assert!(matches!(tx_result, Ok(Some(_))));
assert_eq!(last_get_tx_hash.read().await.unwrap(), hash);
}

fn sign_tx_with_random_key_pair(tx: Transaction) -> TransactionSigned {
let secp = Secp256k1::new();
let key_pair = Keypair::new(&secp, &mut rand::thread_rng());
sign_tx_with_key_pair(key_pair, tx)
}

fn sign_tx_with_key_pair(key_pair: Keypair, tx: Transaction) -> TransactionSigned {
let signature = reth_primitives::sign_message(
B256::from_slice(&key_pair.secret_bytes()[..]),
tx.signature_hash(),
)
.unwrap();
TransactionSigned::new(tx, signature, Default::default())
}

/// Start a local reth node
pub async fn start_reth_node(
bitfinity_evm_url: Option<String>,
Expand Down Expand Up @@ -372,6 +414,7 @@ pub async fn start_reth_node(
EthereumEngineValidatorBuilder,
>,
>,
TaskManager,
) {
let tasks = TaskManager::current();

Expand Down Expand Up @@ -416,7 +459,7 @@ pub async fn start_reth_node(
let client: EthJsonRpcClient<ReqwestClient> =
EthJsonRpcClient::new(ReqwestClient::new(format!("http://{}", reth_address)));

(client, node_handle)
(client, node_handle, tasks)
}

/// Start a local Eth server.
Expand Down Expand Up @@ -454,9 +497,13 @@ pub mod eth_server {
use did::{keccak, BlockConfirmationData, BlockConfirmationResult, BlockNumber, H256, U64};
use ethereum_json_rpc_client::CertifiedResult;
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
use reth_transaction_pool::test_utils::MockTransaction;

use reth_trie::EMPTY_ROOT_HASH;
use revm_primitives::{Address, B256, U256};
use tokio::sync::RwLock;

use super::sign_tx_with_random_key_pair;

#[rpc(server, namespace = "eth")]
pub trait Eth {
Expand All @@ -472,6 +519,10 @@ pub mod eth_server {
#[method(name = "sendRawTransaction")]
async fn send_raw_transaction(&self, tx: Bytes) -> RpcResult<B256>;

/// Gets transaction by hash.
#[method(name = "getTransactionByHash")]
async fn transaction_by_hash(&self, hash: B256) -> RpcResult<Option<did::Transaction>>;

/// Returns the genesis balances.
#[method(name = "getGenesisBalances", aliases = ["ic_getGenesisBalances"])]
async fn get_genesis_balances(&self) -> RpcResult<Vec<(Address, U256)>>;
Expand Down Expand Up @@ -519,6 +570,9 @@ pub mod eth_server {
pub gas_price: u128,
/// Current max priority fee per gas
pub max_priority_fee_per_gas: u128,

/// Hash of last
pub last_get_tx_by_hash: Arc<RwLock<Option<B256>>>,
/// Current block number (atomic for thread safety)
pub current_block: Arc<std::sync::atomic::AtomicU64>,
/// Chain ID
Expand Down Expand Up @@ -564,6 +618,7 @@ pub mod eth_server {
Self {
gas_price: rand::random(),
max_priority_fee_per_gas: rand::random(),
last_get_tx_by_hash: Default::default(),
current_block,
chain_id: 1,
state: did::evm_state::EvmGlobalState::Staging { max_block_number: None },
Expand Down Expand Up @@ -684,6 +739,22 @@ pub mod eth_server {
Ok(hash.into())
}

async fn transaction_by_hash(&self, hash: B256) -> RpcResult<Option<did::Transaction>> {
*self.last_get_tx_by_hash.write().await = Some(hash);

// return transaction, initialized enough to pass reth checks.
let tx = sign_tx_with_random_key_pair(MockTransaction::legacy().with_hash(hash).into());
let did_tx = did::Transaction {
hash: hash.into(),
r: tx.signature.r().into(),
s: tx.signature.s().into(),
v: (tx.signature.recid().to_byte() as u64).into(),
..Default::default()
};

Ok(Some(did_tx))
}

async fn get_genesis_balances(&self) -> RpcResult<Vec<(Address, U256)>> {
Ok(self.genesis_balances.clone())
}
Expand Down
23 changes: 18 additions & 5 deletions crates/rpc/rpc-eth-api/src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,10 +551,23 @@ where
hash: B256,
) -> RpcResult<Option<RpcTransaction<T::NetworkTypes>>> {
trace!(target: "rpc::eth", ?hash, "Serving eth_getTransactionByHash");
Ok(EthTransactions::transaction_by_hash(self, hash)
// Ok(EthTransactions::transaction_by_hash(self, hash)
// .await?
// .map(|tx| tx.into_transaction(self.tx_resp_builder()))
// .transpose()?)

let mut tx_opt = EthTransactions::transaction_by_hash(self, hash)
.await?
.map(|tx| tx.into_transaction(self.tx_resp_builder()))
.transpose()?)
.transpose()?;
if tx_opt.is_none() {
tx_opt = BitfinityEvmRpc::btf_transaction_by_hash(self, hash)
.await?
.map(|tx| tx.into_transaction(self.tx_resp_builder()))
.transpose()?;
}

Ok(tx_opt)
}

/// Handler for: `eth_getRawTransactionByBlockHashAndIndex`
Expand Down Expand Up @@ -743,7 +756,7 @@ where
/// Handler for: `eth_gasPrice`
async fn gas_price(&self) -> RpcResult<U256> {
trace!(target: "rpc::eth", "Serving eth_gasPrice");
Ok(BitfinityEvmRpc::gas_price(self).await?)
Ok(BitfinityEvmRpc::btf_gas_price(self).await?)
}

/// Handler for: `eth_getAccount`
Expand All @@ -759,7 +772,7 @@ where
/// Handler for: `eth_maxPriorityFeePerGas`
async fn max_priority_fee_per_gas(&self) -> RpcResult<U256> {
trace!(target: "rpc::eth", "Serving eth_maxPriorityFeePerGas");
Ok(BitfinityEvmRpc::max_priority_fee_per_gas(self).await?)
Ok(BitfinityEvmRpc::btf_max_priority_fee_per_gas(self).await?)
}

/// Handler for: `eth_blobBaseFee`
Expand Down Expand Up @@ -827,7 +840,7 @@ where
async fn send_raw_transaction(&self, tx: Bytes) -> RpcResult<B256> {
trace!(target: "rpc::eth", ?tx, "Serving eth_sendRawTransaction");
// Ok(EthTransactions::send_raw_transaction(self, tx).await?)
BitfinityEvmRpc::send_raw_transaction(self, tx).await
BitfinityEvmRpc::btf_send_raw_transaction(self, tx).await
}

/// Handler for: `eth_sign`
Expand Down
Loading
Loading