diff --git a/Cargo.lock b/Cargo.lock
index df2c58b7f4c1bb4bddea5a8f66d02a7ff69a6076..e4bd817300f0303da34756c5b2652842c0e21712 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -8735,7 +8735,7 @@ dependencies = [
  "httpdate",
  "itoa",
  "pin-project-lite",
- "socket2 0.5.7",
+ "socket2 0.4.9",
  "tokio",
  "tower-service",
  "tracing",
@@ -16456,7 +16456,7 @@ checksum = "4e69bf016dc406eff7d53a7d3f7cf1c2e72c82b9088aac1118591e36dd2cd3e9"
 dependencies = [
  "bitcoin_hashes 0.13.0",
  "rand",
- "rand_core 0.6.4",
+ "rand_core 0.5.1",
  "serde",
  "unicode-normalization",
 ]
@@ -20721,7 +20721,7 @@ checksum = "f8650aabb6c35b860610e9cff5dc1af886c9e25073b7b1712a68972af4281302"
 dependencies = [
  "bytes",
  "heck 0.5.0",
- "itertools 0.13.0",
+ "itertools 0.12.1",
  "log",
  "multimap",
  "once_cell",
@@ -20767,7 +20767,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac"
 dependencies = [
  "anyhow",
- "itertools 0.13.0",
+ "itertools 0.12.1",
  "proc-macro2 1.0.86",
  "quote 1.0.37",
  "syn 2.0.87",
@@ -29085,9 +29085,9 @@ dependencies = [
 
 [[package]]
 name = "subxt"
-version = "0.38.0"
+version = "0.38.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c53029d133e4e0cb7933f1fe06f2c68804b956de9bb8fa930ffca44e9e5e4230"
+checksum = "1c17d7ec2359d33133b63c97e28c8b7cd3f0a5bc6ce567ae3aef9d9e85be3433"
 dependencies = [
  "async-trait",
  "derive-where",
diff --git a/prdoc/pr_7325.prdoc b/prdoc/pr_7325.prdoc
new file mode 100644
index 0000000000000000000000000000000000000000..788f01cb32470ab5f7a10dfc520c6dcc9f5d4310
--- /dev/null
+++ b/prdoc/pr_7325.prdoc
@@ -0,0 +1,11 @@
+title: '[pallet-revive] eth-rpc minor fixes'
+doc:
+- audience: Runtime Dev
+  description: |-
+    - Add option to specify database_url from an environment variable
+    - Add  a test-deployment.rs rust script that can be used to test deployment and call of a contract before releasing eth-rpc
+    - Make evm_block non fallible so that it can return an Ok response for older blocks when the runtime API is not available
+    - Update subxt version to integrate changes from https://github.com/paritytech/subxt/pull/1904
+crates:
+- name: pallet-revive-eth-rpc
+  bump: minor
diff --git a/substrate/frame/revive/rpc/Cargo.toml b/substrate/frame/revive/rpc/Cargo.toml
index 9d822f5ff8e2771a3bdb421698eacea5339b2803..014231f7f3e55c9a296e4519e6d9ea95215061bd 100644
--- a/substrate/frame/revive/rpc/Cargo.toml
+++ b/substrate/frame/revive/rpc/Cargo.toml
@@ -17,34 +17,33 @@ path = "src/main.rs"
 name = "eth-indexer"
 path = "src/eth-indexer.rs"
 
+[[bin]]
+name = "eth-rpc-tester"
+path = "src/eth-rpc-tester.rs"
+
 [[example]]
 name = "deploy"
 path = "examples/rust/deploy.rs"
-required-features = ["example"]
 
 [[example]]
 name = "transfer"
 path = "examples/rust/transfer.rs"
-required-features = ["example"]
 
 [[example]]
 name = "rpc-playground"
 path = "examples/rust/rpc-playground.rs"
-required-features = ["example"]
 
 [[example]]
 name = "extrinsic"
 path = "examples/rust/extrinsic.rs"
-required-features = ["example"]
 
 [[example]]
 name = "remark-extrinsic"
 path = "examples/rust/remark-extrinsic.rs"
-required-features = ["example"]
 
 [dependencies]
 anyhow = { workspace = true }
-clap = { workspace = true, features = ["derive"] }
+clap = { workspace = true, features = ["derive", "env"] }
 codec = { workspace = true, features = ["derive"] }
 ethabi = { version = "18.0.0" }
 futures = { workspace = true, features = ["thread-pool"] }
@@ -52,8 +51,9 @@ hex = { workspace = true }
 jsonrpsee = { workspace = true, features = ["full"] }
 log = { workspace = true }
 pallet-revive = { workspace = true, default-features = true }
+pallet-revive-fixtures = { workspace = true, default-features = true }
 prometheus-endpoint = { workspace = true, default-features = true }
-rlp = { workspace = true, optional = true }
+rlp = { workspace = true }
 sc-cli = { workspace = true, default-features = true }
 sc-rpc = { workspace = true, default-features = true }
 sc-rpc-api = { workspace = true, default-features = true }
@@ -62,24 +62,18 @@ sp-arithmetic = { workspace = true, default-features = true }
 sp-core = { workspace = true, default-features = true }
 sp-crypto-hashing = { workspace = true }
 sp-weights = { workspace = true, default-features = true }
-sqlx = { version = "0.8.2", features = [
-	"macros",
-	"runtime-tokio",
-	"sqlite",
+sqlx = { version = "0.8.2", features = ["macros", "runtime-tokio", "sqlite"] }
+subxt = { workspace = true, default-features = true, features = [
+	"reconnecting-rpc-client",
 ] }
-subxt = { workspace = true, default-features = true, features = ["reconnecting-rpc-client"] }
-subxt-signer = { workspace = true, optional = true, features = [
+subxt-signer = { workspace = true, features = [
 	"unstable-eth",
 ] }
 thiserror = { workspace = true }
 tokio = { workspace = true, features = ["full"] }
 
-[features]
-example = ["rlp", "subxt-signer"]
-
 [dev-dependencies]
 env_logger = { workspace = true }
-pallet-revive-fixtures = { workspace = true, default-features = true }
 static_init = { workspace = true }
 substrate-cli-test-utils = { workspace = true }
 subxt-signer = { workspace = true, features = ["unstable-eth"] }
diff --git a/substrate/frame/revive/rpc/examples/README.md b/substrate/frame/revive/rpc/examples/README.md
index b9a2756b381d26cb7155b11c0aa1968eb2836256..1079c254b9c2070fb798c7b8362aa8788d89ab79 100644
--- a/substrate/frame/revive/rpc/examples/README.md
+++ b/substrate/frame/revive/rpc/examples/README.md
@@ -42,7 +42,7 @@ RUST_LOG="info,eth-rpc=debug" cargo run -p pallet-revive-eth-rpc -- --dev
 Run one of the examples from the `examples` directory to send a transaction to the node:
 
 ```bash
-RUST_LOG="info,eth-rpc=debug" cargo run -p pallet-revive-eth-rpc --features example --example deploy
+RUST_LOG="info,eth-rpc=debug" cargo run -p pallet-revive-eth-rpc --example deploy
 ```
 
 ## JS examples
diff --git a/substrate/frame/revive/rpc/src/cli.rs b/substrate/frame/revive/rpc/src/cli.rs
index d63d596ab7a8b87cd37e944da954819f58cd5b9b..b6c57d2c3b0bfcb50f024aee5521d9b1edf4d1c2 100644
--- a/substrate/frame/revive/rpc/src/cli.rs
+++ b/substrate/frame/revive/rpc/src/cli.rs
@@ -19,7 +19,7 @@ use crate::{
 	client::{connect, Client},
 	BlockInfoProvider, BlockInfoProviderImpl, CacheReceiptProvider, DBReceiptProvider,
 	EthRpcServer, EthRpcServerImpl, ReceiptProvider, SystemHealthRpcServer,
-	SystemHealthRpcServerImpl,
+	SystemHealthRpcServerImpl, LOG_TARGET,
 };
 use clap::Parser;
 use futures::{pin_mut, FutureExt};
@@ -52,7 +52,7 @@ pub struct CliCommand {
 	/// The database used to store Ethereum transaction hashes.
 	/// This is only useful if the node needs to act as an archive node and respond to Ethereum RPC
 	/// queries for transactions that are not in the in memory cache.
-	#[clap(long)]
+	#[clap(long, env = "DATABASE_URL")]
 	pub database_url: Option<String>,
 
 	/// If true, we will only read from the database and not write to it.
@@ -148,6 +148,7 @@ pub fn run(cmd: CliCommand) -> anyhow::Result<()> {
 				Arc::new(BlockInfoProviderImpl::new(cache_size, api.clone(), rpc.clone()));
 			let receipt_provider: Arc<dyn ReceiptProvider> =
 				if let Some(database_url) = database_url.as_ref() {
+					log::info!(target: LOG_TARGET, "🔗 Connecting to provided database");
 					Arc::new((
 						CacheReceiptProvider::default(),
 						DBReceiptProvider::new(
@@ -158,6 +159,7 @@ pub fn run(cmd: CliCommand) -> anyhow::Result<()> {
 						.await?,
 					))
 				} else {
+					log::info!(target: LOG_TARGET, "🔌 No database provided, using in-memory cache");
 					Arc::new(CacheReceiptProvider::default())
 				};
 
diff --git a/substrate/frame/revive/rpc/src/client.rs b/substrate/frame/revive/rpc/src/client.rs
index 440972c7a681b58dbd6cd3dfdc9040a099c1d17e..47e439f068513f9ef5184bd40fcc57ffbdc11d46 100644
--- a/substrate/frame/revive/rpc/src/client.rs
+++ b/substrate/frame/revive/rpc/src/client.rs
@@ -646,9 +646,9 @@ impl Client {
 		&self,
 		block: Arc<SubstrateBlock>,
 		hydrated_transactions: bool,
-	) -> Result<Block, ClientError> {
+	) -> Block {
 		let runtime_api = self.api.runtime_api().at(block.hash());
-		let gas_limit = Self::block_gas_limit(&runtime_api).await?;
+		let gas_limit = Self::block_gas_limit(&runtime_api).await.unwrap_or_default();
 
 		let header = block.header();
 		let timestamp = extract_block_timestamp(&block).await.unwrap_or_default();
@@ -658,7 +658,7 @@ impl Client {
 		let state_root = header.state_root.0.into();
 		let extrinsics_root = header.extrinsics_root.0.into();
 
-		let receipts = extract_receipts_from_block(&block).await?;
+		let receipts = extract_receipts_from_block(&block).await.unwrap_or_default();
 		let gas_used =
 			receipts.iter().fold(U256::zero(), |acc, (_, receipt)| acc + receipt.gas_used);
 		let transactions = if hydrated_transactions {
@@ -675,7 +675,7 @@ impl Client {
 				.into()
 		};
 
-		Ok(Block {
+		Block {
 			hash: block.hash(),
 			parent_hash,
 			state_root,
@@ -689,7 +689,7 @@ impl Client {
 			receipts_root: extrinsics_root,
 			transactions,
 			..Default::default()
-		})
+		}
 	}
 
 	/// Convert a weight to a fee.
@@ -697,7 +697,6 @@ impl Client {
 		runtime_api: &subxt::runtime_api::RuntimeApi<SrcChainConfig, OnlineClient<SrcChainConfig>>,
 	) -> Result<U256, ClientError> {
 		let payload = subxt_client::apis().revive_api().block_gas_limit();
-
 		let gas_limit = runtime_api.call(payload).await?;
 		Ok(*gas_limit)
 	}
diff --git a/substrate/frame/revive/rpc/src/eth-indexer.rs b/substrate/frame/revive/rpc/src/eth-indexer.rs
index 3e7f6b6fa91b88554203386ca00ebbe5e9b577a0..894143be0a525a581a32301dc12070b3bbc9143b 100644
--- a/substrate/frame/revive/rpc/src/eth-indexer.rs
+++ b/substrate/frame/revive/rpc/src/eth-indexer.rs
@@ -37,7 +37,7 @@ pub struct CliCommand {
 	pub oldest_block: Option<SubstrateBlockNumber>,
 
 	/// The database used to store Ethereum transaction hashes.
-	#[clap(long)]
+	#[clap(long, env = "DATABASE_URL")]
 	pub database_url: String,
 
 	#[allow(missing_docs)]
diff --git a/substrate/frame/revive/rpc/src/eth-rpc-tester.rs b/substrate/frame/revive/rpc/src/eth-rpc-tester.rs
new file mode 100644
index 0000000000000000000000000000000000000000..0ddad6874dfd5b188508d59a4dacf31ee40f85ca
--- /dev/null
+++ b/substrate/frame/revive/rpc/src/eth-rpc-tester.rs
@@ -0,0 +1,157 @@
+// This file is part of Substrate.
+
+// Copyright (C) Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+use clap::Parser;
+use jsonrpsee::http_client::HttpClientBuilder;
+use pallet_revive::evm::{Account, BlockTag, ReceiptInfo};
+use pallet_revive_eth_rpc::{
+	example::{wait_for_receipt, TransactionBuilder},
+	EthRpcClient,
+};
+use tokio::{
+	io::{AsyncBufReadExt, BufReader},
+	process::{Child, ChildStderr, Command},
+	signal::unix::{signal, SignalKind},
+};
+
+const DOCKER_CONTAINER_NAME: &str = "eth-rpc-test";
+
+#[derive(Parser, Debug)]
+#[clap(author, about, version)]
+pub struct CliCommand {
+	/// The parity docker image e.g eth-rpc:master-fb2e414f
+	#[clap(long, default_value = "eth-rpc:master-fb2e414f")]
+	docker_image: String,
+
+	/// The docker binary
+	/// Either docker or podman
+	#[clap(long, default_value = "docker")]
+	docker_bin: String,
+}
+
+#[tokio::main]
+async fn main() -> anyhow::Result<()> {
+	let CliCommand { docker_bin, docker_image, .. } = CliCommand::parse();
+
+	let mut docker_process = start_docker(&docker_bin, &docker_image)?;
+	let stderr = docker_process.stderr.take().unwrap();
+
+	tokio::select! {
+		result = docker_process.wait() => {
+			println!("docker failed: {result:?}");
+		}
+		_ = interrupt() => {
+			kill_docker().await?;
+		}
+		_ = test_eth_rpc(stderr) => {
+			kill_docker().await?;
+		}
+	}
+
+	Ok(())
+}
+
+async fn interrupt() {
+	let mut sigint = signal(SignalKind::interrupt()).expect("failed to listen for SIGINT");
+	let mut sigterm = signal(SignalKind::terminate()).expect("failed to listen for SIGTERM");
+
+	tokio::select! {
+		_ = sigint.recv() => {},
+		_ = sigterm.recv() => {},
+	}
+}
+
+fn start_docker(docker_bin: &str, docker_image: &str) -> anyhow::Result<Child> {
+	let docker_process = Command::new(docker_bin)
+		.args([
+			"run",
+			"--name",
+			DOCKER_CONTAINER_NAME,
+			"--rm",
+			"-p",
+			"8545:8545",
+			&format!("docker.io/paritypr/{docker_image}"),
+			"--node-rpc-url",
+			"wss://westend-asset-hub-rpc.polkadot.io",
+			"--rpc-cors",
+			"all",
+			"--unsafe-rpc-external",
+			"--log=sc_rpc_server:info",
+		])
+		.stderr(std::process::Stdio::piped())
+		.kill_on_drop(true)
+		.spawn()?;
+
+	Ok(docker_process)
+}
+
+async fn kill_docker() -> anyhow::Result<()> {
+	Command::new("docker").args(["kill", DOCKER_CONTAINER_NAME]).output().await?;
+	Ok(())
+}
+
+async fn test_eth_rpc(stderr: ChildStderr) -> anyhow::Result<()> {
+	let mut reader = BufReader::new(stderr).lines();
+	while let Some(line) = reader.next_line().await? {
+		println!("{line}");
+		if line.contains("Running JSON-RPC server") {
+			break;
+		}
+	}
+
+	let account = Account::default();
+	let data = vec![];
+	let (bytes, _) = pallet_revive_fixtures::compile_module("dummy")?;
+	let input = bytes.into_iter().chain(data).collect::<Vec<u8>>();
+
+	println!("Account:");
+	println!("- address: {:?}", account.address());
+	let client = HttpClientBuilder::default().build("http://localhost:8545")?;
+
+	let nonce = client.get_transaction_count(account.address(), BlockTag::Latest.into()).await?;
+	let balance = client.get_balance(account.address(), BlockTag::Latest.into()).await?;
+	println!("-  nonce: {nonce:?}");
+	println!("-  balance: {balance:?}");
+
+	println!("\n\n=== Deploying dummy contract ===\n\n");
+	let hash = TransactionBuilder::default().input(input).send(&client).await?;
+
+	println!("Hash: {hash:?}");
+	println!("Waiting for receipt...");
+	let ReceiptInfo { block_number, gas_used, contract_address, .. } =
+		wait_for_receipt(&client, hash).await?;
+
+	let contract_address = contract_address.unwrap();
+	println!("\nReceipt:");
+	println!("Block explorer: https://westend-asset-hub-eth-explorer.parity.io/{hash:?}");
+	println!("- Block number: {block_number}");
+	println!("- Gas used: {gas_used}");
+	println!("- Address: {contract_address:?}");
+
+	println!("\n\n=== Calling dummy contract ===\n\n");
+	let hash = TransactionBuilder::default().to(contract_address).send(&client).await?;
+
+	println!("Hash: {hash:?}");
+	println!("Waiting for receipt...");
+
+	let ReceiptInfo { block_number, gas_used, to, .. } = wait_for_receipt(&client, hash).await?;
+	println!("\nReceipt:");
+	println!("Block explorer: https://westend-asset-hub-eth-explorer.parity.io/{hash:?}");
+	println!("- Block number: {block_number}");
+	println!("- Gas used: {gas_used}");
+	println!("- To: {to:?}");
+	Ok(())
+}
diff --git a/substrate/frame/revive/rpc/src/example.rs b/substrate/frame/revive/rpc/src/example.rs
index 3b9a33296ef4d9073c52e44bdb895cbe57875dc5..aad5b4fbc344d511088d0a73ee99fab3de042749 100644
--- a/substrate/frame/revive/rpc/src/example.rs
+++ b/substrate/frame/revive/rpc/src/example.rs
@@ -15,8 +15,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 //! Example utilities
-#![cfg(any(feature = "example", test))]
-
 use crate::{EthRpcClient, ReceiptInfo};
 use anyhow::Context;
 use pallet_revive::evm::{
diff --git a/substrate/frame/revive/rpc/src/lib.rs b/substrate/frame/revive/rpc/src/lib.rs
index 5e1341e2a29ab85b394241414cc70e112bf3e3b0..fcf93fa6c0d2e3dba86d079e6639a5cdd0942941 100644
--- a/substrate/frame/revive/rpc/src/lib.rs
+++ b/substrate/frame/revive/rpc/src/lib.rs
@@ -214,7 +214,7 @@ impl EthRpcServer for EthRpcServerImpl {
 		let Some(block) = self.client.block_by_hash(&block_hash).await? else {
 			return Ok(None);
 		};
-		let block = self.client.evm_block(block, hydrated_transactions).await?;
+		let block = self.client.evm_block(block, hydrated_transactions).await;
 		Ok(Some(block))
 	}
 
@@ -254,7 +254,7 @@ impl EthRpcServer for EthRpcServerImpl {
 		let Some(block) = self.client.block_by_number_or_tag(&block).await? else {
 			return Ok(None);
 		};
-		let block = self.client.evm_block(block, hydrated_transactions).await?;
+		let block = self.client.evm_block(block, hydrated_transactions).await;
 		Ok(Some(block))
 	}