A cli tool to easily fork live networks (e.g kusama/polkadot).
Currently this tool is focused in the AH migration project and isn't ready to use as general purpouse tool without customization.
zombie-bite
is a simple cli tool that allow you to spawn a new network based on a live one (e.g kusama/polkadot/ paseo). Under the hood we orchestrate the sync
prior to bite and spawn a new network with the live state using doppelganger
(based on paritytech/polkadot-sdk#4230) as family of binaries that allow us to inject some keys using a custom block_import
on top of the regular one.
In order to use this tool you will need this binaries available in your PATH
- Doppelganger binaries (doppelganger, doppelganger-parachain, workers)
zombie-bite
was designed focused on creating reusble artifacts on each step, the expected flow of usage is:
-
bite
the desired network, this will run the biting process and generate the artifacts tospawn
the bited network as many times you want. -
spawn
the network, reutilizing the artifacts from the bitting process. Ones the network is running you can signalzombie-bite
to stop it and generate the artifacts for thepost
state. (e.g: Is expected to run the AH migration as part of this step). -
post
step it utilized when you want to reuse a network from the artifacts generated by thespawn
step. (e.g: Is expected to run the post migration test using this step)
-
Base Path (base_path):
zombie_bite
encapsulate all the intermedia and generated files in this directory, using three main subdirectories (bite
,spawn
andpost
). If this directories are already used,zombie-bite
will move the content to a new one with a numerical suffix (e.g something likespawn.0
). -
Signal Stop: Ones the network is running, you can signal
zombie-bite
to stop it and pack the artifacts by placing a file calledstop.txt
in the base_path
Currently zombie-bite
support a set of subcommands that allow you to reuse the artifacts from the different steps
❯ cargo run -- help
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.32s
Running `target/debug/zombie-bite help`
Usage: zombie-bite <COMMAND>
Commands:
bite Bite the running network using 'doppelganger' binaries, and generate the artifacts for spawning
spawn Spawn a new instance of the network from the bite step
generate-artifacts [Helper] Generate artifacts to be used by the next step (only 'spawn' and 'post' allowed)
clean-up-dir [Helper] Clean up directory to only include the needed artifacts
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print version
As this tool is primarily for the AHM project, we will focus in this section on how to use it to bite a live network (e.g: polakadot) with asset-hub. Then spawn a new instance of the network, run the migration and stop the network to later spawn for running the post migration test.
The order of resolution that zombie-bite
use is:
- Iff the
--base-path
or-d
option is provided use that path. - If the option is not passed as cli args, use the env var 'ZOMBIE_BITE_BASE_PATH'.
- If the env var is not provided, fallback to use
<cwd>_timestamp
.
First we need to have compiled the runtimes we want to override for the rc and ah, then we can start the bite
process by running.
zombie-bite bite -d /tmp/ahm-migration -r polkadot --rc-override ./runtime_wasm/polkadot_runtime.compact.compressed.wasm --ah-override ./runtime_wasm/asset_hub_polkadot_runtime.compact.compressed.wasm
Note: We will using this path /tmp/ahm-migration
for the whole flow.
Ones this process completed, we will have all the needed artifacts to spawn a new instance of the bited network
The next step is to spawn the network, and run the runtime migration. We can spawn
a new instance of the bited network with the following cmd:
zombie-bite spawn -d /tmp/ahm-migration
This will spawn the network and print direct links to connect to the nodes using both pjs
or papi
. Also, where the logs are stored and the command usage for spawn each node:
2025-08-02T00:26:33.286194Z INFO zombienet_orchestrator::spawner: 🚀 alice, should be running now
2025-08-02T00:26:33.286215Z INFO zombienet_orchestrator::spawner: 💻 alice: direct link (pjs) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:60568#/explorer
2025-08-02T00:26:33.286219Z INFO zombienet_orchestrator::spawner: 💻 alice: direct link (papi) https://dev.papi.how/explorer#networkId=custom&endpoint=ws://127.0.0.1:60568
2025-08-02T00:26:33.286222Z INFO zombienet_orchestrator::spawner: 📊 alice: metrics link http://127.0.0.1:56245/metrics
2025-08-02T00:26:33.286228Z INFO zombienet_orchestrator::spawner: 📓 logs cmd: tail -f /parity/zombie-bite_1754046046/post/alice/alice.log
2025-08-02T00:26:33.457376Z INFO zombienet_orchestrator::spawner: 🚀 bob, spawning.... with command: doppelganger --chain /parity/zombie-bite_1754046046/post/bob/cfg/polkadot.json --name bob --rpc-cors all --rpc-methods unsafe --node-key 81b637d8fcd2c6da6359e6963113a1170de795e4b725b84d1e0b4cfd9ec58ce9 --no-telemetry --prometheus-external --validator --insecure-validator-i-know-what-i-do --prometheus-port 56250 --rpc-port 56249 --listen-addr /ip4/0.0.0.0/tcp/56251/ws --base-path /parity/zombie-bite_1754046046/post/bob/data --bootnodes /ip4/127.0.0.1/tcp/56246/ws/p2p/12D3KooWQCkBm1BYtkHpocxCwMgR8yjitEeHGx8spzcDLGt2gkBm -l=babe=trace,grandpa=info,runtime=trace,consensus::common=trace,parachain=debug --discover-local --allow-private-ip --no-hardware-benchmarks
2025-08-02T00:26:59.339049Z INFO zombienet_orchestrator::spawner: 🚀 bob, should be running now
2025-08-02T00:26:59.339072Z INFO zombienet_orchestrator::spawner: 💻 bob: direct link (pjs) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:56249#/explorer
2025-08-02T00:26:59.339076Z INFO zombienet_orchestrator::spawner: 💻 bob: direct link (papi) https://dev.papi.how/explorer#networkId=custom&endpoint=ws://127.0.0.1:56249
2025-08-02T00:26:59.339079Z INFO zombienet_orchestrator::spawner: 📊 bob: metrics link http://127.0.0.1:56250/metrics
2025-08-02T00:26:59.339084Z INFO zombienet_orchestrator::spawner: 📓 logs cmd: tail -f /parity/zombie-bite_1754046046/post/bob/bob.log
2025-08-02T00:26:59.343660Z INFO zombienet_orchestrator::spawner: 🚀 collator, spawning.... with command: doppelganger-parachain --chain /parity/zombie-bite_1754046046/post/collator/cfg/1000.json --name collator --rpc-cors all --rpc-methods unsafe --node-key 53cf10627db4ce8abcddad56fc510cdfc58bfe587b0cbb6772f1f0727266e565 --prometheus-external --collator --prometheus-port 56255 --rpc-port 60569 --listen-addr /ip4/0.0.0.0/tcp/56256/ws --base-path /parity/zombie-bite_1754046046/post/collator/data --relay-chain-rpc-urls ws://127.0.0.1:60568 -l=aura=debug,runtime=debug,cumulus-consensus=trace,consensus::common=trace,parachain::collation-generation=trace,parachain::collator-protocol=trace,parachain=debug,xcm=trace --force-authoring --discover-local --allow-private-ip --no-hardware-benchmarks -- --base-path /parity/zombie-bite_1754046046/post/collator/relay-data --chain /parity/zombie-bite_1754046046/post/collator/cfg/polkadot.json --execution wasm --port 56252 --prometheus-port 56253
2025-08-02T00:27:30.223794Z INFO zombienet_orchestrator::spawner: 🚀 collator, should be running now
2025-08-02T00:27:30.223819Z INFO zombienet_orchestrator::spawner: 💻 collator: direct link (pjs) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:60569#/explorer
2025-08-02T00:27:30.223824Z INFO zombienet_orchestrator::spawner: 💻 collator: direct link (papi) https://dev.papi.how/explorer#networkId=custom&endpoint=ws://127.0.0.1:60569
2025-08-02T00:27:30.223828Z INFO zombienet_orchestrator::spawner: 📊 collator: metrics link http://127.0.0.1:56255/metrics
2025-08-02T00:27:30.223839Z INFO zombienet_orchestrator::spawner: 📊 collator: collator full-node metrics link http://127.0.0.1:56253/metrics
2025-08-02T00:27:30.223844Z INFO zombienet_orchestrator::spawner: 📓 logs cmd: tail -f /parity/zombie-bite_1754046046/post/collator/collator.log
Also, the spawn process have will wait until finalize a few blocks (3) to confirm the bootstrap of the network and a monitorin process will run and check the block production every 15 minutes. If this process detect that some node is stall will proceed to restart it.
For AHM, this is the moment to run the migration and ones is completed you can signal zombie-bite
to teardown the current network and generate the artifacts for post migration test.
To signal the teardown, you should create a fila called stop.txt in the base_path
touch /parity/zombie-bite_1754046046/stop.txt
This will automatically teardown the network and generate the artifacts.
The post
step is mainly thought to run post migration test or any other logic you want to run from the previous state of the network.
To spawn the network as part of the post
step you can run
zombie-bite spawn -d /tmp/ahm-migration -s post
Again, this will print network information and you can signal to teardown by creating the stop.txt
file inside the base_path
touch /parity/zombie-bite_1754046046/stop.txt
By default the relaychain nodes are spawned with this log levesl:
babe=trace,grandpa=trace,runtime=debug,consensus::common=trace,parachain=debug,sync=debug
but you can override those by setting the RUST_LOG_RC
env, since the script will inject that env into the spawning logic.
And the parachain collators with this log levels:
aura=debug,runtime=debug,cumulus-consensus=trace,consensus::common=trace,parachain::collation-generation=trace,parachain::collator-protocol=trace,parachain=debug,xcm=trace
but you can override those by setting the RUST_LOG_COL
env, since the script will inject that env into the spawning logic.
Zombie-bite create a json file including two maps (overrides
and injects
), these two are simple key/values json that zombie-bite pass to the doppelganger nodes to override/inject those keys in the block import process. Those nodes override
the key IFF the key exist in the state being imported and inject
the ones sets at the end of the import process, so will be present in the resulting state even if there wasen't there originally.
You can check the keys we override/inject by default (for both relaychain / parachain) and at the moment if you want to include other key (or customize one) yo need to modify this file and rebuild the tool. Note: a process to dynamically set the overrides/injects map is planned.
Zombie-bite reads a few env vars to allow users to customize th behavior:
- ZOMBIE_BITE_BASE_PATH: base_path to use.
- RUST_LOG_RC: log level to set in the relaychain nodes.
- RUST_LOG_COL: log level to set in the collator.
- ZOMBIE_BITE_RC_PORT: port to use for
alice
. (deprecated) - ZOMBIE_BITE_ALICE_PORT: port to use for
alice
. - ZOMBIE_BITE_BOB_PORT: port to use for
bob
. - ZOMBIE_BITE_AH_PORT: port to use for the collator.
- ZOMBIE_SUDO: sudo key to set in sudo pallet (IFF present) and in RC manager.