mirror of
https://github.com/logos-blockchain/logos-blockchain-module.git
synced 2026-08-09 15:53:14 +00:00
210 lines
9.1 KiB
YAML
210 lines
9.1 KiB
YAML
|
|
name: "Generating and Inspecting a Logos Blockchain Node Config"
|
||
|
|
output: blockchain-module-config.md
|
||
|
|
release: ""
|
||
|
|
|
||
|
|
intro: |
|
||
|
|
`blockchain_module` wraps the [`logos-blockchain`](https://github.com/logos-blockchain/logos-blockchain)
|
||
|
|
node as a Logos module. Before a node can run it needs a **user config** — a YAML
|
||
|
|
file describing the keystore, the network ports, the bootstrap peers to sync
|
||
|
|
from, and where the node keeps its state, database and logs.
|
||
|
|
|
||
|
|
The module generates that file for you through `generate_user_config`, so the
|
||
|
|
operator never has to hand-write YAML. This doc-test drives that call through
|
||
|
|
the headless `logoscore` daemon and inspects what comes out, then shows what
|
||
|
|
happens when you try to generate a second config into the same instance.
|
||
|
|
|
||
|
|
> No node is started here — config generation is entirely local and needs no
|
||
|
|
> network. For starting and stopping a node see the companion
|
||
|
|
> [`blockchain-module-runtime`](./blockchain-module-runtime.md) doc-test.
|
||
|
|
|
||
|
|
what_you_build: "A generated `user_config.yaml` for a Logos blockchain node, produced through the module's `generate_user_config` call and inspected for the values that were asked for."
|
||
|
|
|
||
|
|
what_you_learn:
|
||
|
|
- How a Logos module is packaged as `.lgx` and installed with `lgpm`
|
||
|
|
- How to call a module's methods headlessly through the `logoscore` daemon
|
||
|
|
- What `generate_user_config` writes, and which knobs it accepts
|
||
|
|
- Why a second generation into the same instance is refused, and what to use instead
|
||
|
|
- Why the generated config's paths land under the module's own per-instance directory
|
||
|
|
|
||
|
|
prerequisites:
|
||
|
|
- |
|
||
|
|
**Nix** with flakes enabled (see [nixos.org](https://nixos.org/download.html)).
|
||
|
|
- "**A Linux or macOS machine.** Nothing here needs a display or a network peer."
|
||
|
|
|
||
|
|
sections:
|
||
|
|
- title: "Build the Logos daemon"
|
||
|
|
step: true
|
||
|
|
text: |
|
||
|
|
Build the Logos runtime CLI from its published flake. The result outputs a
|
||
|
|
binary named `logoscore` under a symlinked directory named `./logos`.
|
||
|
|
`logoscore` is the headless frontend for
|
||
|
|
[`logos-liblogos`](https://github.com/logos-co/logos-liblogos) — it brings in
|
||
|
|
the whole module-runtime stack we need to load and call the module.
|
||
|
|
steps:
|
||
|
|
- title: "Build the CLI"
|
||
|
|
run: "nix build 'github:logos-co/logos-logoscore-cli' --out-link ./logos"
|
||
|
|
code_block: |
|
||
|
|
nix build 'github:logos-co/logos-logoscore-cli' --out-link ./logos
|
||
|
|
check_file: "logos/bin/logoscore"
|
||
|
|
post_text: |
|
||
|
|
The build produces `logos/bin/logoscore` plus bundled runtime libraries
|
||
|
|
and a `logos/modules/` directory containing the built-in
|
||
|
|
`capability_module` (required for the auth handshake when loading
|
||
|
|
modules).
|
||
|
|
|
||
|
|
- title: "Build the lgpm package manager"
|
||
|
|
step: true
|
||
|
|
text: |
|
||
|
|
`lgpm` installs `.lgx` packages into a modules directory so the daemon can
|
||
|
|
discover them.
|
||
|
|
steps:
|
||
|
|
- title: "Build lgpm"
|
||
|
|
run: "nix build 'github:logos-co/logos-package-manager' --out-link ./lgpm"
|
||
|
|
code_block: |
|
||
|
|
nix build 'github:logos-co/logos-package-manager' --out-link ./lgpm
|
||
|
|
check_file: "lgpm/bin/lgpm"
|
||
|
|
|
||
|
|
- title: "Build and install the blockchain module"
|
||
|
|
step: true
|
||
|
|
text: |
|
||
|
|
The module's flake exposes an `.lgx` package — the Logos distribution format.
|
||
|
|
Building it compiles the Qt plugin *and* the bundled `logos_blockchain`
|
||
|
|
native library it links against, so this step is the slow one.
|
||
|
|
steps:
|
||
|
|
- title: "Build the .lgx package"
|
||
|
|
run: "nix build 'github:logos-blockchain/logos-blockchain-module{release}#lgx' --out-link ./blockchain-lgx"
|
||
|
|
code_block: |
|
||
|
|
nix build 'github:logos-blockchain/logos-blockchain-module{release}#lgx' --out-link ./blockchain-lgx
|
||
|
|
|
||
|
|
- title: "Install it into a modules directory"
|
||
|
|
text: "Install the package so the daemon can find it:"
|
||
|
|
run: "./lgpm/bin/lgpm --modules-dir ./modules install --dir ./blockchain-lgx"
|
||
|
|
code_block: |
|
||
|
|
lgpm --modules-dir ./modules install --dir ./blockchain-lgx
|
||
|
|
expect_contains:
|
||
|
|
- "blockchain_module"
|
||
|
|
check_file: "modules/blockchain_module/manifest.json"
|
||
|
|
|
||
|
|
- title: "Load the module in the daemon"
|
||
|
|
step: true
|
||
|
|
text: |
|
||
|
|
Start the daemon pointed at the modules directory, then load
|
||
|
|
`blockchain_module`. Loading only brings the plugin into the process — it
|
||
|
|
does **not** start a blockchain node.
|
||
|
|
steps:
|
||
|
|
- title: "Start the daemon"
|
||
|
|
run: "./logos/bin/logoscore stop >/dev/null 2>&1; sleep 2; ./logos/bin/logoscore daemon --modules-dir ./modules --persistence-path ./data >/dev/null 2>&1 &"
|
||
|
|
code_block: |
|
||
|
|
logoscore daemon --modules-dir ./modules --persistence-path ./data
|
||
|
|
|
||
|
|
- title: "Load the module"
|
||
|
|
run: "sleep 8; ./logos/bin/logoscore load-module blockchain_module"
|
||
|
|
code_block: |
|
||
|
|
logoscore load-module blockchain_module
|
||
|
|
expect_contains:
|
||
|
|
- "blockchain_module"
|
||
|
|
|
||
|
|
- title: "Inspect the methods it exposes"
|
||
|
|
text: |
|
||
|
|
`module-info` lists the `Q_INVOKABLE` methods — the same names you can
|
||
|
|
`call`. Note `generate_user_config`, `start`, `stop`, and the
|
||
|
|
`wallet_*` family:
|
||
|
|
run: "./logos/bin/logoscore module-info blockchain_module"
|
||
|
|
code_block: |
|
||
|
|
logoscore module-info blockchain_module
|
||
|
|
expect_contains:
|
||
|
|
- "generate_user_config"
|
||
|
|
- "start"
|
||
|
|
- "stop"
|
||
|
|
|
||
|
|
- title: "Generate a config with bootstrap peers"
|
||
|
|
step: true
|
||
|
|
text: |
|
||
|
|
`generate_user_config` takes a JSON object of arguments. Every field is
|
||
|
|
optional — an empty object produces a working default config. Here we pass
|
||
|
|
the two that matter most for joining a network: the bootstrap peers to sync
|
||
|
|
from, and the ports to listen on.
|
||
|
|
|
||
|
|
`use_persistence_paths` routes the config — and the node's `state`, `db`
|
||
|
|
and `logs` directories — under the module's own per-instance directory,
|
||
|
|
which is always writable. That is the safe default.
|
||
|
|
steps:
|
||
|
|
- title: "Write the arguments"
|
||
|
|
file:
|
||
|
|
path: gen-args.json
|
||
|
|
content: |
|
||
|
|
{
|
||
|
|
"initial_peers": [
|
||
|
|
"/ip4/65.109.51.37/udp/3000/quic-v1/p2p/12D3KooWFrouXfmrR4nsLMtE7wu15DoMJ6VtoUtHinREZCvbWHar"
|
||
|
|
],
|
||
|
|
"net_port": 3000,
|
||
|
|
"blend_port": 3001,
|
||
|
|
"output": "user_config.yaml",
|
||
|
|
"use_persistence_paths": true
|
||
|
|
}
|
||
|
|
|
||
|
|
- title: "Generate the config"
|
||
|
|
run: "./logos/bin/logoscore call blockchain_module generate_user_config @gen-args.json"
|
||
|
|
code_block: |
|
||
|
|
logoscore call blockchain_module generate_user_config @gen-args.json
|
||
|
|
expect_contains:
|
||
|
|
- '"success":true'
|
||
|
|
- "user_config.yaml"
|
||
|
|
post_text: |
|
||
|
|
The call returns the absolute path of the file it wrote — that path is
|
||
|
|
what you hand to `start`, as the runtime doc-test does.
|
||
|
|
|
||
|
|
`output` is worth passing even though it is optional. Omit it and the
|
||
|
|
call still reports success but returns an **empty** path, leaving you
|
||
|
|
nothing to start the node with.
|
||
|
|
|
||
|
|
- title: "Generating a second config into the same instance"
|
||
|
|
step: true
|
||
|
|
text: |
|
||
|
|
A natural next move is to generate a *second* config — say a peerless one
|
||
|
|
with `skip_ibd: true` — alongside the first. That does **not** work, and the
|
||
|
|
error is worth seeing because it is the same one operators hit when they
|
||
|
|
re-run generation over an existing setup.
|
||
|
|
|
||
|
|
The keystore is created once per instance directory. A second
|
||
|
|
`generate_user_config` against the same instance refuses rather than
|
||
|
|
overwriting it:
|
||
|
|
steps:
|
||
|
|
- title: "Write the arguments"
|
||
|
|
file:
|
||
|
|
path: gen-args-solo.json
|
||
|
|
content: |
|
||
|
|
{
|
||
|
|
"skip_ibd": true,
|
||
|
|
"net_port": 3100,
|
||
|
|
"blend_port": 3101,
|
||
|
|
"output": "solo-user-config.yaml",
|
||
|
|
"use_persistence_paths": true
|
||
|
|
}
|
||
|
|
|
||
|
|
- title: "Try to generate a second config"
|
||
|
|
run: "./logos/bin/logoscore call blockchain_module generate_user_config @gen-args-solo.json"
|
||
|
|
code_block: |
|
||
|
|
logoscore call blockchain_module generate_user_config @gen-args-solo.json
|
||
|
|
expect_contains:
|
||
|
|
- "Keystore file exists. Use `update` command."
|
||
|
|
post_text: |
|
||
|
|
Refusing is the right behaviour — silently regenerating a keystore would
|
||
|
|
discard the keys the previous config's node identity depends on. To
|
||
|
|
change an existing setup use `update_user_config`; to get a genuinely
|
||
|
|
separate configuration, use a separate instance directory.
|
||
|
|
|
||
|
|
This is also why `skip_ibd` is demonstrated in the companion
|
||
|
|
[`blockchain-module-runtime`](./blockchain-module-runtime.md) doc-test
|
||
|
|
rather than here: that spec generates exactly one config, with
|
||
|
|
`skip_ibd: true`, and then starts a node from it.
|
||
|
|
|
||
|
|
- title: "Shut down"
|
||
|
|
step: true
|
||
|
|
text: "Stop the daemon. No node was ever started, so there is nothing else to clean up."
|
||
|
|
steps:
|
||
|
|
- title: "Stop the daemon"
|
||
|
|
run: "./logos/bin/logoscore stop"
|
||
|
|
code_block: |
|
||
|
|
logoscore stop
|