Skip to content

Commit 418408f

Browse files
authored
Merge pull request #20 from ChainSafe/assethub_zombienet-forking-integration-tests
Assethub zombienet forking integration tests
2 parents a33f365 + 36b81f2 commit 418408f

File tree

6 files changed

+585
-80
lines changed

6 files changed

+585
-80
lines changed

crates/anvil-polkadot/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,4 +163,5 @@ op-alloy-rpc-types.workspace = true
163163

164164
[features]
165165
default = []
166-
asm-keccak = ["alloy-primitives/asm-keccak"]
166+
asm-keccak = ["alloy-primitives/asm-keccak"]
167+
forking-tests = []

crates/anvil-polkadot/src/substrate_node/service/client.rs

Lines changed: 2 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::{
22
AnvilNodeConfig,
3-
config::ForkChoice,
43
substrate_node::{
54
genesis::DevelopmentGenesisBlockBuilder,
65
lazy_loading::{
@@ -25,7 +24,7 @@ use polkadot_sdk::{
2524
sp_blockchain,
2625
sp_core::storage::well_known_keys::CODE,
2726
sp_keystore::KeystorePtr,
28-
sp_runtime::{generic::SignedBlock, traits::Header as HeaderT},
27+
sp_runtime::generic::SignedBlock,
2928
sp_storage::StorageKey,
3029
};
3130
use std::{collections::HashMap, sync::Arc, time::Duration};
@@ -42,8 +41,7 @@ pub fn new_client(
4241
) -> Result<(Arc<Client>, Arc<Backend>, KeystorePtr, TaskManager), sc_service::error::Error> {
4342
let fork_config: Option<(Arc<dyn RPCClient<Block>>, Block)> =
4443
if let Some(fork_url) = &anvil_config.eth_rpc_url {
45-
let (rpc_client, checkpoint_block) =
46-
setup_fork(anvil_config, config, fork_url, genesis_num)?;
44+
let (rpc_client, checkpoint_block) = setup_fork(config, fork_url, genesis_num)?;
4745
Some((rpc_client, checkpoint_block))
4846
} else {
4947
None
@@ -124,49 +122,8 @@ pub fn new_client(
124122
Ok((Arc::new(client), backend, keystore_container.keystore(), task_manager))
125123
}
126124

127-
/// Resolves the block number to fork from, handling both positive and negative block numbers.
128-
/// Negative numbers are subtracted from the latest block number.
129-
#[allow(dead_code)]
130-
fn resolve_fork_block_number(
131-
rpc_client: &Rpc<Block>,
132-
fork_choice: &ForkChoice,
133-
) -> Result<u32, sp_blockchain::Error> {
134-
match fork_choice {
135-
ForkChoice::Block(block_number) => {
136-
if *block_number < 0 {
137-
// Get the latest block from the chain header
138-
let latest_header = rpc_client
139-
.header(None)
140-
.map_err(|e| {
141-
sp_blockchain::Error::Backend(format!("failed to fetch latest header: {e}"))
142-
})?
143-
.ok_or_else(|| {
144-
sp_blockchain::Error::Backend("latest header not found".into())
145-
})?;
146-
147-
let latest_number: u32 = *latest_header.number();
148-
149-
let offset: u32 = block_number.abs().try_into().map_err(|_| {
150-
sp_blockchain::Error::Backend(format!(
151-
"Block number offset too large: {block_number}"
152-
))
153-
})?;
154-
155-
Ok(latest_number.saturating_sub(offset))
156-
} else {
157-
(*block_number).try_into().map_err(|_| {
158-
sp_blockchain::Error::Backend(format!(
159-
"Invalid fork block number: {block_number}"
160-
))
161-
})
162-
}
163-
}
164-
}
165-
}
166-
167125
/// Fetches the checkpoint block and sets up the chain spec for forking
168126
fn setup_fork(
169-
_anvil_config: &AnvilNodeConfig,
170127
config: &mut sc_service::Configuration,
171128
fork_url: &str,
172129
genesis_num: u64,
@@ -189,38 +146,6 @@ fn setup_fork(
189146
sp_blockchain::Error::Backend(format!("failed to fetch system_properties: {e}"))
190147
})?;
191148

192-
// TODO refactor this to account for fork choice
193-
// Get block hash from fork_choice config
194-
// If no fork_choice is specified, we need to fetch the latest block and use its hash
195-
// for all subsequent requests to avoid inconsistencies if a new block is mined between calls.
196-
// let block_hash: <Block as BlockT>::Hash = if let Some(fork_choice) =
197-
// &anvil_config.fork_choice { // let block_num = resolve_fork_block_number(&rpc_client,
198-
// fork_choice)?; let block_num = genesis_num as u32;
199-
// rpc_client
200-
// .block_hash(Some(block_num))
201-
// .map_err(|e| {
202-
// sp_blockchain::Error::Backend(format!(
203-
// "failed to fetch block hash for block {block_num}: {e}"
204-
// ))
205-
// })?
206-
// .ok_or_else(|| {
207-
// sp_blockchain::Error::Backend(format!("block hash not found for block
208-
// {block_num}")) })?
209-
// } else {
210-
// // No fork_choice specified, fetch the latest block header and use its hash
211-
// let latest_header = rpc_client
212-
// .header(None)
213-
// .map_err(|e| {
214-
// sp_blockchain::Error::Backend(format!(
215-
// "failed to fetch latest header for fork: {e}"
216-
// ))
217-
// })?
218-
// .ok_or_else(|| {
219-
// sp_blockchain::Error::Backend("latest header not found for fork".into())
220-
// })?;
221-
// latest_header.hash()
222-
// };
223-
224149
let block_num = genesis_num as u32;
225150
let block_hash = rpc_client
226151
.block_hash(Some(block_num))

crates/anvil-polkadot/src/substrate_node/service/mod.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::{
22
AnvilNodeConfig,
3+
config::ForkChoice,
34
substrate_node::{
45
lazy_loading::backend::Backend as LazyLoadingBackend,
56
mining_engine::{MiningEngine, MiningMode, run_mining_engine},
@@ -198,6 +199,7 @@ pub fn new(
198199
if let Some(ref fork_url) = anvil_config.eth_rpc_url {
199200
// TODO ws is for local host, wss for remote (aka prod)
200201
let http_url = fork_url.replacen("https://", "ws://", 1).replacen("http://", "ws://", 1);
202+
let fork_choice = anvil_config.fork_choice.clone();
201203
let storage_map = std::thread::spawn(move || -> eyre::Result<Result<u64, ()>> {
202204
let rt = TokioRtBuilder::new_current_thread()
203205
.enable_all()
@@ -217,7 +219,24 @@ pub fn new(
217219
.await
218220
.unwrap()
219221
.unwrap();
220-
Ok(Ok(finalized_head_header.number.into()))
222+
let finalized_block_number: u64 = finalized_head_header.number.into();
223+
224+
// Apply fork_choice if specified
225+
let target_block_number = match fork_choice {
226+
Some(ForkChoice::Block(block_num)) => {
227+
if block_num < 0 {
228+
// Negative offset from latest finalized block
229+
let offset = (-block_num) as u64;
230+
finalized_block_number.saturating_sub(offset)
231+
} else {
232+
// Specific block number
233+
block_num as u64
234+
}
235+
}
236+
None => finalized_block_number,
237+
};
238+
239+
Ok(Ok(target_block_number))
221240
})
222241
})
223242
.join()

0 commit comments

Comments
 (0)