Startup guide
Install, configure and run the Lithos client, from nothing to mining.
This guide takes you from nothing to a Lithos client mining on the Ergo testnet. It covers the requirements, the configuration file, starting the client, connecting your mining software, and making your first difficulty commitment.
It does not cover lending collateral or using LithosDex, which both live in the client's web interface. LithosDex has its own section. It also does not explain how the protocol works internally. For that, read Lithos Protocol.
Before you begin#
You need the following:
| Requirement | Detail |
|---|---|
| Java 11 | Required by both the Ergo node and the Lithos client. Later Java versions are not supported |
| An Ergo node | Version 6.0.4 or later, on testnet, with indexing and mining enabled, fully synced |
| Mining software | Any miner supporting Ergo's Autolykos 2 algorithm |
| Testnet ERG | A balance in the node wallet, to cover transaction fees and submission bonds. See What submitting costs |
| GPU memory | See the warning below |
The node must be version 6.0.4 or later. Lithos sets a specific coinbase recipient on every block it builds, and only these node versions expose the API call that allows it. On an older node, no Lithos block can be produced.
Step 1: Set up an Ergo testnet node#
Lithos talks to a local Ergo node to read the chain, sign transactions with the node's wallet keystore,
and receive block candidates. Follow Setting up an Ergo testnet node,
which covers installation, the ergo.conf file, creating a wallet, and verifying the node's API.
Before continuing, confirm three things:
- The node is fully synced. Check the height on the node panel at
http://127.0.0.1:9052/panel. - The node was started with
extraIndex = true. Lithos reads boxes by address, token and script, and only an indexed node serves those queries. - You have the node's API key and wallet password, and know the path to the wallet keystore file.
Step 2: Download and unpack the Lithos client#
Download the latest release .zip from the
Lithos Protocol releases, then unzip it. The archive expands into
a lithos-client folder containing:
| Folder | Contents |
|---|---|
bin/ | The start scripts, and where your configuration file goes |
conf/ | application.conf, the shipped defaults for every setting |
lib/ | The client's JAR files |
Do not edit conf/application.conf. You override the settings you care about in your own file, which
keeps your configuration intact when you upgrade.
Step 3: Create your configuration file#
Create a file named lithos.conf inside lithos-client/bin. The client reads this file at startup and
pulls in the shipped defaults through the include on the first line.
{
include file("../conf/application.conf")
node {
url = "http://127.0.0.1"
key = "NODE_API_KEY_HERE"
storagePath = "path/to/nodefolder/.ergo/wallet/keystore/keyfile.json"
pass = "NODE_WALLET_PASS_HERE"
networkType = "TESTNET"
explorerURL = "default"
numAddresses = 32
mempoolSorting = "bySize"
}
# Change this to any long random string of your own
play.http.secret.key = "changethissecret"
# Blake2b256 hash of the API key that guards the client's authenticated endpoints.
# This value is the hash of "hello". Change it. See "Security" below.
lithos.apiKeyHash = "324dcf027dd4a30a932c441f365a25e86b173defa4b8e58948253471b81b72cf"
stratum {
diff = "140M" # Format: (value)(powerOfTen), e.g. "4.0G", "1.52M", "300.1K"
stratumPort = 4444
reduceShareMessages = true # Cuts share traffic between your mining software and Lithos
reductionMultiplier = 10000 # How far it cuts: 10, 100, 1000 or 10000
forceConfigDiff = false # Leave false unless you are experimenting
}
state.autoCommit = false # Leave off to commit from the web interface. See Step 6
}Every setting in that file:
| Setting | What it does |
|---|---|
node.url | Your node's address, including the scheme. Give a port to use it, or leave it off and Lithos appends the default: 9052 on testnet, 9053 on mainnet |
node.key | The node's REST API key, matching the apiKeyHash in your ergo.conf |
node.storagePath | Full path to the node wallet's keyfile.json. Lithos signs transactions with it |
node.pass | The node wallet password, used to unlock that keystore |
node.networkType | TESTNET or MAINNET. Decides the node port, address prefixes and contract set |
node.explorerURL | Required by the Ergo SDK the client is built on. The client reads nothing from it, so leave it at default |
node.numAddresses | How many wallet addresses Lithos derives keys for. Leave it at 32. Raising it later is safe; lowering it strands any ERG already paid to the addresses above the new limit |
node.mempoolSorting | Must match your node's ergo.node.mempoolSorting, either bySize or byExecutionCost. Lithos packs blocks against the rule your node actually applies |
play.http.secret.key | Signs the client's own web session cookies. Set it to any long random string |
lithos.apiKeyHash | Blake2b256 hash of the key required by the client's authenticated endpoints |
stratum.diff | The difficulty the stratum serves until your difficulty commitment takes effect, and the one autoCommit commits. See Choosing a difficulty |
stratum.stratumPort | The port your mining software connects to |
stratum.reduceShareMessages | Raises the difficulty your mining software reports at, without changing the difficulty Lithos pays you at |
stratum.reductionMultiplier | How many times your committed difficulty it raises it to: 10, 100, 1000 or 10000. At 10000 your mining software sends only super shares |
stratum.forceConfigDiff | Forces Lithos to mine at diff instead of your on-chain commitment. For testing only |
state.autoCommit | Registers you and commits diff on the blockchain, then keeps your difficulty commitment equal to diff. Ships off, so you commit from the web interface instead. See Step 6 |
Keeping secrets out of the file#
lithos.conf holds your node API key and wallet password in plain text. To read them from environment
variables instead, add these lines at the end of the file:
node.key = ${?NODE_KEY_ENV}
node.pass = ${?NODE_PASS_ENV}
play.http.secret.key = ${?PLAY_ENV}Each line overrides the value above it when the named variable is set, and is ignored when it is not.
Step 4: Start the client#
Start your Ergo node first and wait for it to sync. Then run the start script from the bin folder:
cd lithos-client\bin
.\lithos-client.batcd lithos-client/bin
./lithos-clientThe client starts a stratum server on port 4444 and a web interface on port 9000. Open
http://localhost:9000 in a browser to see sync status, your mined blocks, payments and collateral
positions.
Step 5: Connect your mining software#
Lithos works with any Autolykos 2 miner. The wallet address and worker name you pass have no effect on Lithos, so any valid string works. Payouts are decided by your difficulty commitment, not by what your mining software reports.
SOAT Miner is open source, charges no dev fee, and supports
Lithos directly. Use the --lithos option, or run the included mine_ergo_lithos script, which sets
everything up for you.
Rigel is closed source and charges a dev fee, but it is tested and known to work:
rigel.exe -a autolykos2 -o stratum+tcp://127.0.0.1:4444 -u YOUR_ERG_WALLET -w my_rig --log-file logs/miner.log127.0.0.1 reaches a client on the same machine as the rig. A rig on another machine uses the client
machine's LAN address instead, such as stratum+tcp://192.168.1.20:4444. The stratum accepts rigs
from every network by default; to limit it to this machine or to one network, set
stratum.bindAddress.
Step 6: Commit your difficulty#
You cannot be paid until your difficulty is committed on the blockchain. A difficulty commitment is a promise to mine at a given difficulty, made in advance, and it is what makes your payouts reflect your hashrate rather than your luck. Your first difficulty commitment also registers you as a Lithos miner.
Nothing is written on chain until you commit. Until then, the client mines normally but cannot submit NISPs, so you are not paid from rollups. Every tab of the Mining web interface shows a warning while no difficulty commitment is in force.
To commit from the web interface, follow these steps:
- Choose your difficulty. See Choosing a difficulty.
- Open Mining, then Difficulty, then the Commitment tab.
- Enter your difficulty under New diff, written the way
stratum.diffis, such as140M. - Check the block heights the panel shows, then tick the box that confirms the lock.
- Enter your API key if the panel asks for it, then select Register and commit.
Registering costs 0.002 ERG from the node wallet: 0.001 ERG locked in your data box and a 0.001 ERG
network fee. Each later change costs the 0.001 ERG fee. To commit without the web interface, send
POST /mining/commitment with your difficulty and your API key. GET /mining/commitment reports what
is in force. See Lithos API.
Three waits then stand between you and earning:
- Synchronizing. The client syncs from
sync.startHeightinapplication.conf, which you can override in your own file withsync.startHeight = NEW_HEIGHT. Syncing the miner registry takes about 30 minutes on the current testnet. The Commitment tab refuses to commit until it finishes. - Confirming. Your registration transaction confirms, and the client records your registration.
- The difficulty commitment taking effect. It binds 125 blocks after you send it: about 1 hour 35 minutes on testnet, and about 4 hours 10 minutes on mainnet. Work you do before then is not payable.
The Commitment tab shows each stage. The warning disappears once your difficulty commitment is in force.
Letting the client commit for you#
state.autoCommit makes the client register you and keep your difficulty commitment equal to
stratum.diff. It ships off. Turn it on if you prefer to set your difficulty in lithos.conf:
stratum.diff = "YOUR_DIFF"
state.autoCommit = trueAfter a restart, the client checks your registration and difficulty commitment about a minute after
startup and every minute after that. Auto-commit waiting on ... in the log names what the client is
waiting for, and Difficulty commitment ... is on chain means it is done. While autoCommit is on,
the Commitment tab and POST /mining/commitment refuse to commit, so the two never change your
difficulty against each other.
Changing your difficulty later costs a day, not an hour#
To change your difficulty, enter the new value on the Commitment tab. With autoCommit on, edit
diff and restart instead. A change can only be sent when the contracts allow it. Two rules decide
when that is, both counted from when you send a difficulty commitment:
| Rule | Blocks | On testnet | On mainnet |
|---|---|---|---|
| Before the commitment takes effect | 125 | about 1 hour 35 minutes | about 4 hours 10 minutes |
| Before the commitment may be replaced | 845 | about 10 hours 30 minutes | about 28 hours |
The second rule is the expensive one. A rollup stays open to fraud proofs for 720 blocks after the block that opened it, and a super share may be 60 blocks older than that block. Your commitment has to survive that whole span so the contracts can check old work against the difficulty you actually promised.
Choosing a difficulty#
Your diff value is the most consequential setting in the file. It decides both what you are paid and
whether you get paid at all.
Super shares#
While mining, you will see log messages about super shares. A super share is a share that clears one ten-thousandth of your difficulty target. That makes it rare enough to be evidence of sustained work, and common enough to accumulate.
To be paid for a block, you must have produced 10 super shares within the 60 blocks before that block was found. Those 10 super shares plus your score become one Non-Interactive Share Proof (NISP), which the client submits for you.
Sixty blocks is about 45 minutes on testnet and about 2 hours on mainnet, because testnet blocks arrive roughly every 45 seconds against mainnet's 2 minutes. The window is the same 60 blocks on both networks, so testnet gives you less wall-clock time to reach 10 super shares than mainnet will.
Those times are averages. Blocks arrive early or late, so on mainnet about 1 window in 13 lasts under 100 minutes. A short window costs every miner super shares at the same time, and the recommendations below allow for it.
How many super shares you produce depends on your hashrate and your diff:
- Raising
diffincreases your payout per block, and produces fewer super shares. - Lowering
diffproduces more super shares, and pays less per block.
Aim for a diff that averages between 12 and 17 super shares per window. That range is where
expected earnings peak. On mainnet, averaging 12 pays you about 75% of the time at the highest score
in the range. Averaging 17 pays you about 96% of the time at a lower one. Below 12 your earnings fall
quickly, because short windows leave you under 10.
Start at averaging 17, then raise diff slowly. Averaging 17 pays you about 96% of the time on
mainnet and about 93% on testnet. It still lands inside the range if your hashrate turns out to be
29% lower than you estimated. Once your payouts arrive steadily, raise diff a little at a time
toward averaging 15, where expected earnings peak. Each change is a new commitment, so steps are at
least 845 blocks apart, as
Changing your difficulty later explains.
To find a starting value for your hardware:
diff = (hashrate in H/s × window in seconds) ÷ (10,000 × super shares you want to average)The window is 2,700 seconds on testnet and 7,200 seconds on mainnet. So a 1 GH/s rig on testnet
averages 17 super shares at a diff of 15.9M, and 12 at 22.5M.
Mining on Lithos has the full table of payout chances at each average, and starting values for common hashrates. On testnet, try several values and watch how many super shares your hardware actually produces.
What submitting costs#
Every NISP you submit carries a bond, which the client posts from your node wallet alongside the proof. You get it back in full when the rollup pays out. You lose it only if someone proves your submission fraudulent, in which case it goes to whoever proved it.
The bond is priced from the difficulty you claimed:
bond = max(0.002 ERG, your score / 25)Your score is your committed difficulty, and dividing it by 25 gives the bond in nanoERG. So a higher
diff raises both what you earn per block and what you must have on hand to claim it. The floor of
0.002 ERG applies below a difficulty of 50M, and above that the bond rises with your difficulty:
| Committed difficulty | Bond per submission |
|---|---|
| 50M or below | 0.002 ERG, the floor |
| 140M | 0.0056 ERG |
| 1.0G | 0.04 ERG |
| 4.0G | 0.16 ERG |
| 25G | 1.0 ERG |
Keep enough testnet ERG in the node wallet to cover a bond for every rollup you are submitting to at once, plus about 0.001 ERG of transaction fee each. Rollups open on every Lithos block and stay open for 360 blocks, so several can be in flight together.
Testing values without committing#
To experiment without writing anything to the blockchain, do not commit, leave autoCommit off, and
force the stratum to use your diff:
stratum.forceConfigDiff = true
state.autoCommit = falseThe client then always mines at the diff in your config and never commits it. Your experimental
values stay off-chain.
Reducing share traffic#
At low difficulties your mining software may send enough shares to trigger errors about duplicate or
old shares. Set reduceShareMessages = true, the default in the shipped config, to raise the stratum
difficulty to reductionMultiplier times your committed difficulty. The difficulty Lithos evaluates and
pays you at is unchanged.
At the default reductionMultiplier = 10000, your mining software sends only super shares. If that
leaves it too few shares to show a steady hashrate, lower it to 1000, 100 or 10. See
Share traffic.
Where Lithos stores its data#
The client creates a .lithos folder next to the start script the first time it mines a super share.
It holds your super shares and rollup state. Do not delete it while the client is running.
Common problems#
The following table lists the failures reported most often, and what to do about them:
| What you see | Cause | Fix |
|---|---|---|
| The client will not start | The node is not running, or node.storagePath or node.pass is wrong | Start the node first. Check the keystore path and password |
| No blocks are ever marked as Lithos blocks | The node is older than 6.0.4 | Upgrade the node |
| Box lookups fail, or the collateral list is empty | The node was started without extraIndex = true | Add it to ergo.conf and restart the node |
| Your hashrate is far below normal | The Autolykos 2 table does not fit in VRAM | See the memory warning above |
| Duplicate or old share errors | diff is low enough to flood the stratum | Set reduceShareMessages = true, or raise reductionMultiplier |
| Mining works, but you are never paid | No difficulty commitment is in force, or you are producing fewer than 10 super shares per 60 blocks | Check the Commitment tab and commit if it says you are not committed, then wait 125 blocks. If that was not it, lower your difficulty |
| Submissions fail to build | The node wallet cannot cover a bond | Fund the wallet. See What submitting costs |
| Transactions fail to broadcast | The node wallet has no ERG for fees | Fund the node wallet with testnet ERG |
Security#
Lithos uses your node's wallet and API key to build and sign transactions on your behalf. Two things follow from that:
- Use a fresh testnet key. The client reads your node's secret keys from its keystore. Generate a key for testnet that is unrelated to any mainnet wallet you own.
- Change both default secrets. The shipped
lithos.apiKeyHashis the hash of the stringhello, and the shippedplay.http.secret.keyis a placeholder. Anyone who reaches your client with the default API key can move funds. Replace both before running.
To generate a new API key hash, use your node's POST /utils/hash/blake2b endpoint at
http://127.0.0.1:9052/swagger, then put the resulting hash in lithos.apiKeyHash and keep the
original string as your key.
Next steps#
- Setting up an Ergo testnet node: the full node walkthrough.
- Lithos Protocol: how payouts and collateral work.
- Mining on Lithos: scores, super shares and NISPs in detail.
- Lithos API: the client's REST endpoints, callable from these docs.