Release set v0.2.1
The following package versions are pinned for release set v0.2.1.
Note: The release-set version identifies the testnet version. Individual package versions are pinned independently and do not need to match the release-set version.
Node operator guide
| Package | Version |
|---|---|
logos-blockchain-module | 0.2.1 |
logos-storage-module | 2.1.0 |
logos-delivery-module | 0.2.0 |
logos-logoscore-cli | 0.2.2 |
logos-package-manager | 0.2.1 |
logos-package-downloader | 0.2.1 |
Other release packages
| Package | Version |
|---|---|
lez-explorer-ui | 1.1.0 |
lez-indexer-module | 1.1.0 |
logos-execution-zone-module | 1.1.0 |
logos-execution-zone-wallet-ui | 1.1.0 |
logos-blockchain-ui | 0.2.1 |
logos-chat-module | 0.2.1 |
logos-chat-ui | 0.2.1 |
logos-storage-ui | 2.1.0 |
logos-basecamp | 0.2.3 |
Overview
Run one Logos node with one logoscore daemon and one shared modules directory.
This guide starts these modules:
| Module | Package | Public ports |
|---|---|---|
| Blockchain | blockchain_module | 3000/udp, configured Blend UDP port |
| Storage | storage_module | 8090/udp, 8091/tcp |
| Delivery | delivery_module | 9000/udp, 30303/tcp |
Commands assume a Linux host and these default paths:
/usr/local/bin/logoscore
/usr/local/bin/lgpd
/usr/local/bin/lgpm
/opt/logos-node/modules
/opt/logos-node/packages
/var/lib/logos-nodeReplace <public-ip> with the public IPv4 address of the node.
Run the module commands as the same OS user that owns /var/lib/logos-node.
Install Runtime Tools
Install curl, jq, and FUSE support for AppImage binaries.
apt-get update
apt-get install -y curl jq wget fuse3Download the Linux release assets from each repository’s Releases page:
| Tool | Repository |
|---|---|
logoscore | https://github.com/logos-co/logos-logoscore-cli |
lgpd | https://github.com/logos-co/logos-package-downloader |
lgpm | https://github.com/logos-co/logos-package-manager |
For x86_64 Linux, download the pinned testnet tool versions:
wget https://github.com/logos-co/logos-logoscore-cli/releases/download/0.2.2/logoscore-x86_64-linux.tar.gz
wget https://github.com/logos-co/logos-package-downloader/releases/download/0.2.1/lgpd-x86_64-linux.tar.gz
wget https://github.com/logos-co/logos-package-manager/releases/download/0.2.1/lgpm-x86_64-linux.tar.gzVerify the runtime-tool archives against the SHA-256 digests recorded for the pinned GitHub release assets:
sha256sum --check <<'EOF'
6f216f4b807520194dd0e4d1a3d69bd2bc83f38781a5e7b2c1abf66e40143b33 logoscore-x86_64-linux.tar.gz
2581f5bb6618623b9eb27b8bba37d39647b33c56d2f5bf15b41d0da286d45aee lgpd-x86_64-linux.tar.gz
41c897a6da6db0ecabe03c0098b9bd0652ea8cd2eaf091e2d646a65b71260780 lgpm-x86_64-linux.tar.gz
EOFInstall the tools under /usr/local/bin with the expected command names:
tar -xzf logoscore-x86_64-linux.tar.gz
install -m755 logoscore-x86_64.AppImage /usr/local/bin/logoscore
tar -xzf lgpd-x86_64-linux.tar.gz
install -m755 lgpd-x86_64.AppImage /usr/local/bin/lgpd
tar -xzf lgpm-x86_64-linux.tar.gz
install -m755 lgpm-x86_64.AppImage /usr/local/bin/lgpmVerify:
logoscore --version
lgpd --version
lgpm --versionPrepare The Host
Create the runtime user and directories:
useradd --system --home /var/lib/logos-node --create-home --shell /usr/sbin/nologin logos
mkdir -p /opt/logos-node/modules /opt/logos-node/packages
mkdir -p /var/lib/logos-node/blockchain-module-testnet
mkdir -p /var/lib/logos-node/storage-module
mkdir -p /var/lib/logos-node/delivery-module
chown -R logos:logos /var/lib/logos-nodeOpen these ports on the host firewall:
3000/udp
<YOUR_BLEND_PORT>/udp
8090/udp
8091/tcp
9000/udp
30303/tcp<YOUR_BLEND_PORT>/udp is required when joining Blend.
Obtain it from blend.core.backend.listening_address in the generated blockchain configuration.
Install Modules
lgpd download downloads the version published in the configured module catalog.
It does not automatically build or fetch the newest commit from the module repositories.
For a testnet, publish the intended module versions in the catalog before operators run these commands.
Download the module packages from the configured module catalog: The root hash selects the exact published package identity for the pinned version.
lgpd download blockchain_module --version 0.2.1 --root-hash c33c59d690b206476214e5fcacaee08bd56911ad855ae9c08919005b5f3b3c43 --output /opt/logos-node/packages
lgpd download storage_module --version 2.1.0 --root-hash c9ad6299dd62be478dc89a589cb88ab5876bee11812ed3bcaf97ecadcac0b34e --output /opt/logos-node/packages
lgpd download delivery_module --version 0.2.0 --root-hash eb47c06575a6113f34a6d71e5e0b72d6d2db2ec7510b8be0ab9633b8385edd57 --output /opt/logos-node/packagesInstall all three packages into the shared modules directory:
lgpm --modules-dir /opt/logos-node/modules install --file /opt/logos-node/packages/blockchain_module-0.2.1.lgx
lgpm --modules-dir /opt/logos-node/modules install --file /opt/logos-node/packages/storage_module-2.1.0.lgx
lgpm --modules-dir /opt/logos-node/modules install --file /opt/logos-node/packages/delivery_module-0.2.0.lgxCheck installed versions:
jq -r '.name + " " + .version' /opt/logos-node/modules/*/manifest.jsonThe output must include:
blockchain_module 0.2.1
delivery_module 0.2.0
storage_module 2.1.0Start Logos Core
As root, open a shell as the logos runtime user:
runuser -u logos -- env HOME=/var/lib/logos-node bashRun the daemon, module configuration, module calls, and health checks from this shell.
This keeps the daemon and CLI client on the same /var/lib/logos-node/.logoscore state and ensures generated files belong to logos.
For a first manual run,
start logoscore in the foreground with the shared modules directory:
cd /var/lib/logos-node
logoscore -D -m /opt/logos-node/modulesKeep that terminal open. Use another terminal for module commands.
For a temporary background run,
redirect output and append &:
cd /var/lib/logos-node
logoscore -D -m /opt/logos-node/modules > logoscore.log 2>&1 &For unattended operation, prefer a systemd service over a manually started daemon.
Check:
logoscore statusBlockchain
Create the blockchain peer file:
cd /var/lib/logos-node/blockchain-module-testnet
cat > peers.json <<EOF
{
"initial_peers": [
"/ip4/65.109.51.37/udp/3000/quic-v1/p2p/12D3KooWFrouXfmrR4nsLMtE7wu15DoMJ6VtoUtHinREZCvbWHar",
"/ip4/65.109.51.37/udp/3001/quic-v1/p2p/12D3KooWJRGau8M1rjT7R5e4YYsgdFhsMX35nRDtMwCDjxQkXAHz",
"/ip4/65.109.51.37/udp/3002/quic-v1/p2p/12D3KooWQXJavMDTRscjauFSgVAB1VLB6Rzpy2uY5SU9Tk7927tb",
"/ip4/65.109.51.37/udp/50001/quic-v1/p2p/12D3KooWSQc7CcGtvWDPF1yCbBthFnQjprfCVHmfmNDUrSmqQsU1"
]
}
EOFThe blockchain-module-testnet directory is a setup workspace for the peer file
and related blockchain commands.
If an existing node was created with the older blockchain-module-devnet
directory name, do not rename a running node just to match this guide.
Keep the existing path or update all local scripts and services consistently
during a planned reprovision.
Load the module and generate user_config.yaml:
logoscore load-module blockchain_module
cd /var/lib/logos-node/blockchain-module-testnet
logoscore call blockchain_module generate_user_config "$(cat peers.json)"
chmod 600 /var/lib/logos-node/user_config.yaml /var/lib/logos-node/keystore.yamlgenerate_user_config writes user_config.yaml in the logoscore daemon working directory.
With the service layout in this guide, that path is /var/lib/logos-node/user_config.yaml.
The generated user_config.yaml contains node-local wallet and key-management configuration.
Keep it private, restrict file permissions, and do not publish it.
Generate a fresh file for each node.
Start the module.
The second argument is intentionally an empty string; the blockchain module no longer requires a downloaded deployment.yaml file:
logoscore call blockchain_module start /var/lib/logos-node/user_config.yaml ""Check:
logoscore call blockchain_module get_cryptarchia_info | jq -r .result.value | jq .Blockchain Config
Operator-facing fields in user_config.yaml:
| Field | Purpose | Guidance |
|---|---|---|
network.initial_peers | Bootstrap peers | Use the current network document |
network.port | Public UDP P2P port | Keep aligned with firewall/NAT, normally 3000 |
api.listen_address | Local API bind | Keep private, normally 127.0.0.1:8080 |
state.base_folder | State directory | Use a persistent local path |
| logger filters | Log verbosity | Use INFO for unattended operation |
Joining Blend Network
Request funds to both the BlendZk and SdpFunding keys from your keystore.yaml from the faucet
The public keys and note IDs below are examples.
Use the corresponding values from your own keystore.yaml and wallet responses when running these commands.
# keystore.yaml
public_keys:
...
BlendZk: 13cccf99f90fd78c2134891ce3c1afce0605753a7694b9d56678d63a8d471820
...
SdpFunding: 91d381a87e05d46fc9bc95246273b6930290506f0589ad039444decd3c24940e
...
secret_keys:
...Wait until you receive funds to both addresses, you can check the balance of your accounts with the following commands, you may need to repeat the faucet requests since only one drip is allowed per block.
# check BlendZk key has received funds
logoscore call blockchain_module wallet_get_notes 13cccf99f90fd78c2134891ce3c1afce0605753a7694b9d56678d63a8d471820 "" \
| jq -r .result.value | jq .notes
# > [
# > {
# > "id": "de5f5b6d2baac23bf562d89676ebd304e8d6e6f67afc22f378b5dabf164d142d",
# > "value": "1000"
# > }
# > ]
# check SdpFunding key has received funds
logoscore call blockchain_module wallet_get_notes 91d381a87e05d46fc9bc95246273b6930290506f0589ad039444decd3c24940e "" \
| jq -r .result.value | jq .notes
# > [
# > {
# > "id": "47831c89a3609a7bd38755b2d2da7e2dfb63bef8515a8b8ad82c8a61b7b9a006",
# > "value": "1000"
# > }
# > ]Join the blend network by locking one of the notes held by your BlendZk key.
<YOUR_IP>: must be your external ip address<YOUR_BLEND_PORT>: Retrieve your configured blend port from the user_config.yaml (blend.core.backend.listening_address), note that if you do port-mapping, the external mapped port must be used.<BLEND_ZK_NOTE_ID>: the note id of one of the notes held by your BlendZk key, as queried above.
Before joining:
- open
<YOUR_BLEND_PORT>/udpon the public host firewall; - if the node is behind NAT, forward that external UDP port to the port in
blend.core.backend.listening_address;
The submitted locator must use the external address and port that other nodes can dial. The Blend core listener starts only after the node’s declaration becomes active. Configure the firewall and NAT forwarding before joining. Verify the local listener and public reachability after activation.
logoscore call blockchain_module blend_join_as_core_node \
"/ip4/<YOUR_IP>/udp/<YOUR_BLEND_PORT>/quic-v1" \
"<BLEND_ZK_NOTE_ID>"
# successful call will return the declaration id:
# > {"method":"blend_join_as_core_node","module":"blockchain_module","result":{"error":null,"success":true,"value":"2691821bd61394cc18939626de4e9231c699e8ddefd1ebf9e6c35b32229bdc65"},"status":"ok"}Verify the declaration was accepted on chain by polling /mantle/sdp/declarations, looking for your declaration
curl http://127.0.0.1:8080/mantle/sdp/declarations | jq .
# > [
# > {
# > "service_type": "BN",
# > "provider_id": "35d60d973560b8344f83dc266a3fe89e35a3dcf9959c492d0a7a0b7a85c5d2ce",
# > "locked_note_id": "<BLEND_ZK_NOTE_ID>",
# > "locators": [
# > "/ip4/<YOUR_IP>/udp/<YOUR_BLEND_PORT>/quic-v1"
# > ],
# > "zk_id": "13cccf99f90fd78c2134891ce3c1afce0605753a7694b9d56678d63a8d471820",
# > "created": 1,
# > "active": 3,
# > "withdraw_at": null,
# > "nonce": 0
# > }
# > ]
service_type: BN identifies it as a Blend node declaration, zk_id is your BlendZk public key, and provider_id is your BlendSigning key.
When in a block, the active epoch should be two epochs in the future (active == created + 2), as that’s when it will become active
Storage
Create the storage config:
cd /var/lib/logos-node/storage-module
mkdir -p storage-data
cat > config.json <<EOF
{
"data-dir": "./storage-data",
"log-level": "INFO",
"listen-ip": "0.0.0.0",
"listen-port": 8091,
"disc-port": 8090,
"network": "logos.test"
}
EOFFields:
| Field | Purpose |
|---|---|
data-dir | Storage repository path |
log-level | Log verbosity |
listen-ip | Local TCP bind address |
listen-port | Public TCP libp2p port |
disc-port | Public UDP discovery port |
network | Storage network preset |
The logos.test network preset provides the storage bootstrap settings.
Use fixed listen-port and disc-port.
Do not leave public nodes on random ports.
Start storage without mix:
cd /var/lib/logos-node/storage-module
logoscore load-module storage_module
logoscore call storage_module init @config.json
logoscore call storage_module startOptional: Mix Support And Private Queries
To run storage with mix support,
generate the storage config from the current published mix bootstrap data.
This replaces the basic config.json above.
The script accepts an optional storage data directory as its first argument.
Without one, it uses logos-storage-data under the current directory.
cd /var/lib/logos-node/storage-module
cat > make-mix-storage-config.sh <<'EOF'
#!/usr/bin/env bash
set -e
data_dir=${1:-"${PWD}/logos-storage-data"}
udp_spr_json=$(curl -s https://logos-storage-network.fra1.digitaloceanspaces.com/v0.2/udp-sprs.json)
tcp_spr_json=$(curl -s https://logos-storage-network.fra1.digitaloceanspaces.com/v0.2/tcp-sprs.json)
mp_json=$(curl -s https://logos-storage-network.fra1.digitaloceanspaces.com/v0.2/mix-pool.json | jq -c 'tostring')
cat <<JSON | jq .
{
"log-level": "INFO;trace:libp2p,mix",
"mix-enabled": true,
"listen-port": 8091,
"disc-port": 8090,
"bootstrap-node": $udp_spr_json,
"dht-mix-proxy": $tcp_spr_json,
"data-dir": "${data_dir}",
"mix-pool-json": ${mp_json}
}
JSON
EOF
chmod 755 make-mix-storage-config.sh
./make-mix-storage-config.sh > config.jsonStart storage with that config:
cd /var/lib/logos-node/storage-module
logoscore load-module storage_module
logoscore call storage_module init @config.json
logoscore call storage_module start
logoscore call storage_module togglePrivateQueries trueAfter startup, allow the node time to populate routing state. If the first private query fails with a manifest lookup error, retry once after a short warm-up period.
Privately query a known test object:
logoscore call storage_module downloadToUrl zDvZRwzkzrrYB6sS1rRpRLt4gBhc1pWoyTSjkfszfmj1seaYYLCZ /var/lib/logos-node/storage-module/farewell-to-westphalia.pdf false 65536Delivery
Create the kernel-only delivery config for a node operator:
Replace <public-ip> before running this command.
cd /var/lib/logos-node/delivery-module
cat > config.json <<EOF
{
"entryLayer": "kernel",
"kernelConf": {
"preset": "logos.test",
"relay": true,
"logLevel": "INFO",
"tcpPort": 30303,
"discv5UdpPort": 9000,
"discv5Discovery": true,
"nat": "extip:<public-ip>"
}
}
EOFFields:
| Field | Purpose |
|---|---|
entryLayer | Delivery stack layer; use kernel for a node-operator service |
kernelConf | Kernel node configuration |
kernelConf.preset | Network preset |
kernelConf.relay | Enable the Relay protocol |
kernelConf.logLevel | Log verbosity |
kernelConf.tcpPort | Public TCP P2P port |
kernelConf.discv5UdpPort | Public UDP discovery port |
kernelConf.discv5Discovery | Enable discv5 discovery |
kernelConf.nat | Public IP advertisement mode |
The kernel-only entry layer intentionally omits the messaging client and reliable channel manager.
Calls to send, subscribe, and channel* are unavailable, while getNodeInfo, storeQuery, and metrics remain available.
The logos.test preset provides the delivery network bootstrap settings.
extMultiaddrs is usually not needed when nat advertises the public address.
Use fixed tcpPort and discv5UdpPort.
Do not leave public nodes on random ports.
Start:
cd /var/lib/logos-node/delivery-module
logoscore load-module delivery_module
logoscore call delivery_module createNode @config.json
logoscore call delivery_module startCheck:
logoscore call delivery_module getAvailableNodeInfoIDs
logoscore call delivery_module getNodeInfo Version
logoscore call delivery_module getNodeInfo MyMultiaddressesHealth Checks
Check daemon and modules:
logoscore status --jsonExpected modules:
storage_module
blockchain_module
delivery_module
capability_moduleCheck listeners:
ss -lntup | egrep '(:3000|:8090|:8091|:9000|:30303|:8080)'Expected:
0.0.0.0:3000/udp
0.0.0.0:8090/udp
0.0.0.0:8091/tcp
0.0.0.0:9000/udp
0.0.0.0:30303/tcp
127.0.0.1:8080/tcpCheck blockchain:
logoscore call blockchain_module get_cryptarchia_info | jq -r .result.value | jq .Check delivery:
logoscore call delivery_module getNodeInfo MyMultiaddressesCheck the configured Blend UDP listener:
ss -lunConfirm that the local UDP port from blend.core.backend.listening_address is present.
If the public Blend port differs, also confirm that NAT forwards <YOUR_BLEND_PORT>/udp to this local port.
Optional: Systemd
For unattended operation, use systemd.
Recommended pattern:
- one service for
logoscore; - one separate bootstrap service or script for module startup;
- journald output with retention limits.
Do not start modules from ExecStartPost in the logoscore service.
If module startup is slow or returns an error, systemd may kill the daemon.
The daemon service should do only this:
[Unit]
Description=Logos Node
After=network-online.target
Wants=network-online.target
[Service]
User=logos
Group=logos
WorkingDirectory=/var/lib/logos-node
Environment=HOME=/var/lib/logos-node
ExecStart=/usr/local/bin/logoscore -m /opt/logos-node/modules -D
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.targetThe bootstrap script should:
- wait for
logoscore status; - load and start blockchain;
- load and start storage;
- load and start delivery;
- tolerate already-loaded modules and slow module starts.
Cap journal usage:
[Journal]
SystemMaxUse=200M
SystemKeepFree=1G
MaxRetentionSec=7day
MaxFileSec=1dayPrefer INFO logs for unattended operation.
Use DEBUG only for short troubleshooting windows.