Our synthetic local chain funds a validator using one denomination while its staking module expects another. Both strings look plausible and the account has a positive balance. The validator setup still fails because the staking transaction asks to bond an asset that its account does not hold under the required denomination.

We build an independent genesis preflight using symbolic denomination names and integer balances. It does not start a node or contain a network configuration. The fixture checks consistency between the intended bond asset and the validator funding before a container attempts to initialize the chain.

A coin amount includes its denomination

In a Cosmos SDK chain the amount and denomination form a coin quantity. A large numeric balance in the wrong denomination does not fund a staking operation. A display symbol in an interface is another representation and should not be substituted for the base denomination used by module state.

Our fixture records the module's bond denomination and the denomination used in the validator genesis transaction. It then looks up the validator's balance for that exact key. These checks establish consistency and sufficient synthetic funding without relying on a successful container process exit as evidence.

function preflight(profile) {
  if (profile.validatorDenom !== profile.bondDenom)
    throw new Error("denomination");
  const funded = profile.balances[profile.bondDenom] ?? 0n;
  if (funded < profile.bondAmount) throw new Error("funding");
  return true;
}
function ready(expectedChain, previousHeight, status) {
  return status.chain === expectedChain && status.height > previousHeight;
}

We deliberately avoid a default denomination in the preflight. A default that happens to work for a generic SDK example can be wrong for the intended chain. An absent required value should fail before initialization instead of silently creating a local environment that exercises different staking semantics.

Pin the node before generating its state

The binary version determines which genesis schema and module behavior the local environment runs. Reusing a data directory generated by another version can make a reproducible image behave unpredictably. A clean initialization procedure needs an explicit policy for retained state and incompatible version changes.

An image tag helps identify a release while a digest identifies specific image content. The local chain specification also needs the genesis inputs and launch arguments. Pinning the image alone does not establish the state that integration tests actually observe.

We validate the denomination before creating the validator transaction because a funded account and a running container are separate observations and neither observation establishes that the staking module can accept the intended bond quantity or that the resulting node will participate in the chain state expected by the integration suite.

If the environment follows an upstream release automatically then it needs a recorded resolved version for each test run. Otherwise a green run and a later failure can use different binaries while appearing to share the same local configuration.

Readiness means observing the chain

A running process is not yet a usable blockchain. The RPC endpoint should report the expected chain identifier and produce successive blocks. A stored contract test needs an additional readiness condition that the account and required modules can complete their intended transactions.

Our fixture separates a preflight check from a tiny readiness predicate. The predicate requires a matching chain identifier and a block height that has increased since the previous observation. This is a diagnostic gate and does not establish consensus correctness or long term network health.

Bond denomination and funding checked before block readiness
7 assertions passed

The tests reject a mismatched denomination and insufficient funding independently. They also reject an endpoint reporting the wrong chain and a node whose block height has stopped advancing. The accepted fixture supplies separate evidence for each declared readiness condition.

Recovery starts from the state boundary

When initialization fails we preserve the diagnostic output needed to identify the failed phase and then recreate only the disposable local state under the documented procedure. Repeatedly rerunning initialization against a partially populated directory can create a second failure that hides the original mismatch.

A development chain should use dedicated synthetic accounts and isolated volumes. Test credentials do not belong in a shared environment or a published article. The runnable example has no keys at all because it tests configuration consistency without requiring account signing.

The preflight becomes an integration check when the selected binary starts from an empty disposable volume and produces two new blocks before receiving a minimal transaction. Keep the resolved binary version and genesis checksum beside that result so another test run can reconstruct the environment.

Sources and examples