This commit is contained in:
pgherveou
2025-10-08 06:28:57 +00:00
parent 765569a8b6
commit 1f84ce6f61
34 changed files with 1093 additions and 503 deletions
+24 -9
View File
@@ -33,7 +33,10 @@ impl Process {
let log_file_prefix = log_file_prefix.into();
let (stdout_file_name, stderr_file_name) = match log_file_prefix {
Some(prefix) => (format!("{prefix}_stdout.log"), format!("{prefix}_stderr.log")),
Some(prefix) => (
format!("{prefix}_stdout.log"),
format!("{prefix}_stderr.log"),
),
None => ("stdout.log".to_string(), "stderr.log".to_string()),
};
@@ -54,16 +57,20 @@ impl Process {
.context("Failed to open the stderr logs file")?;
let mut command = {
let stdout_logs_file =
stdout_logs_file.try_clone().context("Failed to clone the stdout logs file")?;
let stderr_logs_file =
stderr_logs_file.try_clone().context("Failed to clone the stderr logs file")?;
let stdout_logs_file = stdout_logs_file
.try_clone()
.context("Failed to clone the stdout logs file")?;
let stderr_logs_file = stderr_logs_file
.try_clone()
.context("Failed to clone the stderr logs file")?;
let mut command = Command::new(binary_path.as_ref());
command_building_callback(&mut command, stdout_logs_file, stderr_logs_file);
command
};
let mut child = command.spawn().context("Failed to spawn the built command")?;
let mut child = command
.spawn()
.context("Failed to spawn the built command")?;
match process_readiness_wait_behavior {
ProcessReadinessWaitBehavior::NoStartupWait => {}
@@ -121,7 +128,11 @@ impl Process {
}
}
ProcessReadinessWaitBehavior::WaitForCommandToExit => {
if !child.wait().context("Failed waiting for process to finish")?.success() {
if !child
.wait()
.context("Failed waiting for process to finish")?
.success()
{
anyhow::bail!("Failed to spawn command");
}
}
@@ -138,8 +149,12 @@ impl Process {
impl Drop for Process {
fn drop(&mut self) {
self.child.kill().expect("Failed to kill the process");
self.stdout_logs_file.flush().expect("Failed to flush the stdout logs file");
self.stderr_logs_file.flush().expect("Failed to flush the stderr logs file");
self.stdout_logs_file
.flush()
.expect("Failed to flush the stdout logs file");
self.stderr_logs_file
.flush()
.expect("Failed to flush the stderr logs file");
}
}
+66 -23
View File
@@ -108,7 +108,9 @@ impl GethNode {
let wallet_configuration = AsRef::<WalletConfiguration>::as_ref(&context);
let geth_configuration = AsRef::<GethConfiguration>::as_ref(&context);
let geth_directory = working_directory_configuration.as_path().join(Self::BASE_DIRECTORY);
let geth_directory = working_directory_configuration
.as_path()
.join(Self::BASE_DIRECTORY);
let id = NODE_COUNT.fetch_add(1, Ordering::SeqCst);
let base_directory = geth_directory.join(id.to_string());
@@ -196,7 +198,11 @@ impl GethNode {
.read_to_string(&mut stderr)
.context("Failed to read geth --init stderr")?;
if !child.wait().context("Failed waiting for geth --init process to finish")?.success() {
if !child
.wait()
.context("Failed waiting for geth --init process to finish")?
.success()
{
anyhow::bail!("failed to initialize geth node #{:?}: {stderr}", &self.id);
}
@@ -256,7 +262,8 @@ impl GethNode {
Ok(process) => self.handle = Some(process),
Err(err) => {
error!(?err, "Failed to start geth, shutting down gracefully");
self.shutdown().context("Failed to gracefully shutdown after geth start error")?;
self.shutdown()
.context("Failed to gracefully shutdown after geth start error")?;
return Err(err);
}
}
@@ -401,7 +408,10 @@ impl EthereumNode for GethNode {
}
},
)
.instrument(tracing::info_span!("Awaiting transaction receipt", ?transaction_hash))
.instrument(tracing::info_span!(
"Awaiting transaction receipt",
?transaction_hash
))
.await
})
}
@@ -413,8 +423,10 @@ impl EthereumNode for GethNode {
trace_options: GethDebugTracingOptions,
) -> Pin<Box<dyn Future<Output = anyhow::Result<GethTrace>> + '_>> {
Box::pin(async move {
let provider =
self.provider().await.context("Failed to create provider for tracing")?;
let provider = self
.provider()
.await
.context("Failed to create provider for tracing")?;
poll(
Self::TRACE_POLLING_DURATION,
PollingWaitBehavior::Constant(Duration::from_millis(200)),
@@ -422,7 +434,10 @@ impl EthereumNode for GethNode {
let provider = provider.clone();
let trace_options = trace_options.clone();
async move {
match provider.debug_trace_transaction(tx_hash, trace_options).await {
match provider
.debug_trace_transaction(tx_hash, trace_options)
.await
{
Ok(trace) => Ok(ControlFlow::Break(trace)),
Err(error) => {
let error_string = error.to_string();
@@ -502,10 +517,7 @@ impl EthereumNode for GethNode {
Box::pin(async move {
let id = self.id;
let provider = self.provider().await?;
Ok(Arc::new(GethNodeResolver {
id,
provider,
}) as Arc<dyn ResolverApi>)
Ok(Arc::new(GethNodeResolver { id, provider }) as Arc<dyn ResolverApi>)
})
}
@@ -648,7 +660,10 @@ impl ResolverApi for GethNodeResolver {
.context("Failed to get the geth block")?
.context("Failed to get the Geth block, perhaps there are no blocks?")
.and_then(|block| {
block.header.base_fee_per_gas.context("Failed to get the base fee per gas")
block
.header
.base_fee_per_gas
.context("Failed to get the base fee per gas")
})
})
}
@@ -765,7 +780,11 @@ mod tests {
// Arrange
let (context, node) = shared_state();
let account_address = context.wallet_configuration.wallet().default_signer().address();
let account_address = context
.wallet_configuration
.wallet()
.default_signer()
.address();
let transaction = TransactionRequest::default()
.to(account_address)
.value(U256::from(100_000_000_000_000u128));
@@ -788,7 +807,10 @@ mod tests {
// Assert
let version = version.expect("Failed to get the version");
assert!(version.starts_with("geth version"), "expected version string, got: '{version}'");
assert!(
version.starts_with("geth version"),
"expected version string, got: '{version}'"
);
}
#[tokio::test]
@@ -812,8 +834,12 @@ mod tests {
let node = shared_node();
// Act
let gas_limit =
node.resolver().await.unwrap().block_gas_limit(BlockNumberOrTag::Latest).await;
let gas_limit = node
.resolver()
.await
.unwrap()
.block_gas_limit(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = gas_limit.expect("Failed to get the gas limit");
@@ -826,8 +852,12 @@ mod tests {
let node = shared_node();
// Act
let coinbase =
node.resolver().await.unwrap().block_coinbase(BlockNumberOrTag::Latest).await;
let coinbase = node
.resolver()
.await
.unwrap()
.block_coinbase(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = coinbase.expect("Failed to get the coinbase");
@@ -840,8 +870,12 @@ mod tests {
let node = shared_node();
// Act
let block_difficulty =
node.resolver().await.unwrap().block_difficulty(BlockNumberOrTag::Latest).await;
let block_difficulty = node
.resolver()
.await
.unwrap()
.block_difficulty(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = block_difficulty.expect("Failed to get the block difficulty");
@@ -854,7 +888,12 @@ mod tests {
let node = shared_node();
// Act
let block_hash = node.resolver().await.unwrap().block_hash(BlockNumberOrTag::Latest).await;
let block_hash = node
.resolver()
.await
.unwrap()
.block_hash(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = block_hash.expect("Failed to get the block hash");
@@ -867,8 +906,12 @@ mod tests {
let node = shared_node();
// Act
let block_timestamp =
node.resolver().await.unwrap().block_timestamp(BlockNumberOrTag::Latest).await;
let block_timestamp = node
.resolver()
.await
.unwrap()
.block_timestamp(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = block_timestamp.expect("Failed to get the block timestamp");
@@ -132,7 +132,9 @@ impl LighthouseGethNode {
let wallet_configuration = AsRef::<WalletConfiguration>::as_ref(&context);
let kurtosis_configuration = AsRef::<KurtosisConfiguration>::as_ref(&context);
let geth_directory = working_directory_configuration.as_path().join(Self::BASE_DIRECTORY);
let geth_directory = working_directory_configuration
.as_path()
.join(Self::BASE_DIRECTORY);
let id = NODE_COUNT.fetch_add(1, Ordering::SeqCst);
let base_directory = geth_directory.join(id.to_string());
@@ -145,7 +147,10 @@ impl LighthouseGethNode {
http_connection_string: String::default(),
enclave_name: format!(
"enclave-{}-{}",
SystemTime::now().duration_since(UNIX_EPOCH).expect("Must not fail").as_nanos(),
SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Must not fail")
.as_nanos(),
id
),
@@ -178,7 +183,8 @@ impl LighthouseGethNode {
fn init(&mut self, _: Genesis) -> anyhow::Result<&mut Self> {
self.init_directories()
.context("Failed to initialize the directories of the Lighthouse Geth node.")?;
self.init_kurtosis_config_file().context("Failed to write the config file to the FS")?;
self.init_kurtosis_config_file()
.context("Failed to write the config file to the FS")?;
Ok(self)
}
@@ -420,8 +426,9 @@ impl LighthouseGethNode {
.context("Full block subscriber")?;
let mut tx_hashes = futures::future::try_join_all(
NetworkWallet::<Ethereum>::signer_addresses(self.wallet.as_ref()).enumerate().map(
|(nonce, address)| async move {
NetworkWallet::<Ethereum>::signer_addresses(self.wallet.as_ref())
.enumerate()
.map(|(nonce, address)| async move {
let mut transaction = TransactionRequest::default()
.from(self.prefunded_account_address)
.to(address)
@@ -429,8 +436,7 @@ impl LighthouseGethNode {
.value(INITIAL_BALANCE.try_into().unwrap());
transaction.chain_id = Some(CHAIN_ID);
self.submit_transaction(transaction).await
},
),
}),
)
.await
.context("Failed to submit all transactions")?
@@ -525,7 +531,10 @@ impl LighthouseGethNode {
}
},
)
.instrument(tracing::info_span!("Awaiting transaction receipt", ?transaction_hash))
.instrument(tracing::info_span!(
"Awaiting transaction receipt",
?transaction_hash
))
.await
})
}
@@ -614,7 +623,9 @@ impl EthereumNode for LighthouseGethNode {
) -> Pin<Box<dyn Future<Output = anyhow::Result<GethTrace>> + '_>> {
Box::pin(async move {
let provider = Arc::new(
self.http_provider().await.context("Failed to create provider for tracing")?,
self.http_provider()
.await
.context("Failed to create provider for tracing")?,
);
poll(
Self::TRACE_POLLING_DURATION,
@@ -623,7 +634,10 @@ impl EthereumNode for LighthouseGethNode {
let provider = provider.clone();
let trace_options = trace_options.clone();
async move {
match provider.debug_trace_transaction(tx_hash, trace_options).await {
match provider
.debug_trace_transaction(tx_hash, trace_options)
.await
{
Ok(trace) => Ok(ControlFlow::Break(trace)),
Err(error) => {
let error_string = error.to_string();
@@ -703,10 +717,7 @@ impl EthereumNode for LighthouseGethNode {
Box::pin(async move {
let id = self.id;
let provider = self.ws_provider().await?;
Ok(Arc::new(LighthouseGethNodeResolver {
id,
provider,
}) as Arc<dyn ResolverApi>)
Ok(Arc::new(LighthouseGethNodeResolver { id, provider }) as Arc<dyn ResolverApi>)
})
}
@@ -848,7 +859,10 @@ impl<F: TxFiller<Ethereum>, P: Provider<Ethereum>> ResolverApi
.context("Failed to get the geth block")?
.context("Failed to get the Geth block, perhaps there are no blocks?")
.and_then(|block| {
block.header.base_fee_per_gas.context("Failed to get the base fee per gas")
block
.header
.base_fee_per_gas
.context("Failed to get the base fee per gas")
})
})
}
@@ -902,7 +916,11 @@ impl Node for LighthouseGethNode {
.spawn()
.expect("Failed to spawn the enclave kill command");
if !child.wait().expect("Failed to wait for the enclave kill command").success() {
if !child
.wait()
.expect("Failed to wait for the enclave kill command")
.success()
{
let stdout = {
let mut stdout = String::default();
child
@@ -1128,7 +1146,11 @@ mod tests {
let (context, node) = new_node();
node.fund_all_accounts().await.expect("Failed");
let account_address = context.wallet_configuration.wallet().default_signer().address();
let account_address = context
.wallet_configuration
.wallet()
.default_signer()
.address();
let transaction = TransactionRequest::default()
.to(account_address)
.value(U256::from(100_000_000_000_000u128));
@@ -1151,7 +1173,10 @@ mod tests {
// Assert
let version = version.expect("Failed to get the version");
assert!(version.starts_with("CLI Version"), "expected version string, got: '{version}'");
assert!(
version.starts_with("CLI Version"),
"expected version string, got: '{version}'"
);
}
#[tokio::test]
@@ -1175,8 +1200,12 @@ mod tests {
let (_context, node) = new_node();
// Act
let gas_limit =
node.resolver().await.unwrap().block_gas_limit(BlockNumberOrTag::Latest).await;
let gas_limit = node
.resolver()
.await
.unwrap()
.block_gas_limit(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = gas_limit.expect("Failed to get the gas limit");
@@ -1189,8 +1218,12 @@ mod tests {
let (_context, node) = new_node();
// Act
let coinbase =
node.resolver().await.unwrap().block_coinbase(BlockNumberOrTag::Latest).await;
let coinbase = node
.resolver()
.await
.unwrap()
.block_coinbase(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = coinbase.expect("Failed to get the coinbase");
@@ -1203,8 +1236,12 @@ mod tests {
let (_context, node) = new_node();
// Act
let block_difficulty =
node.resolver().await.unwrap().block_difficulty(BlockNumberOrTag::Latest).await;
let block_difficulty = node
.resolver()
.await
.unwrap()
.block_difficulty(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = block_difficulty.expect("Failed to get the block difficulty");
@@ -1217,7 +1254,12 @@ mod tests {
let (_context, node) = new_node();
// Act
let block_hash = node.resolver().await.unwrap().block_hash(BlockNumberOrTag::Latest).await;
let block_hash = node
.resolver()
.await
.unwrap()
.block_hash(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = block_hash.expect("Failed to get the block hash");
@@ -1230,8 +1272,12 @@ mod tests {
let (_context, node) = new_node();
// Act
let block_timestamp =
node.resolver().await.unwrap().block_timestamp(BlockNumberOrTag::Latest).await;
let block_timestamp = node
.resolver()
.await
.unwrap()
.block_timestamp(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = block_timestamp.expect("Failed to get the block timestamp");
@@ -108,7 +108,9 @@ impl SubstrateNode {
) -> Self {
let working_directory_path =
AsRef::<WorkingDirectoryConfiguration>::as_ref(&context).as_path();
let eth_rpc_path = AsRef::<EthRpcConfiguration>::as_ref(&context).path.as_path();
let eth_rpc_path = AsRef::<EthRpcConfiguration>::as_ref(&context)
.path
.as_path();
let wallet = AsRef::<WalletConfiguration>::as_ref(&context).wallet();
let substrate_directory = working_directory_path.join(Self::BASE_DIRECTORY);
@@ -325,12 +327,15 @@ impl SubstrateNode {
&self,
genesis: &Genesis,
) -> anyhow::Result<Vec<(String, u128)>> {
genesis.alloc.iter().try_fold(Vec::new(), |mut vec, (address, acc)| {
let substrate_address = Self::eth_to_substrate_address(address);
let balance = acc.balance.try_into()?;
vec.push((substrate_address, balance));
Ok(vec)
})
genesis
.alloc
.iter()
.try_fold(Vec::new(), |mut vec, (address, acc)| {
let substrate_address = Self::eth_to_substrate_address(address);
let balance = acc.balance.try_into()?;
vec.push((substrate_address, balance));
Ok(vec)
})
}
fn eth_to_substrate_address(address: &Address) -> String {
@@ -425,7 +430,10 @@ impl EthereumNode for SubstrateNode {
transaction: TransactionRequest,
) -> Pin<Box<dyn Future<Output = anyhow::Result<TransactionReceipt>> + '_>> {
Box::pin(async move {
let provider = self.provider().await.context("Failed to create the provider")?;
let provider = self
.provider()
.await
.context("Failed to create the provider")?;
execute_transaction(provider, transaction).await
})
}
@@ -502,10 +510,7 @@ impl EthereumNode for SubstrateNode {
Box::pin(async move {
let id = self.id;
let provider = self.provider().await?;
Ok(Arc::new(SubstrateNodeResolver {
id,
provider,
}) as Arc<dyn ResolverApi>)
Ok(Arc::new(SubstrateNodeResolver { id, provider }) as Arc<dyn ResolverApi>)
})
}
@@ -526,8 +531,10 @@ impl EthereumNode for SubstrateNode {
.provider()
.await
.context("Failed to create the provider for block subscription")?;
let mut block_subscription =
provider.watch_full_blocks().await.context("Failed to create the blocks stream")?;
let mut block_subscription = provider
.watch_full_blocks()
.await
.context("Failed to create the blocks stream")?;
block_subscription.set_channel_size(0xFFFF);
block_subscription.set_poll_interval(Duration::from_secs(1));
let block_stream = block_subscription.into_stream();
@@ -648,7 +655,10 @@ impl ResolverApi for SubstrateNodeResolver {
.context("Failed to get the substrate block")?
.context("Failed to get the substrate block, perhaps the chain has no blocks?")
.and_then(|block| {
block.header.base_fee_per_gas.context("Failed to get the base fee per gas")
block
.header
.base_fee_per_gas
.context("Failed to get the base fee per gas")
})
})
}
@@ -927,26 +937,25 @@ impl TransactionBuilder<ReviveNetwork> for <Ethereum as Network>::TransactionReq
);
match result {
Ok(unsigned_tx) => Ok(unsigned_tx),
Err(UnbuiltTransactionError {
request,
error,
}) => Err(UnbuiltTransactionError::<ReviveNetwork> {
request,
error: match error {
TransactionBuilderError::InvalidTransactionRequest(tx_type, items) => {
TransactionBuilderError::InvalidTransactionRequest(tx_type, items)
}
TransactionBuilderError::UnsupportedSignatureType => {
TransactionBuilderError::UnsupportedSignatureType
}
TransactionBuilderError::Signer(error) => {
TransactionBuilderError::Signer(error)
}
TransactionBuilderError::Custom(error) => {
TransactionBuilderError::Custom(error)
}
},
}),
Err(UnbuiltTransactionError { request, error }) => {
Err(UnbuiltTransactionError::<ReviveNetwork> {
request,
error: match error {
TransactionBuilderError::InvalidTransactionRequest(tx_type, items) => {
TransactionBuilderError::InvalidTransactionRequest(tx_type, items)
}
TransactionBuilderError::UnsupportedSignatureType => {
TransactionBuilderError::UnsupportedSignatureType
}
TransactionBuilderError::Signer(error) => {
TransactionBuilderError::Signer(error)
}
TransactionBuilderError::Custom(error) => {
TransactionBuilderError::Custom(error)
}
},
})
}
}
}
@@ -1214,7 +1223,11 @@ mod tests {
let provider = node.provider().await.expect("Failed to create provider");
let account_address = context.wallet_configuration.wallet().default_signer().address();
let account_address = context
.wallet_configuration
.wallet()
.default_signer()
.address();
let transaction = TransactionRequest::default()
.to(account_address)
.value(U256::from(100_000_000_000_000u128));
@@ -1254,11 +1267,14 @@ mod tests {
);
// Call `init()`
dummy_node.init(serde_json::from_str(genesis_content).unwrap()).expect("init failed");
dummy_node
.init(serde_json::from_str(genesis_content).unwrap())
.expect("init failed");
// Check that the patched chainspec file was generated
let final_chainspec_path =
dummy_node.base_directory.join(SubstrateNode::CHAIN_SPEC_JSON_FILE);
let final_chainspec_path = dummy_node
.base_directory
.join(SubstrateNode::CHAIN_SPEC_JSON_FILE);
assert!(final_chainspec_path.exists(), "Chainspec file should exist");
let contents = fs::read_to_string(&final_chainspec_path).expect("Failed to read chainspec");
@@ -1364,7 +1380,10 @@ mod tests {
for (eth_addr, expected_ss58) in cases {
let result = SubstrateNode::eth_to_substrate_address(&eth_addr.parse().unwrap());
assert_eq!(result, expected_ss58, "Mismatch for Ethereum address {eth_addr}");
assert_eq!(
result, expected_ss58,
"Mismatch for Ethereum address {eth_addr}"
);
}
}
@@ -1415,8 +1434,12 @@ mod tests {
let node = shared_node();
// Act
let gas_limit =
node.resolver().await.unwrap().block_gas_limit(BlockNumberOrTag::Latest).await;
let gas_limit = node
.resolver()
.await
.unwrap()
.block_gas_limit(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = gas_limit.expect("Failed to get the gas limit");
@@ -1429,8 +1452,12 @@ mod tests {
let node = shared_node();
// Act
let coinbase =
node.resolver().await.unwrap().block_coinbase(BlockNumberOrTag::Latest).await;
let coinbase = node
.resolver()
.await
.unwrap()
.block_coinbase(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = coinbase.expect("Failed to get the coinbase");
@@ -1443,8 +1470,12 @@ mod tests {
let node = shared_node();
// Act
let block_difficulty =
node.resolver().await.unwrap().block_difficulty(BlockNumberOrTag::Latest).await;
let block_difficulty = node
.resolver()
.await
.unwrap()
.block_difficulty(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = block_difficulty.expect("Failed to get the block difficulty");
@@ -1457,7 +1488,12 @@ mod tests {
let node = shared_node();
// Act
let block_hash = node.resolver().await.unwrap().block_hash(BlockNumberOrTag::Latest).await;
let block_hash = node
.resolver()
.await
.unwrap()
.block_hash(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = block_hash.expect("Failed to get the block hash");
@@ -1470,8 +1506,12 @@ mod tests {
let node = shared_node();
// Act
let block_timestamp =
node.resolver().await.unwrap().block_timestamp(BlockNumberOrTag::Latest).await;
let block_timestamp = node
.resolver()
.await
.unwrap()
.block_timestamp(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = block_timestamp.expect("Failed to get the block timestamp");
@@ -130,10 +130,14 @@ impl ZombieNode {
+ AsRef<EthRpcConfiguration>
+ AsRef<WalletConfiguration>,
) -> Self {
let eth_proxy_binary = AsRef::<EthRpcConfiguration>::as_ref(&context).path.to_owned();
let eth_proxy_binary = AsRef::<EthRpcConfiguration>::as_ref(&context)
.path
.to_owned();
let working_directory_path = AsRef::<WorkingDirectoryConfiguration>::as_ref(&context);
let id = NODE_COUNT.fetch_add(1, Ordering::SeqCst);
let base_directory = working_directory_path.join(Self::BASE_DIRECTORY).join(id.to_string());
let base_directory = working_directory_path
.join(Self::BASE_DIRECTORY)
.join(id.to_string());
let logs_directory = base_directory.join(Self::LOGS_DIRECTORY);
let wallet = AsRef::<WalletConfiguration>::as_ref(&context).wallet();
@@ -165,8 +169,10 @@ impl ZombieNode {
let template_chainspec_path = self.base_directory.join(Self::CHAIN_SPEC_JSON_FILE);
self.prepare_chainspec(template_chainspec_path.clone(), genesis)?;
let polkadot_parachain_path =
self.polkadot_parachain_path.to_str().context("Invalid polkadot parachain path")?;
let polkadot_parachain_path = self
.polkadot_parachain_path
.to_str()
.context("Invalid polkadot parachain path")?;
let node_rpc_port = Self::NODE_BASE_RPC_PORT + self.id as u16;
@@ -198,8 +204,10 @@ impl ZombieNode {
}
fn spawn_process(&mut self) -> anyhow::Result<()> {
let network_config =
self.network_config.clone().context("Node not initialized, call init() first")?;
let network_config = self
.network_config
.clone()
.context("Node not initialized, call init() first")?;
let rt = tokio::runtime::Runtime::new().unwrap();
let network = rt.block_on(async {
@@ -264,12 +272,17 @@ impl ZombieNode {
mut genesis: Genesis,
) -> anyhow::Result<()> {
let mut cmd: Command = std::process::Command::new(&self.polkadot_parachain_path);
cmd.arg(Self::EXPORT_CHAINSPEC_COMMAND).arg("--chain").arg("asset-hub-westend-local");
cmd.arg(Self::EXPORT_CHAINSPEC_COMMAND)
.arg("--chain")
.arg("asset-hub-westend-local");
let output = cmd.output().context("Failed to export the chain-spec")?;
if !output.status.success() {
anyhow::bail!("Build chain-spec failed: {}", String::from_utf8_lossy(&output.stderr));
anyhow::bail!(
"Build chain-spec failed: {}",
String::from_utf8_lossy(&output.stderr)
);
}
let content = String::from_utf8(output.stdout)
@@ -330,12 +343,15 @@ impl ZombieNode {
&self,
genesis: &Genesis,
) -> anyhow::Result<Vec<(String, u128)>> {
genesis.alloc.iter().try_fold(Vec::new(), |mut vec, (address, acc)| {
let polkadot_address = Self::eth_to_polkadot_address(address);
let balance = acc.balance.try_into()?;
vec.push((polkadot_address, balance));
Ok(vec)
})
genesis
.alloc
.iter()
.try_fold(Vec::new(), |mut vec, (address, acc)| {
let polkadot_address = Self::eth_to_polkadot_address(address);
let balance = acc.balance.try_into()?;
vec.push((polkadot_address, balance));
Ok(vec)
})
}
fn eth_to_polkadot_address(address: &Address) -> String {
@@ -519,10 +535,7 @@ impl EthereumNode for ZombieNode {
let id = self.id;
let provider = self.provider().await?;
Ok(Arc::new(ZombieNodeResolver {
id,
provider,
}) as Arc<dyn ResolverApi>)
Ok(Arc::new(ZombieNodeResolver { id, provider }) as Arc<dyn ResolverApi>)
})
}
@@ -543,8 +556,10 @@ impl EthereumNode for ZombieNode {
.provider()
.await
.context("Failed to create the provider for block subscription")?;
let mut block_subscription =
provider.watch_full_blocks().await.context("Failed to create the blocks stream")?;
let mut block_subscription = provider
.watch_full_blocks()
.await
.context("Failed to create the blocks stream")?;
block_subscription.set_channel_size(0xFFFF);
block_subscription.set_poll_interval(Duration::from_secs(1));
let block_stream = block_subscription.into_stream();
@@ -667,7 +682,10 @@ impl<F: TxFiller<ReviveNetwork>, P: Provider<ReviveNetwork>> ResolverApi
.context("Failed to get the zombie block")?
.context("Failed to get the zombie block, perhaps the chain has no blocks?")
.and_then(|block| {
block.header.base_fee_per_gas.context("Failed to get the base fee per gas")
block
.header
.base_fee_per_gas
.context("Failed to get the base fee per gas")
})
})
}
@@ -779,8 +797,10 @@ mod tests {
pub async fn new_node() -> (TestExecutionContext, ZombieNode) {
let context = test_config();
let mut node =
ZombieNode::new(context.polkadot_parachain_configuration.path.clone(), &context);
let mut node = ZombieNode::new(
context.polkadot_parachain_configuration.path.clone(),
&context,
);
let genesis = context.genesis_configuration.genesis().unwrap().clone();
node.init(genesis).unwrap();
@@ -845,11 +865,14 @@ mod tests {
"#;
let context = test_config();
let mut node =
ZombieNode::new(context.polkadot_parachain_configuration.path.clone(), &context);
let mut node = ZombieNode::new(
context.polkadot_parachain_configuration.path.clone(),
&context,
);
// Call `init()`
node.init(serde_json::from_str(genesis_content).unwrap()).expect("init failed");
node.init(serde_json::from_str(genesis_content).unwrap())
.expect("init failed");
// Check that the patched chainspec file was generated
let final_chainspec_path = node.base_directory.join(ZombieNode::CHAIN_SPEC_JSON_FILE);
@@ -890,7 +913,10 @@ mod tests {
"#;
let context = test_config();
let node = ZombieNode::new(context.polkadot_parachain_configuration.path.clone(), &context);
let node = ZombieNode::new(
context.polkadot_parachain_configuration.path.clone(),
&context,
);
let result = node
.extract_balance_from_genesis_file(&serde_json::from_str(genesis_json).unwrap())
@@ -952,7 +978,10 @@ mod tests {
for (eth_addr, expected_ss58) in cases {
let result = ZombieNode::eth_to_polkadot_address(&eth_addr.parse().unwrap());
assert_eq!(result, expected_ss58, "Mismatch for Ethereum address {eth_addr}");
assert_eq!(
result, expected_ss58,
"Mismatch for Ethereum address {eth_addr}"
);
}
}
@@ -960,7 +989,10 @@ mod tests {
fn eth_rpc_version_works() {
// Arrange
let context = test_config();
let node = ZombieNode::new(context.polkadot_parachain_configuration.path.clone(), &context);
let node = ZombieNode::new(
context.polkadot_parachain_configuration.path.clone(),
&context,
);
// Act
let version = node.eth_rpc_version().unwrap();
@@ -976,7 +1008,10 @@ mod tests {
fn version_works() {
// Arrange
let context = test_config();
let node = ZombieNode::new(context.polkadot_parachain_configuration.path.clone(), &context);
let node = ZombieNode::new(
context.polkadot_parachain_configuration.path.clone(),
&context,
);
// Act
let version = node.version().unwrap();
@@ -1014,8 +1049,12 @@ mod tests {
let node = shared_node().await;
// Act
let gas_limit =
node.resolver().await.unwrap().block_gas_limit(BlockNumberOrTag::Latest).await;
let gas_limit = node
.resolver()
.await
.unwrap()
.block_gas_limit(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = gas_limit.expect("Failed to get the gas limit");
@@ -1028,8 +1067,12 @@ mod tests {
let node = shared_node().await;
// Act
let coinbase =
node.resolver().await.unwrap().block_coinbase(BlockNumberOrTag::Latest).await;
let coinbase = node
.resolver()
.await
.unwrap()
.block_coinbase(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = coinbase.expect("Failed to get the coinbase");
@@ -1042,8 +1085,12 @@ mod tests {
let node = shared_node().await;
// Act
let block_difficulty =
node.resolver().await.unwrap().block_difficulty(BlockNumberOrTag::Latest).await;
let block_difficulty = node
.resolver()
.await
.unwrap()
.block_difficulty(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = block_difficulty.expect("Failed to get the block difficulty");
@@ -1056,7 +1103,12 @@ mod tests {
let node = shared_node().await;
// Act
let block_hash = node.resolver().await.unwrap().block_hash(BlockNumberOrTag::Latest).await;
let block_hash = node
.resolver()
.await
.unwrap()
.block_hash(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = block_hash.expect("Failed to get the block hash");
@@ -1069,8 +1121,12 @@ mod tests {
let node = shared_node().await;
// Act
let block_timestamp =
node.resolver().await.unwrap().block_timestamp(BlockNumberOrTag::Latest).await;
let block_timestamp = node
.resolver()
.await
.unwrap()
.block_timestamp(BlockNumberOrTag::Latest)
.await;
// Assert
let _ = block_timestamp.expect("Failed to get the block timestamp");
@@ -55,7 +55,10 @@ where
let future = self.service.call(req);
Box::pin(async move {
let _permit = semaphore.acquire().await.expect("Semaphore has been closed");
let _permit = semaphore
.acquire()
.await
.expect("Semaphore has been closed");
tracing::debug!(
available_permits = semaphore.available_permits(),
"Acquired Semaphore Permit"
+19 -14
View File
@@ -80,8 +80,10 @@ where
NonceFiller: TxFiller<N>,
WalletFiller<W>: TxFiller<N>,
{
let sendable_transaction =
provider.fill(transaction).await.context("Failed to fill transaction")?;
let sendable_transaction = provider
.fill(transaction)
.await
.context("Failed to fill transaction")?;
let transaction_envelope = sendable_transaction
.try_into_envelope()
@@ -103,21 +105,24 @@ where
debug!(%tx_hash, "Submitted Transaction");
pending_transaction.set_timeout(Some(Duration::from_secs(120)));
let tx_hash = pending_transaction
.watch()
.await
.context(format!("Transaction inclusion watching timeout for {tx_hash}"))?;
let tx_hash = pending_transaction.watch().await.context(format!(
"Transaction inclusion watching timeout for {tx_hash}"
))?;
poll(Duration::from_secs(60), PollingWaitBehavior::Constant(Duration::from_secs(3)), || {
let provider = provider.clone();
poll(
Duration::from_secs(60),
PollingWaitBehavior::Constant(Duration::from_secs(3)),
|| {
let provider = provider.clone();
async move {
match provider.get_transaction_receipt(tx_hash).await {
Ok(Some(receipt)) => Ok(ControlFlow::Break(receipt)),
_ => Ok(ControlFlow::Continue(())),
async move {
match provider.get_transaction_receipt(tx_hash).await {
Ok(Some(receipt)) => Ok(ControlFlow::Break(receipt)),
_ => Ok(ControlFlow::Continue(())),
}
}
}
})
},
)
.await
.context(format!("Polling for receipt failed for {tx_hash}"))
}