Run an Ethereum Classic node
This page follows an Ethereum Classic node in depth, from its first start to a clean stop. Its commands are written for Linux and macOS. Running a node has a guide for each platform, including Windows and Docker, and the flags for each kind of node. Run a Mordor node covers what differs on the test network.
What this runs, and what it does not need¶
geth is the whole node. Ethereum Classic is proof of work, so there is no consensus client or beacon node to run beside it, and no JWT secret to configure.
The Engine API, the interface Ethereum’s consensus clients use, starts only on a chain configured for the merge, and neither Ethereum Classic nor Mordor is. The node opens no port 8551 and writes no JWT secret. Given --authrpc.addr, --authrpc.port, --authrpc.vhosts or --authrpc.jwtsecret, it logs that it ignored them.
Before you start¶
geth versionreports a 1.13 release. See Installation.- The machine has the disk and memory the network needs. See Hardware requirements.
- Other nodes can reach this one. Allow the peer-to-peer port through your firewall, over TCP and UDP. Ports and listeners gives the port, and A host firewall a ruleset.
Start it¶
1 | |
<datadir> is a directory on the disk that will hold the chain, and the node creates it on first start. The node runs in the foreground and logs to the terminal until you stop it.
Every command on this page passes --classic. On a new or Ethereum Classic data directory, geth with no network flag also runs Ethereum Classic (what that changes for a node upgraded from v1.12.x). The flag is still worth passing. It records the network in your service file, and it makes the node refuse a data directory that holds another network instead of running it. Pointed at a Mordor data directory, geth --classic stops at once:
1 | |
Where your data lives¶
Path, inside <datadir> | What it holds |
|---|---|
geth/chaindata/ | The chain database |
geth/chaindata/ancient/ | Older headers, bodies and receipts, kept as flat files |
geth/nodekey | The node’s private key, which sets its identity on the network; written on first start |
geth/nodes/ | The database of other nodes this node has found |
geth/etchash/ | Etchash verification caches, written during sync |
geth/blobpool/, geth/transactions.rlp | Transaction pool state |
keystore/ | Account keyfiles; empty until you create an account |
tmp/ | Temporary files |
geth.ipc | The socket geth attach connects to; it exists while the node runs |
Delete nothing inside it by hand. Removing geth/nodekey, for one, gives the node a new identity on the network.
Without --datadir, the node uses a classic directory under a default location:
| Platform | Default data directory |
|---|---|
| Linux | ~/.ethereum/classic |
| macOS | ~/Library/Ethereum/classic |
| Windows | %LOCALAPPDATA%\Ethereum\classic, unless AppData\Roaming\Ethereum in your home directory already exists and is not empty, in which case its classic directory |
What a healthy first sync looks like¶
The lines below come from a first sync of Ethereum Classic with the default settings. They are in order, with the data directory shown as <datadir>; the timestamps show where the log skips ahead.
Starting:
1 2 3 4 5 6 7 | |
Starting Core-Geth on Ethereum Classic...names the network.scheme=hashis the state scheme a new database gets (state scheme).network=1is Ethereum Classic’s network ID, anddbversion=<nil>means the database is new.Writing custom genesis blockappears once, on a new data directory.Failed to load snapshotis expected on a new data directory: it has no state snapshot yet, so the node starts building one.IPC endpoint openedgives the socket thatgeth attachconnects to.
Syncing:
1 2 3 4 5 6 | |
- Once it has peers, the node downloads two things side by side and logs each one: the chain (headers, bodies and receipts) and the state (accounts, storage slots and contract code).
synced=is each one’s progress.etais the node’s own estimate, and it swings widely at first. state healinglines follow the state download, while the node fetches state that changed as it downloaded.pendingcounts what is left, and healing lines can reappear briefly later in the sync.- The
ERRORandWARNlines are expected. The table below says why each appears.
Synced:
1 2 3 4 5 | |
Snap sync complete, auto disablingmarks the end of the first sync.Enabled artificial finality features reason=syncedis MESS switching on (MESS on this node).- From here the node imports new blocks as they arrive, usually one block per
Imported new chain segmentline.af=trueon those lines means MESS is in force. - The node goes on building its state snapshot in the background, and serves no snapshot data to other nodes until that finishes.
Indexed transactionsmeans the transaction index is built.
Warnings a first sync logs¶
A first sync logs many of these. None of them stops it.
| Line | Level | Why it appears |
|---|---|---|
Failed to load snapshot | WARN | A new data directory has no state snapshot, so the node builds one |
Pivot seemingly stale, moving | WARN | The chain moved on while the state downloaded, so the node moved its sync target forward |
Synchronisation failed, dropping peer | WARN | Syncing from one peer failed, for example with err=timeout, and the node dropped that peer |
How to tell it is done¶
A new node is synced when all four of these hold.
- The log shows the sync finishing:
Snap sync complete, auto disabling, thenEnabled artificial finality features reason=synced. -
eth.syncingreturnsfalse:1$ geth --classic attach --exec 'eth.syncing' <datadir>/geth.ipcUntil then it returns an object, even on a node that has not started syncing, and it stays an object until
Indexed transactionsis logged. In that objectcurrentBlockclimbs towardhighestBlock, buthighestBlockis the head the sync set out for, and during a long sync the network moves past it. It is not the network’s head. -
The node has peers. This returns a number above zero:
1$ geth --classic attach --exec 'net.peerCount' <datadir>/geth.ipc -
Its head matches the network’s. Compare this with a block explorer or another node you operate; the two should match, give or take the blocks mined between the readings:
1$ geth --classic attach --exec 'eth.blockNumber' <datadir>/geth.ipc
After an upgrade from v1.12.x, use the checks in 5. Start, and verify instead.
Run it as a service¶
Each platform guide keeps the node running, and gives it time to stop cleanly:
| Platform | How | Where |
|---|---|---|
| Linux | A systemd service | Linux users guide, step 6 |
| macOS | A launchd agent | Mac users guide, step 6 |
| Windows | A window that opens when you sign in | Windows users guide, step 6 |
| Docker | A restart policy and a stop timeout | Docker users guide, step 3 |
Stop it safely¶
Send the node one interrupt, then wait. In the foreground, press Ctrl-C once. sudo systemctl stop core-geth and docker stop send SIGTERM, which the node handles the same way. A synced node logs:
1 2 3 4 5 6 7 | |
Blockchain stopped means the node has written its cached state to disk. The process exits after that line; wait for it to exit before you start anything else on the data directory.
Pressing Ctrl-C again does not speed it up. Each further interrupt only logs a warning:
1 | |
The tenth further interrupt makes the node panic instead of finishing, which is an unclean stop.
A stop during the first sync takes longer, because the node first rolls back the part of the chain it was downloading (stop times). It also logs an error that you can ignore:
1 | |
Started again, the node resumes the sync.
A killed node logs Unclean shutdown detected when it next starts (After an unclean stop).
A node started with the console subcommand stops differently; see Command line.
Use your node¶
geth attach without --exec opens an interactive JavaScript console on the running node:
1 | |
For programs and wallets, turn on the HTTP endpoint:
1 | |
It listens on 127.0.0.1:8545 only, and serves the eth, net and web3 namespaces; admin calls are refused. Ask it for the chain ID:
1 2 3 4 | |
0x3d is Ethereum Classic’s chain ID (supported networks). A wallet uses the same URL and chain ID.
Keep the endpoint on 127.0.0.1. Before you open it wider, read RPC exposure.
MESS on this node¶
This node runs MESS, Modified Exponential Subjective Scoring (ECIP-1100), a chain-selection defense against deep reorganizations. It ships on by default as the client maintainers’ decision, which the README’s ETC consensus history explains. The node switches it on when it finishes syncing: that is the Enabled artificial finality features reason=synced line. admin_ecbp1100Status reports its state and changes nothing:
1 | |
nodeSwitch is the switch that log line turns on. enabled is true when that switch is on and the head has reached activatedAtBlock, the block MESS applies from. MESS covers turning it off and back on, and when the node switches it off by itself.
Next steps¶
- Running a node, for your platform’s commands and the flags for each kind of node.
- Run a Mordor node, to rehearse on the test network.
- Hardware requirements, for disk, memory and sync times.
- Sync modes and data retention, for how a node syncs and what it keeps.
- Maintenance, backup and upgrades, to back up, upgrade and prune the node.
- Monitoring, for metrics, logs and health checks.
- Troubleshooting, for what a problem looks like in the log and how to fix it.
- Choose your role, for the guides that match what you run the node for.
- Security and network exposure, for ports, the firewall and RPC exposure.
- Configuration, to keep settings in a file, and Command-line Options, for every flag.
- JSON-RPC API, and the
ethnamespace foreth_syncingand the rest of it. - Migrating to v1.13.0, if this machine ran a v1.12.x node.