How It Works

This document covers the two core aspects of what ZombieNet does under the hood: chain spec customization and command-line argument generation.

Chain Spec Customization

When spawning a network, ZombieNet modifies chain specifications to configure the test environment. These customizations happen automatically based on your network configuration.

Relay Chain Customizations

The framework applies these modifications to relay chain specs:

CustomizationDescription
Runtime Genesis PatchMerges user-provided genesis_overrides JSON (applied first)
Clear AuthoritiesRemoves existing authorities from session/keys, aura/authorities, grandpa/authorities, collatorSelection/invulnerables, and staking/invulnerables + staking/stakers (relay only). Also sets validatorCount to 0 unless devStakers is configured.
Add BalancesAdds balances for each node's sr and sr_stash accounts. Balance is max(initial_balance, staking_min * 2). Only nodes with initial_balance > 0 receive balances.
Add Zombie AccountAdds //Zombie account with 1000 units (in chain denomination, i.e., 1000 * 10^token_decimals planck) for internal operations
Add StakingConfigures staking for validators with minimum stake
Add Session AuthoritiesAdds validators as session authorities (if session pallet exists)
Add Aura/Grandpa AuthoritiesFor chains without session pallet
Add HRMP ChannelsConfigures cross-chain messaging channels
Register ParachainsAdds InGenesis parachains to genesis

Parachain Customizations

For cumulus-based parachains:

CustomizationDescription
Override para_id/paraIdSets correct parachain ID in chain spec root (both para_id and paraId variants)
Override relay_chainSets relay chain ID in chain spec root
Apply Genesis OverridesMerges user-provided JSON overrides
Clear/Add AuthoritiesClears existing authorities from session/keys, aura/authorities, grandpa/authorities, collatorSelection/invulnerables. Then adds collator session keys (if session pallet exists) or aura authorities.
Add Collator SelectionAdds invulnerable collators to collatorSelection/invulnerables
Override parachainInfoSets correct parachainId in /parachainInfo/parachainId
Add BalancesExtracts accounts from assets pallet metadata and ensures they have native token balances. Adds balances for collator sr accounts.

For EVM-based parachains (is_evm_based = true), Ethereum session keys are generated and used instead of standard keys.

Chain Spec Key Types

ZombieNet supports customizing session key types and their cryptographic schemes via the chain_spec_key_types configuration option.

Cryptographic Schemes

SchemeSuffixDescription
SR25519_srSchnorr signatures, used by most runtime keys
ED25519_edEdwards curve signatures, used by grandpa
ECDSA_ecElliptic curve, used by beefy and Ethereum compatibility

Predefined Key Types

These key types have predefined default schemes:

Key TypeDefault SchemeNotes
auraSR25519ED25519 on asset-hub-polkadot
babeSR25519
grandpaED25519
beefyECDSA
im_onlineSR25519
authority_discoverySR25519
para_validatorSR25519
para_assignmentSR25519
parachain_validatorSR25519
nimbusSR25519
vrfSR25519

Syntax

Two formats are supported:

  • Short form: aura — uses the predefined default scheme
  • Long form: aura_ed — explicitly specifies the scheme

Unknown key types default to SR25519 when using short form.

Example

[relaychain]
chain_spec_key_types = ["aura", "grandpa", "beefy"]  # Uses defaults

# Or with explicit schemes:
chain_spec_key_types = ["aura_ed", "grandpa_sr", "custom_key_ec"]

Optional Overrides

Two additional overrides can be applied after the raw chain spec is generated:

  • WASM Override (wasm_override): Replaces runtime code (:code storage key) with custom WASM
  • Raw Spec Override (raw_spec_override): Applies JSON patch merge to override any part of the raw spec

Command-Line Arguments

ZombieNet generates command-line arguments for each spawned node. Understanding what gets added helps debug issues and customize node behavior.

Framework-Managed Arguments

These arguments are always set by the framework and filtered out if provided by user configuration:

ArgumentValue
--chainGenerated chain spec path
--nameNode name from config
--rpc-corsall
--rpc-methodsunsafe
--parachain-idParachain ID (relay chain nodes only, when para_id is specified; NOT used for cumulus collators)
--node-keyDeterministic key derived from node name

Additionally, these flags are managed by the framework:

FlagWhen Added
--no-telemetryRelay chain nodes only (not cumulus collators)
--collatorCumulus collators with is_validator: true
--execution wasmEmbedded relay chain full node (after -- separator)

Arguments Added Conditionally

ArgumentCondition
--validatorRelay chain nodes with is_validator: true
--insecure-validator-i-know-what-i-doValidators, if the binary supports it
--prometheus-externalUnless already in user args
--unsafe-rpc-externalOnly for Docker/Kubernetes providers (not native)
--bootnodesWhen bootnode addresses are available

Port Arguments

The framework injects port arguments based on assigned ports:

ArgumentDescription
--prometheus-portPrometheus metrics port
--rpc-portRPC/WebSocket port
--listen-addrP2P listen address (format: /ip4/0.0.0.0/tcp/{port}/ws)
--base-pathData directory path

Cumulus Collator Arguments

Cumulus-based collators receive two sets of arguments separated by --:

Before -- (collator arguments):

  • --chain (parachain spec)
  • --collator
  • --prometheus-port, --rpc-port, --listen-addr
  • --base-path
  • User-provided collator args

After -- (embedded relay chain full node):

  • --base-path (separate relay data directory)
  • --chain (relay chain spec)
  • --execution wasm (hardcoded, always WASM execution)
  • --port (full node P2P port, injected by framework when assigned port differs from default 30333)
  • --prometheus-port (full node metrics port, injected by framework when assigned port differs from default 9616)
  • User-provided full node args

Removing Framework Arguments

Use the -: prefix to remove arguments that the framework adds:

[[relaychain.nodes]]
name = "bob"
args = ["-:--insecure-validator-i-know-what-i-do"]

This removes --insecure-validator-i-know-what-i-do from bob's command line.

The removal syntax:

  • -:--flag-name removes --flag-name
  • -:flag-name also removes --flag-name (normalized automatically)
  • Works for both flags and options (the option's value is also removed)

Example: Generated Relay Chain Command

polkadot \
  --chain /cfg/rococo-local.json \
  --name alice \
  --rpc-cors all \
  --rpc-methods unsafe \
  --unsafe-rpc-external \          # omitted for native provider
  --node-key <deterministic_key> \
  --prometheus-external \
  --validator \
  --insecure-validator-i-know-what-i-do \  # if binary supports it
  --bootnodes <bootnode_multiaddrs> \
  --prometheus-port 9615 \
  --rpc-port 9944 \
  --listen-addr /ip4/0.0.0.0/tcp/30333/ws \
  --base-path /data \
  --no-telemetry \
  [user_args...]

Example: Generated Cumulus Collator Command

polkadot-parachain \
  --chain /cfg/1000.json \
  --name collator01 \
  --rpc-cors all \
  --rpc-methods unsafe \
  --unsafe-rpc-external \          # omitted for native provider
  --node-key <deterministic_key> \
  --prometheus-external \
  --collator \                     # if is_validator: true
  --bootnodes <para_bootnode_multiaddrs> \
  --prometheus-port 9615 \
  --rpc-port 9944 \
  --listen-addr /ip4/0.0.0.0/tcp/30333/ws \
  --base-path /data \
  [user_collator_args...] \
  -- \
  --base-path /relay-data \
  --chain /cfg/rococo-local.json \
  --execution wasm \
  --port 30334 \                   # if assigned port differs from default
  --prometheus-port 9616 \         # if assigned port differs from default
  [user_full_node_args...]