Author: Matt Henderson @dafacto
This document details migrating from a public/private Spacemesh node setup to a single node managing four postdata sets, using the new “1:n” feature of go-spacemesh version 1.4, on a 2023 Mac mini.
Spacemesh wizard @Earl in Discord recommends backing up the following before migrating from version 1.3 to 1.4:
Here’s an outline of the process, followed by the contents of my specific configuration files. (The Spacemesh documentation for all the below can be found here, though I found it a bit difficult to follow, as it’s more generic in nature.)
go-spacemesh nodes.go-spacemesh binary that runs your node, and the post service binary that manages your postdata.grpc-post-listener on port 9094 in your startup scripts, modifying the port of any other listeners that conflict with that port. This allows go-spacemesh to communicate with post service processes, each of which does the proving for a particular postdata set.direct private peers from your public node configuration, if you’re migrating from a private/public node setup like me.merge tool discussed in a later step.key.bin file in your postdata folder to key.bin.bak, move and rename the original to local.key in a new identities folder in your node’s node-data folder.local.key files in those identities folders, and rename them to something corresponding to your particular nodes. In my case, I ended up with node1.key, node2.key, node3.key and node4.key. Important!—if you leave your main node key named local.key the migration will not work!merge-nodes utility delivered with go-spacemesh to merge all your nodes into one, e.g. Here I’m merging node2 into node1: ./merge-node --from ~/Spacemesh/node2/node-data --to ~/Spacemesh/node1/node-data. This will move/consolidate all those node.key files into the identities directory of your future single node. (I used node1 as my eventual master, single node.)service processes you’ll run. (See below.)services process for each postdata set you have. (See example below.)go-spacemesh on a single node, and then start your four service processes.At this point you’re finished! You have one node running, communicating with multiple service processes, smeshing multiple postdata sets!
Let’s now look at my specific configurations, so you can see some real-world examples.
start-node.sh
This is the script that I run to start my node. You’ll see that instead of leaving it named node1, I simply renamed it node.
--grpc-post-listener parameter.#!/bin/bash
/Users/mhenders/Spacemesh/app/go-spacemesh \
--config /Users/mhenders/Spacemesh/node/config/config.json \
--listen /ip4/0.0.0.0/tcp/7515 \
-d /Users/mhenders/Spacemesh/node/node-data \
--filelock /Users/mhenders/Spacemesh/node/lock/spacemesh.lock \
--grpc-public-listener 0.0.0.0:9092 \
--grpc-private-listener 0.0.0.0:9093 \
--grpc-post-listener 127.0.0.1:9094 \
--grpc-json-listener 0.0.0.0:9095
go-spacemesh config.json
"smeshing-start": false parameter, so that the node itself isn’t smeshing."post-k3": 1 configuration is to enable distributed ATX verification.{
"main": {
"layer-duration": "5m",
"layers-per-epoch": 4032,
"poet-servers": [
{
"address": "https://poet-1.team24.co",
"pubkey": "AHlrgUZq5dFqK2oa2C9qVq4qIE2beJ/mG7sryynfqx0="
},
{
"address": "https://poet-2.team24.co",
"pubkey": "8SatjpHxbrfeIKTFSAFcZklxPnhUElloRvAUAy1xOxo="
},
{
"address": "https://poet-3.team24.co",
"pubkey": "givyUYkXx4kVe7gOngNEeIA4YrNBPojB7lAH1RLA62c="
},
{
"address": "https://poet-4.team24.co",
"pubkey": "C7/aEeZ716W17Z/Gz1GHtCVEcK8IN2JXrhVyIF43aEA="
}
]
},
"logging": {
"p2p": "error"
},
"poet": {
"phase-shift": "288h",
"cycle-gap": "24h",
"grace-period": "2h"
},
"p2p": {
"min-peers": 30,
"low-peers": 60,
"high-peers": 100,
"bootnodes": [
"/dns4/mainnet-bootnode-14.spacemesh.network/tcp/5000/p2p/12D3KooWRkZMjGNrQfRyeKQC9U58cUwAfyQMtjNsupixkBFag8AY",
"/dns4/mainnet-bootnode-16.spacemesh.network/tcp/5000/p2p/12D3KooWDAFRuFrMNgVQMDy8cgD71GLtPyYyfQzFxMZr2yUBgjHK",
"/dns4/mainnet-bootnode-18.spacemesh.network/tcp/5000/p2p/12D3KooWMJmdfwxDctuGGoTYJD8Wj9jubQBbPfrgrzzXaQ1RTKE6"
],
"direct": []
},
"smeshing": {
"smeshing-start": false,
"smeshing-coinbase":"{address}"
},
"post": {
"post-k3": 1
}
}
start-service1.sh
Here’s one of the four start-service.sh scripts, that start four post services, one for each postdata set I have.
operator-address parameter, that will let you monitor the post service on the local web URL http://127.0.0.1/50051/status. Of course, you need to change the port to something unique for each service. I used 50051 through 50054.threads have been set to 0, which let’s the operating system’s scheduler figure out how many threads to assign to each process.nonces from my previous setup. (There is a complicated profiler process if you want to try to optimize threads and nonces.)#!/bin/bash
/Users/mhenders/Spacemesh/app/service \
--threads 0 \
--address=http://localhost:9094 \
--dir /Volumes/smesh1/postdata \
--nonces 288 \
--operator-address=127.0.0.1:50051
LaunchAgents
On the Mac, you need to create a LaunchAgent, which goes in ~/Library/LaunchAgents/, to control your post services, just like you should have one to control the launch of go-spacemesh. This will launch them all on machine startup, and relaunch them if they ever crash. This is similar to systemd on Linux machines.
You pretty much need to use the LaunchControl app for Mac, to load and run your launch agents, making the process much easier than manually managing them.
I have four service launch agents, one for each start-service.sh script.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>KeepAlive</key>
<dict>
<key>Crashed</key>
<true/>
</dict>
<key>Label</key>
<string>com.spacemesh.service1</string>
<key>Program</key>
<string>/Users/mhenders/Spacemesh/node/start/start-service1.sh</string>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/Users/mhenders/Spacemesh/node/logs/error-service1.log</string>
<key>StandardOutPath</key>
<string>/Users/mhenders/Spacemesh/node/logs/service1.log</string>
</dict>
</plist>
I use the Mac app Keyboard Maestro to monitor my setup once per hour. Here’s what that looks like, collapsing the macro contents into the highest level groups:
/Users/mhenders/Spacemesh/app/go-spacemesh version/opt/homebrew/bin/grpcurl --plaintext -d "{}" localhost:9092 spacemesh.v1.NodeService.Status/opt/homebrew/bin/grpcurl --plaintext localhost:9093 spacemesh.v1.SmesherService.SmesherIDshttp://127.0.0.1:%PostPort%/status where %PostPort% is the http port on which the particular process was configured. (Here’s the official documentation that contains all the status responses you might receive./opt/homebrew/bin/grpcurl --plaintext localhost:9094 spacemesh.v1.PostInfoService.PostStatesThis Keyboard Maestro macro writes all monitoring data to a file that I can inspect at any time, and is configured to email me if anything is wrong.
Here’s what my directory system looks like, after finishing this migration.
Thanks to @nj, @fastmat, @flare, @hakehardware, @earl and others for helping me get all this figured out!
If you have any questions, I’m @dafacto in Discord, or ping me on Twitter.