Skip to content

Commit

Permalink
workbench: generalise topology generation somewhat
Browse files Browse the repository at this point in the history
We are trying to admit more kinds of cluster nodes
  • Loading branch information
deepfire committed Nov 30, 2021
1 parent dc992c4 commit 75d1429
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 53 deletions.
7 changes: 3 additions & 4 deletions nix/supervisord-cluster/default.nix
Expand Up @@ -28,10 +28,9 @@ let
topologyForNode =
{ profile, nodeSpec }:
let inherit (nodeSpec) name i; in
workbench.runWorkbench "topology-${name}.json"
(if nodeSpec.isProducer
then "topology for-local-node ${toString i} ${profile.topology.files} ${toString basePort}"
else "topology for-local-observer ${profile.name} ${profile.topology.files} ${toString basePort}");
workbench.runWorkbench
"topology-${name}.json"
"topology projection-for local-${nodeSpec.kind} ${toString i} ${profile.name} ${profile.topology.files} ${toString basePort}";

nodePublicIP =
{ i, name, ... }@nodeSpec:
Expand Down
2 changes: 2 additions & 0 deletions nix/workbench/profile.sh
Expand Up @@ -91,6 +91,8 @@ case "${op}" in
"$profile_json"
--slurpfile env "$env_json"
)
## WARNING: this is structured in correspondence
## with the output generated by cardano-topology
jq '. as $prof
| $prof.composition.n_bft_hosts as $n_bfts
| $prof.composition.n_pool_hosts as $n_pools
Expand Down
10 changes: 6 additions & 4 deletions nix/workbench/profiles/derived.jq
Expand Up @@ -78,7 +78,8 @@ def add_derived_params:
, genesis:
{ genesis_future_offset: $future_offset
, delegators: ($gsis.delegators // $n_pools)
, pool_coin: ($gsis.pools_balance / $n_pools | floor)
, pool_coin: (if $n_pools == 0 then 0
else $gsis.pools_balance / $n_pools | floor end)
, verbatim:
## TODO: duplication
{ protocolParams:
Expand Down Expand Up @@ -109,9 +110,10 @@ def add_derived_params:
## Second derivation:
{ common:
{ genesis:
{ delegator_coin: ($gsis.pools_balance /
.common.genesis.delegators
| floor)
{ delegator_coin: (if .common.genesis.delegators == 0 then 0
else $gsis.pools_balance / .common.genesis.delegators
| floor
end)
}
}
}) as $derived
Expand Down
109 changes: 64 additions & 45 deletions nix/workbench/topology.sh
@@ -1,23 +1,40 @@
usage_topology() {
usage "topology" "Topology generation" <<EOF
The workbench generates topologies with the following properties:
- all node names are of the form "node-N", where N is a 0-based natural
- the BFT producer, is always present and is node-0; inactived by d=0
- a non-dense, regular pool producer is always present, and is always node-1
- further nodes are dense pools (so potentially configurable to densities >1)
- there is an optional observer as the last node
For the producer section of the topology:
- the topology is distributed across M regions,
and is an M-circle toroidal mesh, one circle per distinct region
- each node has two connections (upstreams) to immediate in-circle neighbors,
and also two connections to nodes 1/3 circle length away,
clockwise and counter-clockwise
- each node has an additional connection to a neighbor in another circle
- as the total topology node count decreases, the topology gracefully degrades
to simpler fully-connected graphs, such as two mutually connected nodes,
and then to a single lone node
Whenever an observer node is present, it is connected to all producers.
Subcommands:
make PROFILE-JSON OUTDIR
Generate the full cluster topology, including:
- the Nixops/'cardano-ops' style topology
- the .dot and .pdf rendering
topology density-map PROFILE-JSON TOPO-DIR
density-map PROFILE-JSON TOPO-DIR
Generate the profile-induced map of node names
to pool density: 0, 1 or N (for dense pools)
for-local-node N TOPO-DIR BASE-PORT
projection-for ROLE N PROFILE TOPO-DIR BASE-PORT
Given TOPO-DIR, containing the full cluster topology,
print topology for the N-th node,
print topology for the N-th node, given its ROLE,
while assigning it a local port number BASE-PORT+N
for-local-observer PROFILE TOPO-DIR BASE-PORT
Given the profile and the full cluster topology,
print topology for the observer node,
while assigning it a local port number BASE-PORT+NODE-COUNT
EOF
}

Expand Down Expand Up @@ -94,46 +111,46 @@ case "${op}" in
| from_entries
' "${args[@]}";;

for-local-node )
local usage="USAGE: wb topology for-local-node N TOPO-DIR BASE-PORT"
local i=${1:?$usage}
local topo_dir=${2:?$usage}
local basePort=${3:?$usage}

args=(--slurpfile topology "$topo_dir"/topology-nixops.json
--argjson basePort $basePort
--argjson i $i
--null-input
)
jq 'def loopback_node_topology_from_nixops_topology($topo; $i):
$topo.coreNodes[$i].producers as $producers
| ($producers | map(ltrimstr("node-") | fromjson)) as $prod_indices
| { Producers:
( $prod_indices
| map
({ addr: "127.0.0.1"
, port: ($basePort + .)
, valency: 1
}
))
};
loopback_node_topology_from_nixops_topology($topology[0]; $i)
' "${args[@]}";;

for-local-observer )
local usage="USAGE: wb topology for-local-observer PROFILE TOPO-DIR BASE-PORT"
local profile=${1:?$usage}
local topo_dir=${2:?$usage}
local basePort=${3:?$usage}
projection-for )
local usage="USAGE: wb topology $op ROLE N PROFILE TOPO-DIR BASE-PORT"
local role=${1:?$usage}
local i=${2:?$usage}
local profile=${3:?$usage}
local topo_dir=${4:?$usage}
local basePort=${5:?$usage}

local prof=$(profile get $profile)

args=(--slurpfile topology "$topo_dir"/topology-nixops.json
--argjson basePort $basePort
--null-input
)
jq 'def loopback_observer_topology_from_nixops_topology($topo):
case "$role" in
local-bft | local-pool )
args=(--slurpfile topology "$topo_dir"/topology-nixops.json
--argjson basePort $basePort
--argjson i $i
--null-input
)
jq '
def loopback_node_topology_from_nixops_topology($topo; $i):
$topo.coreNodes[$i].producers as $producers
| ($producers | map(ltrimstr("node-") | fromjson)) as $prod_indices
| { Producers:
( $prod_indices
| map
({ addr: "127.0.0.1"
, port: ($basePort + .)
, valency: 1
}
))
};
loopback_node_topology_from_nixops_topology($topology[0]; $i)
' "${args[@]}";;
local-observer )
args=(--slurpfile topology "$topo_dir"/topology-nixops.json
--argjson basePort $basePort
--null-input
)
jq '
def loopback_observer_topology_from_nixops_topology($topo):
[range(0; $topo.coreNodes | length)] as $prod_indices
| { Producers:
( $prod_indices
Expand All @@ -147,6 +164,8 @@ case "${op}" in
loopback_observer_topology_from_nixops_topology($topology[0])
' "${args[@]}";;
* ) fail "unhandled role for topology node '$i': '$role'";;
esac;;

* ) usage_topology;; esac
}

0 comments on commit 75d1429

Please sign in to comment.