Compare commits

..

4 Commits

Author SHA1 Message Date
Omar Abdulla 7664e9735e fix clippy warning 2025-07-11 17:20:36 +03:00
Omar Abdulla 4bab457114 Added --dev to substrate-node arguments.
This commit adds the `--dev` argument to the `substrate-node` to allow
the chain to keep advancing as time goes own. We have found that if this
option is not added then the chain won't advance forward.
2025-07-11 17:18:42 +03:00
Omar Abdulla f6374ad52a fix formatting 2025-07-11 14:49:05 +03:00
Omar Abdulla abba0cee08 Introduce a custom kitchensink network 2025-07-11 11:26:55 +03:00
6 changed files with 52 additions and 107 deletions
+2 -21
View File
@@ -99,28 +99,9 @@ jobs:
- name: Install Geth on Ubuntu
if: matrix.os == 'ubuntu-24.04'
run: |
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install -y protobuf-compiler
# We were facing some issues in CI with the 1.16.* versions of geth, and specifically on
# Ubuntu. Eventually, we found out that the last version of geth that worked in our CI was
# version 1.15.11. Thus, this is the version that we want to use in CI. The PPA sadly does
# not have historic versions of Geth and therefore we need to resort to downloading pre
# built binaries for Geth and the surrounding tools which is what the following parts of
# the script do.
sudo apt-get install -y wget ca-certificates tar
ARCH=$(uname -m)
if [ "$ARCH" = "x86_64" ]; then
URL="https://gethstore.blob.core.windows.net/builds/geth-alltools-linux-amd64-1.15.11-36b2371c.tar.gz"
elif [ "$ARCH" = "aarch64" ]; then
URL="https://gethstore.blob.core.windows.net/builds/geth-alltools-linux-arm64-1.15.11-36b2371c.tar.gz"
else
echo "Unsupported architecture: $ARCH"
exit 1
fi
wget -qO- "$URL" | sudo tar xz -C /usr/local/bin --strip-components=1
geth --version
sudo apt-get install -y ethereum protobuf-compiler
- name: Install Geth on macOS
if: matrix.os == 'macos-14'
Generated
+6 -6
View File
@@ -67,9 +67,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "alloy"
version = "1.0.20"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae58d888221eecf621595e2096836ce7cfc37be06bfa39d7f64aa6a3ea4c9e5b"
checksum = "0093d23bf026b580c1f66ed3a053d8209c104a446c5264d3ad99587f6edef24e"
dependencies = [
"alloy-consensus",
"alloy-contract",
@@ -162,9 +162,9 @@ dependencies = [
[[package]]
name = "alloy-core"
version = "1.2.1"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad31216895d27d307369daa1393f5850b50bbbd372478a9fa951c095c210627e"
checksum = "a3c5a28f166629752f2e7246b813cdea3243cca59aab2d4264b1fd68392c10eb"
dependencies = [
"alloy-dyn-abi",
"alloy-json-abi",
@@ -175,9 +175,9 @@ dependencies = [
[[package]]
name = "alloy-dyn-abi"
version = "1.2.1"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b95b3deca680efc7e9cba781f1a1db352fa1ea50e6384a514944dcf4419e652"
checksum = "18cc14d832bc3331ca22a1c7819de1ede99f58f61a7d123952af7dde8de124a6"
dependencies = [
"alloy-json-abi",
"alloy-primitives",
+1 -1
View File
@@ -1,4 +1,4 @@
//! The global configuration used across all revive differential testing crates.
//! The global configuration used accross all revive differential testing crates.
use std::{
fmt::Display,
+1 -1
View File
@@ -12,7 +12,6 @@ rust-version.workspace = true
anyhow = { workspace = true }
alloy = { workspace = true }
tracing = { workspace = true }
tokio = { workspace = true }
revive-dt-node-interaction = { workspace = true }
revive-dt-config = { workspace = true }
@@ -25,3 +24,4 @@ sp-runtime = { workspace = true }
[dev-dependencies]
temp-dir = { workspace = true }
tokio = { workspace = true }
+8 -77
View File
@@ -159,85 +159,17 @@ impl EthereumNode for Instance {
let connection_string = self.connection_string();
let wallet = self.wallet.clone();
execute_transaction(Box::pin(async move {
let outer_span = tracing::debug_span!("Submitting transaction", ?transaction,);
let _outer_guard = outer_span.enter();
tracing::debug!("Submitting transaction: {transaction:#?}");
let provider = ProviderBuilder::new()
execute_transaction(Box::pin(async move {
Ok(ProviderBuilder::new()
.wallet(wallet)
.connect(&connection_string)
.await?;
let pending_transaction = provider.send_transaction(transaction).await?;
let transaction_hash = pending_transaction.tx_hash();
let span = tracing::info_span!("Awaiting transaction receipt", ?transaction_hash);
let _guard = span.enter();
// The following is a fix for the "transaction indexing is in progress" error that we
// used to get. You can find more information on this in the following GH issue in geth
// https://github.com/ethereum/go-ethereum/issues/28877. To summarize what's going on,
// before we can get the receipt of the transaction it needs to have been indexed by the
// node's indexer. Just because the transaction has been confirmed it doesn't mean that
// it has been indexed. When we call alloy's `get_receipt` it checks if the transaction
// was confirmed. If it has been, then it will call `eth_getTransactionReceipt` method
// which _might_ return the above error if the tx has not yet been indexed yet. So, we
// need to implement a retry mechanism for the receipt to keep retrying to get it until
// it eventually works, but we only do that if the error we get back is the "transaction
// indexing is in progress" error or if the receipt is None.
//
// At the moment we do not allow for the 60 seconds to be modified and we take it as
// being an implementation detail that's invisible to anything outside of this module.
//
// We allow a total of 60 retries for getting the receipt with one second between each
// retry and the next which means that we allow for a total of 60 seconds of waiting
// before we consider that we're unable to get the transaction receipt.
let mut retries = 0;
loop {
match provider.get_transaction_receipt(*transaction_hash).await {
Ok(Some(receipt)) => {
tracing::info!("Obtained the transaction receipt");
break Ok(receipt);
}
Ok(None) => {
if retries == 60 {
tracing::error!(
"Polled for transaction receipt for 60 seconds but failed to get it"
);
break Err(anyhow::anyhow!("Failed to get the transaction receipt"));
} else {
tracing::trace!(
retries,
"Sleeping for 1 second and trying to get the receipt again"
);
retries += 1;
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
continue;
}
}
Err(error) => {
let error_string = error.to_string();
if error_string.contains("transaction indexing is in progress") {
if retries == 60 {
tracing::error!(
"Polled for transaction receipt for 60 seconds but failed to get it"
);
break Err(error.into());
} else {
tracing::trace!(
retries,
"Sleeping for 1 second and trying to get the receipt again"
);
retries += 1;
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
continue;
}
} else {
break Err(error.into());
}
}
}
}
.await?
.send_transaction(transaction)
.await?
.get_receipt()
.await?)
}))
}
@@ -338,7 +270,6 @@ impl Node for Instance {
impl Drop for Instance {
fn drop(&mut self) {
tracing::info!(id = self.id, "Dropping node");
if let Some(child) = self.handle.as_mut() {
let _ = child.kill();
}
+34 -1
View File
@@ -128,6 +128,7 @@ impl KitchensinkNode {
// Start Substrate node
let mut substrate_process = Command::new(&self.substrate_binary)
.arg("--dev")
.arg("--chain")
.arg(chainspec_path)
.arg("--base-path")
@@ -808,13 +809,14 @@ impl BlockHeader for KitchenSinkHeader {
#[cfg(test)]
mod tests {
use alloy::rpc::types::TransactionRequest;
use revive_dt_config::Arguments;
use std::path::PathBuf;
use temp_dir::TempDir;
use std::fs;
use super::KitchensinkNode;
use super::*;
use crate::{GENESIS_JSON, Node};
fn test_config() -> (Arguments, TempDir) {
@@ -829,6 +831,37 @@ mod tests {
(config, temp_dir)
}
#[tokio::test]
async fn node_mines_simple_transfer_transaction_and_returns_receipt() {
// Arrange
let (args, _temp_dir) = test_config();
let mut node = KitchensinkNode::new(&args);
node.spawn(GENESIS_JSON.to_owned())
.expect("Failed to spawn the node");
let provider = ProviderBuilder::new()
.network::<KitchenSinkNetwork>()
.wallet(args.wallet())
.connect(&node.rpc_url)
.await
.expect("Failed to create provider");
let account_address = args.wallet().default_signer().address();
let transaction = TransactionRequest::default()
.to(account_address)
.value(U256::from(100_000_000_000_000u128));
// Act
let receipt = provider.send_transaction(transaction).await;
// Assert
let _ = receipt
.expect("Failed to send the transfer transaction")
.get_receipt()
.await
.expect("Failed to get the receipt for the transfer");
}
#[test]
fn test_init_generates_chainspec_with_balances() {
let genesis_content = r#"