Test with the Simulator
Overview
After deploying a Block Node using either manual Kubernetes configuration or Solo Provisioner, you must verify that the node is functioning correctly by testing its ability to receive and process streamed blocks.
This guide walks you through testing your Block Node deployment using a simulator Docker container that publishes test blocks to the node.
The testing process uses a Docker Compose file to create a simulator publisher container. This container streams blocks to your deployed Block Node, verifying connectivity and block processing functionality.
For production-scale load testing using real Consensus Nodes and the Network Load Generator, see Load Testing a Deployed Block Node Using Solo and NLG.
Prerequisites
Before you begin, ensure you have:
A running Block Node deployment on your system using one of the following methods:
Docker and Docker Compose installed and available on your machine where you will run the simulator.
The gRPC service address and port for your Block Node:
For Local deployment:
localhost:40840For cloud deployment server address:
kubectl get svc -n block-node
A gRPC client tool for verification (optional but recommended):
Postman (with gRPC support), or
grpcurl command-line tool
Step 1: Create the Simulator Docker Compose File
Create docker-compose-publisher.yaml in the directory where you plan to run the test, with the following content:
Two placeholders need real values:
<BLOCK_NODE_HOST>— the Block Node address. See Choose the Block Node address.<BLOCK_NODE_VERSION_TAG>— the simulator image tag matching your Block Node version. See Pick a simulator image tag.
The remaining values typically don't need changing for an initial test:
BLOCK_STREAM_SIMULATOR_MODE=PUBLISHER_CLIENTmakes the simulator act as a publisher and stream blocks into the Block Node.GRPC_PORT=40840is the Block Node's default gRPC port. If your deployment uses a non-default port (seeserver.portin configuration.md), set it here.GENERATOR_START_BLOCK_NUMBERandGENERATOR_END_BLOCK_NUMBERdefine the inclusive block-number range the simulator generates (here, blocks 0 through 100).
Choose the Block Node address
The <BLOCK_NODE_HOST> value depends on where the simulator runs:
From the same VM as the Block Node (the simulator runs in Docker on the same host as the cluster): use the Kubernetes service IP from
kubectl get svc -n block-node(theCLUSTER-IPorEXTERNAL-IPcolumn on theblock-nodeservice), or the VM's internal IP fromhostname -I.localhostdoes not work on a typical cloud VM, because the Block Node listens on the cluster service network, not the host loopback.host.docker.internalis also unreliable on cloud Linux — use the service or internal IP directly.From a different machine or network: use the VM's external IP. Cloud firewalls (including GCP's default) only open SSH, so you must add an inbound rule for the gRPC port before this works.
Pick a simulator image tag
The simulator image tag must match your running Block Node version. Read the version from the StatefulSet:
The StatefulSet name
block-node-block-node-serverand the namespaceblock-nodeassume the default Helm release nameblock-nodeused by both deployment guides. If you chose a different release name or namespace, substitute them here and in thekubectlcommands later in this guide.
This returns the full image reference, for example:
The portion after the final : (here, 0.35.0) is the simulator tag to use.
Simulator images are published to the package registry. Not every Block Node release has a matching simulator GA tag - some GA versions only ship -SNAPSHOT or -rc* tags. If a :X.Y.Z tag returns a not found error from Docker, use the closest available tag from the registry (commonly X.Y.Z-rc2 or X.Y.Z-SNAPSHOT).
Step 2: Run the Docker Compose File
From the directory containing docker-compose-publisher.yaml, run:
The simulator streams blocks to the Block Node and stops automatically when it reaches the GENERATOR_END_BLOCK_NUMBER you set. Step 3 explains what to look for in the output.
Step 3: Verify Block Streaming
Once the Docker Compose container is running, verify that blocks are being streamed and accepted.
Check simulator logs:
In the terminal where
docker compose upis running, you should see the simulator go through three phases:Startup: Docker Compose attaches to the simulator container, which prints its configuration (
PUBLISHER_CLIENTmode, block range, pacing) and begins streaming.Streaming: Each
acknowledgement { block_number: N }line confirms the Block Node received and accepted blockN.Summary: When the simulator finishes streaming the configured range, it prints the totals and exits.
Number of Blocks sentshould matchGENERATOR_END_BLOCK_NUMBER−GENERATOR_START_BLOCK_NUMBER+ 1; the1574and31shown are from an example run and will differ for yours.
Verify on the Block Node side:
Confirm the Block Node is processing the incoming blocks by tailing its logs and looking for verification-session entries:
Healthy output shows one
Created ExtendedMerkleTreeSession for block Nline per block received:About
Defaulted container ...messages: if you omit-c block-node-server,kubectlprints which container it picked (the pod has multiple). It's informational; the command still runs correctly. Pass-c block-node-serverexplicitly to suppress it.
Step 4: Clean Up After Testing
The Docker Compose container stops automatically when it reaches the last block in the configured range. To stop early or reset the Block Node before another test:
If the simulator is still running, press Ctrl+C in the terminal where
docker compose upis running.Stop and remove the simulator publisher container:
(Optional) Reset the Block Node data, either to run a new test from a clean state or to prepare the deployment to receive real block streams.
Caution: These commands permanently delete all current block data from the Block Node. Only run them in non-production environments, or when you explicitly intend to clear test data.
For single-node Kubernetes deployments, delete the live and historic data directories inside the Block Node pod, then restart the pod:
Replace
${NAMESPACE}and${POD}with values from your deployment:${NAMESPACE}is the Kubernetes namespace (for example,block-node), and${POD}is the Block Node pod name fromkubectl get pods -n ${NAMESPACE}(for example,block-node-0).For Docker-based Block Node deployments, run the equivalent inside the Block Node container:
After the pod or container restarts, the Block Node comes up with empty live and historic data directories, ready for a fresh simulator run or to begin consuming real block streams.
Last updated