Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*/
@ConfigData("server.http2")
public record WebServerHttp2Config(
@Loggable @ConfigProperty(defaultValue = "250") int flowControlTimeout,
@Loggable @ConfigProperty(defaultValue = "1000") int flowControlTimeout,
@Loggable @ConfigProperty(defaultValue = "8_388_608") int initialWindowSize,
@Loggable @ConfigProperty(defaultValue = "8") long maxConcurrentStreams,
@Loggable @ConfigProperty(defaultValue = "10") int maxEmptyFrames,
Expand Down
1 change: 1 addition & 0 deletions tools-and-tests/network-topology-generator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
out/
99 changes: 99 additions & 0 deletions tools-and-tests/network-topology-generator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
## Network Topology Generator

Check notice on line 1 in tools-and-tests/network-topology-generator/README.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

tools-and-tests/network-topology-generator/README.md#L1

First line in a file should be a top-level heading

This tool defines a shared network-topology format and utilities for validating
and materialising test configurations. It currently includes:
- `network-topology.schema.yaml` — the canonical schema shared across teams.
- `examples/` — sample topologies that cover simple and larger network shapes.
- `scripts/generate-configs.sh` — helper that renders node-specific configs from a topology file.

This schema and tooling objective is to:
- Provide a common format for defining network topologies across teams.
- Enable easy validation of topologies against a shared schema.
- Simplify generation of per-node configuration files for test deployments.
- Facilitate sharing and reuse of network topologies in tests.

### Prerequisites

- `yq` (YAML processor) and `jq` (JSON processor) used by the generator script.
- A JSON/YAML Schema validator (for example `check-jsonschema`) to lint topologies against the schema.

On macOS you can install the CLI dependencies with Homebrew:

```bash
brew install jq
brew install yq

# schema validator
brew install check-jsonschema
```

### Validate a topology

Lint any topology file against the shared schema before committing it:

```bash
check-jsonschema --schemafile network-topology.schema.yaml examples/*.yaml
```

### Generate per-node configs

Use the helper script to materialise config bundles for each block node (BN) and consensus node (CN):

Check notice on line 40 in tools-and-tests/network-topology-generator/README.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

tools-and-tests/network-topology-generator/README.md#L40

Expected: Consensus Node; Actual: consensus node

Simple example:

```bash
scripts/generate-configs.sh examples/simple-1-1.yaml
```

Large example:

```bash
scripts/generate-configs.sh examples/7CNs-4BNs-large.yaml
```

Larger example:

```bash
scripts/generate-configs.sh examples/7CNs-2BNs-each.yaml
```

Shared priorities example:

```bash
scripts/generate-configs.sh examples/4CNs-4BNs-shared-priority.yaml
```

YAML supports connection-local priorities in two syntaxes. Both of the following
produce peers with priority `1` when generating the BN configs:

```yaml
peers:
- bn2: 1 # shorthand single-key map (preferred for quick edits)
- node: bn3 # explicit object form for richer tooling support
priority: 1
```

`consensus_nodes.*.block_nodes` accepts the same forms, so you can reuse priorities
when mapping consensus nodes to block nodes. See
`examples/4CNs-4BNs-shared-priority.yaml` for a complete topology showcasing
shared priorities across multiple links.

The script writes JSON configs under `out/<node>/config.json`. Example output for the `cn1`
node in the `simple-1-1` topology:

```json
{
"nodes": [
{
"address": "localhost",
"port": 40800,
"priority": 1
}
]
}
```

Priorities are resolved in the following order when rendering configs:
1. Connection-level override (from the peer/block list entry)
2. The referenced block node's `priority` property

Check notice on line 98 in tools-and-tests/network-topology-generator/README.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

tools-and-tests/network-topology-generator/README.md#L98

Expected: Block Node; Actual: block node
3. Default incremental order within the list
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
block_nodes:
bn1:
address: bn1.shared.example.com
port: 40800
peers:
- bn2: 1
- bn3: 1

bn2:
address: bn2.shared.example.com
port: 40801
peers:
- bn1: 1
- bn4: 2

bn3:
address: bn3.shared.example.com
port: 40802
peers:
- bn1: 1
- bn4: 2

bn4:
address: bn4.shared.example.com
port: 40803
peers:
- bn2: 2
- bn3: 2

consensus_nodes:
cn1:
block_nodes:
- bn1: 1
- bn2: 1
cn2:
block_nodes:
- bn3: 2
- bn4: 2
cn3:
block_nodes:
- bn1: 1
- bn3: 2
cn4:
block_nodes:
- bn2: 1
- bn4: 2
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
block_nodes:
bn1a: { address: bn1a.example.com, port: 40800, peers: [bn1b] }
bn1b: { address: bn1b.example.com, port: 40801, peers: [bn1a] }

bn2a: { address: bn2a.example.com, port: 40802, peers: [bn2b] }
bn2b: { address: bn2b.example.com, port: 40803, peers: [bn2a] }

bn3a: { address: bn3a.example.com, port: 40804, peers: [bn3b] }
bn3b: { address: bn3b.example.com, port: 40805, peers: [bn3a] }

bn4a: { address: bn4a.example.com, port: 40806, peers: [bn4b] }
bn4b: { address: bn4b.example.com, port: 40807, peers: [bn4a] }

bn5a: { address: bn5a.example.com, port: 40808, peers: [bn5b] }
bn5b: { address: bn5b.example.com, port: 40809, peers: [bn5a] }

bn6a: { address: bn6a.example.com, port: 40810, peers: [bn6b] }
bn6b: { address: bn6b.example.com, port: 40811, peers: [bn6a] }

bn7a: { address: bn7a.example.com, port: 40812, peers: [bn7b] }
bn7b: { address: bn7b.example.com, port: 40813, peers: [bn7a] }

consensus_nodes:
cn1: { block_nodes: [bn1a, bn1b] }
cn2: { block_nodes: [bn2a, bn2b] }
cn3: { block_nodes: [bn3a, bn3b] }
cn4: { block_nodes: [bn4a, bn4b] }
cn5: { block_nodes: [bn5a, bn5b] }
cn6: { block_nodes: [bn6a, bn6b] }
cn7: { block_nodes: [bn7a, bn7b] }
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
block_nodes:
bn1: { address: bn1-host.example.com, port: 40800, peers: [bn2,bn3] }
bn2: { address: bn2-host.example.com, port: 40801, peers: [bn3,bn4] }

bn3: { address: bn3-host.example.com, port: 40802, peers: [bn2,bn1] }
bn4: { address: bn4-host.example.com, port: 40803, peers: [bn1,bn2,bn3] }

consensus_nodes:
cn1: { block_nodes: [bn1, bn2, bn3] }
cn2: { block_nodes: [bn2, bn3, bn4] }
cn3: { block_nodes: [bn3, bn4, bn1] }
cn4: { block_nodes: [bn2, bn3, bn4] }
cn5: { block_nodes: [bn3, bn4, bn1] }
cn6: { block_nodes: [bn4, bn1, bn2] }
cn7: { block_nodes: [bn1, bn2, bn3] }
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
block_nodes:
bn1:
address: localhost
port: 40800
peers: []

consensus_nodes:
cn1:
block_nodes: [bn1]
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
$schema: "https://json-schema.org/draft/2020-12/schema"
$title: "Network Topology Schema"
$type: object
$defs:
nodeRef:
type: string
description: "Reference to a node by its identifier"
nodeLink:
type: object
description: "Reference to a node with an optional connection priority override"
required: ["node"]
properties:
node:
$ref: "#/$defs/nodeRef"
priority:
type: integer
minimum: 1
additionalProperties: false
nodePriorityEntry:
type: object
description: "Single-key map associating a node with a priority"
minProperties: 1
maxProperties: 1
propertyNames:
pattern: "^[a-zA-Z0-9_-]+$"
additionalProperties:
type: integer
minimum: 1
address:
type: string
description: "Resolvable hostname or IP address of the node"
examples: ["localhost", "bn1.example.com"]
port:
type: integer
description: "TCP port the node listens on"
minimum: 1
maximum: 65535

properties:
block_nodes:
type: object
description: "All Block Nodes (BN) available in the network"
patternProperties:
"^[a-zA-Z0-9_-]+$":
type: object
required: ["address", "port"]
properties:
address:
$ref: "#/$defs/address"
port:
$ref: "#/$defs/port"
priority:
type: integer
description: "Optional connection priority"
minimum: 1
peers:
type: array
description: "List of other block-nodes this BN connects to"
items:
anyOf:
- $ref: "#/$defs/nodeRef"
- $ref: "#/$defs/nodeLink"
- $ref: "#/$defs/nodePriorityEntry"
uniqueItems: true
additionalProperties: false
additionalProperties: false

consensus_nodes:
type: object
description: "Consensus Nodes (CN) that connect to one or more Block Nodes"
patternProperties:
"^[a-zA-Z0-9_-]+$":
type: object
required: ["block_nodes"]
properties:
block_nodes:
type: array
description: "List of block-node identifiers this CN connects to"
items:
anyOf:
- $ref: "#/$defs/nodeRef"
- $ref: "#/$defs/nodeLink"
- $ref: "#/$defs/nodePriorityEntry"
minItems: 1
uniqueItems: true
additionalProperties: false
additionalProperties: false

required: ["block_nodes", "consensus_nodes"]
additionalProperties: false
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env bash
set -euo pipefail

TOPOLOGY_FILE=${1:-network-topology.yaml}
OUT_DIR="out"
mkdir -p "$OUT_DIR"

echo "📦 Generating configs from $TOPOLOGY_FILE ..."
command -v yq >/dev/null 2>&1 || { echo "❌ yq is required (https://github.com/mikefarah/yq)"; exit 1; }

REF_TRANSFORM='reduce .[]? as $ref ([]; . + (

Check warning on line 11 in tools-and-tests/network-topology-generator/scripts/generate-configs.sh

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

tools-and-tests/network-topology-generator/scripts/generate-configs.sh#L11

Expressions don't expand in single quotes, use double quotes for that.
if ($ref | type) == "string" then [{id:$ref, priority:null}]
elif ($ref | type) == "object" and (($ref | has("node")) or ($ref | has("id"))) then [{id: ($ref.node // $ref.id), priority: ($ref.priority // null)}]
elif ($ref | type) == "object" then [ $ref | to_entries[] | {id: .key, priority: (.value // null)} ]
else [] end
))
| .[]
| "\(.id)|\(.priority // "")"'

# 1️⃣ Generate BN configs
for bn in $(yq -r '.block_nodes | keys[]' "$TOPOLOGY_FILE"); do
bn_dir="$OUT_DIR/$bn"
mkdir -p "$bn_dir"

json="["
prio=1
while IFS='|' read -r peer_id peer_priority; do
[[ -z "$peer_id" ]] && continue
addr=$(yq -r ".block_nodes[\"$peer_id\"].address" "$TOPOLOGY_FILE")
port=$(yq -r ".block_nodes[\"$peer_id\"].port" "$TOPOLOGY_FILE")
if [[ -z "$peer_priority" ]]; then
peer_priority=$(yq -r ".block_nodes[\"$peer_id\"].priority // \"\"" "$TOPOLOGY_FILE")
fi
if [[ -z "$peer_priority" ]]; then
peer_priority=$prio
fi
json+="$(jq -nc --arg a "$addr" --argjson p "$port" --argjson pr "$peer_priority" '{address:$a,port:$p,priority:$pr}'),"
prio=$((prio+1))
done < <(yq -o=json '.block_nodes["'"$bn"'"].peers // []' "$TOPOLOGY_FILE" | jq -r "$REF_TRANSFORM")
json="${json%,}]"
[[ "$json" == "[" ]] && json="[]"

echo "{\"nodes\": $json}" | jq . > "$bn_dir/config.json"
echo "✅ Generated $bn_dir/config.json"
done

# 2️⃣ Generate CN configs
for cn in $(yq -r '.consensus_nodes | keys[]' "$TOPOLOGY_FILE"); do
cn_dir="$OUT_DIR/$cn"
mkdir -p "$cn_dir"

json="["
prio=1
while IFS='|' read -r bn_id bn_priority; do
[[ -z "$bn_id" ]] && continue
addr=$(yq -r ".block_nodes[\"$bn_id\"].address" "$TOPOLOGY_FILE")
port=$(yq -r ".block_nodes[\"$bn_id\"].port" "$TOPOLOGY_FILE")
if [[ -z "$bn_priority" ]]; then
bn_priority=$(yq -r ".block_nodes[\"$bn_id\"].priority // \"\"" "$TOPOLOGY_FILE")
fi
if [[ -z "$bn_priority" ]]; then
bn_priority=$prio
fi
json+="$(jq -nc --arg a "$addr" --argjson p "$port" --argjson pr "$bn_priority" '{address:$a,port:$p,priority:$pr}'),"
prio=$((prio+1))
done < <(yq -o=json '.consensus_nodes["'"$cn"'"].block_nodes // []' "$TOPOLOGY_FILE" | jq -r "$REF_TRANSFORM")
json="${json%,}]"
[[ "$json" == "[" ]] && json="[]"

echo "{\"nodes\": $json}" | jq . > "$cn_dir/config.json"
echo "✅ Generated $cn_dir/config.json"
done

echo "🎉 All configs generated under $OUT_DIR/"
Loading