Developers Forum for XinFin XDC Network

Discussion on: XDC Masternode Backup and Migration Procedure for v2.6.8 and Later

Collapse
gzliudan profile image
Daniel Liu • Edited on

Your three points are essentially correct, with two important additions and one ordering fix.

1. coinbase.txt — you are right, nothing to back up.

It is a write-only artifact. Nothing in XDPoSChain or XinFin-Node ever reads it; it is only
written by mainnet/start-node.sh, and only on first initialisation (the if [ ! -d
/work/xdcchain/XDC/chaindata ]
branch). On every restart the else branch runs and the file is
never touched again.

Why it is empty: the script extracts the address with
XDC account new ... | awk -F '[{}]' '{print $2}'. Since XDPoSChain v2.5.0 the command prints
Public address of the key: 0x… without curly braces (older versions printed
Address: {xdc…}, which is why you used to see content). So the awk gets an empty string and an
empty line is written. It is a cosmetic script bug, not a missing key.

The coinbase/signer is derived at runtime from the keystore, never from that file:
Etherbase() falls back to the first account in the keystore (eth/backend.go), and
StartStaking() does XDPoS.Authorize(eb, wallet.SignHash) — if the key were missing you would
get signer missing and the node would not seal at all.

Practical note: because of the same awk bug, on a freshly initialised node the --unlock value
is empty and empty entries are skipped, so the account is not unlocked on the very first run.
Restart the container once after a fresh init.

Two things I would still keep: the address itself (it is in the keystore file name
UTC--…--<address>, or XDC account list --datadir /work/xdcchain, or eth.coinbase) — you
need it for KYC/masternode registration and for post-migration verification.

2. The keystore file — critical, but not sufficient on its own.

a) Also migrate the password file. mainnet/.pwd on the host is mounted into the container
as /work/.pwd and is used for --password. A fresh clone ships it empty. If your key was
created with a non-empty password, the new server must have the same .pwd, otherwise the
account stays locked and the node cannot sign. Back up: xdcchain/keystore/UTC--* and
mainnet/.pwd.

b) Make sure there is exactly one keystore file. The start script unlocks
XDC account list | head -n 1 and the node picks the etherbase from the first account in the
keystore. If you let the new server generate its own key first and then add yours, you end up
with two and the node may choose the un-registered one. Best practice: copy your keystore +
.pwd before the first docker compose up. If it already generated one, delete the
auto-generated UTC--… file, then restart.

3. .env — yes, back it up.

It holds no secret material and can be rebuilt with ./start-wizard.sh mainnet, but
INSTANCE_NAME / CONTACT_DETAILS are what appear on the stats page, so restoring it saves
time.

One correction to the procedure

Stop the old node before the new one starts with the same key. Two nodes signing/voting with
the same key at the same time produce duplicate signatures; XDPoS v2 has a forensics path that
detects exactly this, and penalties are recorded in the checkpoint headers (the address then
shows up as SLASHED). Recommended order:

  1. cd XinFin-Node/mainnet && docker compose down on the old server (and keep it down).
  2. On the new server: install, cp env.example .env, fill it in, then place your UTC--… in xdcchain/keystore/ and your .pwd in mainnet/ — before the first start.
  3. docker compose up -d, let it sync. (Optional speed-up: instead of re-syncing, copy the whole xdcchain directory from the stopped old node — that also keeps XDC/nodekey, though the p2p key is not part of your masternode identity.)
  4. Verify:
   ./xdc-attach.sh
   > eth.coinbase                                   // must be your xdc… address
   > eth.getCandidateStatus(eth.coinbase, "latest") // expect { status: "MASTERNODE", … }
   > XDPoS.GetSigners()                             // your address should be listed
   > net.peerCount / eth.blockNumber                // peers > 0, height advancing
Enter fullscreen mode Exit fullscreen mode
  1. Only after the new node is confirmed signing should you touch anything else on the old box.

Note that the masternode stake and the KYC live on chain and are bound to the address, not to
the server, so nothing needs to be redone as long as the address is unchanged.

So, in short: must back up = keystore UTC--… + .pwd; should back up = .env + a
record of your coinbase address; not needed = coinbase.txt, chaindata, nodekey.

Collapse
pxinl444 profile image
PXI_Nl Author

Thank you very much for your detailed and helpful explanation.

Before asking this question, I had already tested the migration process about four times using my own procedure, and each time the migration completed successfully and the node continued receiving rewards without any issues.

That said, I’m very glad I was able to confirm my understanding and the migration process again here, especially regarding coinbase.txt, the keystore directory, and the .pwd file, as well as the importance of fully stopping the old node before starting the new one.

Your explanation has helped me feel even more confident about the process. I really appreciate you taking the time to explain everything so carefully.

Thank you again for your support, Daniel.