|
| 1 | +--- |
| 2 | +id: devnet-from-existing-data |
| 3 | +title: Devnet From Existing Data |
| 4 | +--- |
| 5 | + |
| 6 | +# Devnet From Existing Data |
| 7 | + |
| 8 | +This guide explains how to run a local `dev` chain using an existing Mainnet or Testnet data directory. This setup is useful when you want local testing with real chain data without syncing from scratch. |
| 9 | + |
| 10 | +:::caution |
| 11 | +Always work on a copy of the data directory. Never modify your original Mainnet or Testnet data directly. |
| 12 | +::: |
| 13 | + |
| 14 | +## 1. Copy the Existing Data Directory |
| 15 | + |
| 16 | +Copy the source data directory to a new location for the dev chain: |
| 17 | + |
| 18 | +```bash |
| 19 | +cp -r /path/to/ckb-data /path/to/ckb-dev-fork |
| 20 | +cd /path/to/ckb-dev-fork |
| 21 | +``` |
| 22 | + |
| 23 | +All commands below assume the current directory is the copied directory. |
| 24 | + |
| 25 | +## 2. Get the Source Chain Spec File |
| 26 | + |
| 27 | +Download the chain spec file that matches your copied data: |
| 28 | + |
| 29 | +- Mainnet: `https://github.com/nervosnetwork/ckb/blob/develop/resource/specs/mainnet.toml` |
| 30 | +- Testnet: `https://github.com/nervosnetwork/ckb/blob/develop/resource/specs/testnet.toml` |
| 31 | + |
| 32 | +For example, for Mainnet: |
| 33 | + |
| 34 | +```bash |
| 35 | +curl -L -o mainnet.toml \ |
| 36 | + https://raw.githubusercontent.com/nervosnetwork/ckb/develop/resource/specs/mainnet.toml |
| 37 | +``` |
| 38 | + |
| 39 | +## 3. Initialize the Dev Chain and Import the Source Spec |
| 40 | + |
| 41 | +```bash |
| 42 | +ckb init --chain dev --import-spec ./mainnet.toml --force |
| 43 | +``` |
| 44 | + |
| 45 | +If you copied Testnet data, replace `mainnet.toml` with `testnet.toml`. |
| 46 | + |
| 47 | +## 4. Update `specs/dev.toml` |
| 48 | + |
| 49 | +Set `Dummy` Proof-of-Work for local development. The `[params]` section differs between Mainnet and Testnet — use the matching block below. |
| 50 | + |
| 51 | +:::note |
| 52 | +`genesis_epoch_length` (together with the epoch reward fields) participates in the genesis cellbase reward calculation, which determines the genesis block hash. If the value here does not match the value the source chain was launched with, the node will refuse to start with `chainspec error: ChainSpec: genesis hash mismatch`. |
| 53 | +::: |
| 54 | + |
| 55 | +### Mainnet |
| 56 | + |
| 57 | +Mainnet was launched with `genesis_epoch_length = 1743`, so this value must be preserved: |
| 58 | + |
| 59 | +```toml |
| 60 | +[params] |
| 61 | +genesis_epoch_length = 1743 |
| 62 | +cellbase_maturity = 0 |
| 63 | +permanent_difficulty_in_dummy = true |
| 64 | + |
| 65 | +[pow] |
| 66 | +func = "Dummy" |
| 67 | +``` |
| 68 | + |
| 69 | +### Testnet |
| 70 | + |
| 71 | +The bundled Testnet spec has no `[params]` section and was launched with the default `genesis_epoch_length = 1000`. Do **not** add `genesis_epoch_length` here — leaving it unset lets it fall back to the default and keeps the genesis hash consistent: |
| 72 | + |
| 73 | +```toml |
| 74 | +[params] |
| 75 | +cellbase_maturity = 0 |
| 76 | +permanent_difficulty_in_dummy = true |
| 77 | + |
| 78 | +[pow] |
| 79 | +func = "Dummy" |
| 80 | +``` |
| 81 | + |
| 82 | +- `cellbase_maturity = 0` makes locally mined cellbase outputs immediately spendable, which is convenient for development. |
| 83 | +- `permanent_difficulty_in_dummy = true` keeps the difficulty constant when running with `Dummy` PoW. Its default is `false`, which would let difficulty be recalculated from the dummy block timestamps and swing wildly once you start mining locally; the bundled `resource/specs/dev.toml` therefore enables it by default and the same is recommended here. |
| 84 | + |
| 85 | +## 5. First Run Requires Spec-Check Flags |
| 86 | + |
| 87 | +The copied database still records the original chain spec hash, so the first startup must include: |
| 88 | + |
| 89 | +```bash |
| 90 | +ckb run --skip-spec-check --overwrite-spec |
| 91 | +``` |
| 92 | + |
| 93 | +After the first successful run, `ckb run` can be used normally. |
| 94 | + |
| 95 | +## Troubleshooting |
| 96 | + |
| 97 | +If you see a log like `init_snapshot Spec(GenesisMismatch(...))`, the running spec and database spec do not match. Ensure: |
| 98 | + |
| 99 | +1. You imported the correct source chain spec. |
| 100 | +2. The first run uses `--skip-spec-check --overwrite-spec`. |
| 101 | +3. You are operating in the copied data directory, not the original one. |
0 commit comments