# XDC Trusted Checkpoint Sync

## Overview

The `--syncfromblock` flag enables fast sync from a trusted checkpoint block, skipping historical body/receipt download while maintaining full header chain validation. This is useful for:

- Syncing XDC Apothem nodes from the XDPoS V2 switch block (56,828,700)
- Reducing sync time by skipping pre-V2 block bodies and receipts
- Validating the chain against hardcoded trusted checkpoints

## How It Works

### Nethermind-Style Approach

1. **Download ALL headers from genesis** — maintains full chain continuity and parent validation
2. **Only skip bodies/receipts before cutoff** — saves storage, not bandwidth
3. **Validate checkpoint block hash** — ensures chain integrity at the cutoff point

### Architecture

```
Genesis → ... → Checkpoint (56M) → ... → V2 Switch (56,828,700) → ... → Head
  ↓              ↓                      ↓
Headers      Headers + Checkpoint    Headers + Bodies + Receipts
(validate)   (trusted anchor)        (full validation)
```

## Usage

### Docker

```bash
# Create data directory
mkdir -p /mnt/data/xdc-apothem-checkpoint

# Run with checkpoint sync
docker run -d --name xdc-apothem-checkpoint \
  --restart unless-stopped \
  -v /mnt/data/xdc-apothem-checkpoint:/work/xdcchain \
  -p 30303:30303 \
  -p 8545:8545 \
  anilchinchawale/gp5-xdc:v110-checkpoints \
  --datadir /work/xdcchain \
  --networkid 51 \
  --syncmode full \
  --gcmode archive \
  --apothem \
  --syncfromblock 56000000 \
  --bootnodes "enode://..."
```

### Native Binary (No Docker)

```bash
# Build or download binary
go build -o /usr/local/bin/XDC ./cmd/geth

# Create data directory
mkdir -p /mnt/data/xdc-apothem-checkpoint

# Run with checkpoint sync
/usr/local/bin/XDC \
  --datadir /mnt/data/xdc-apothem-checkpoint \
  --networkid 51 \
  --syncmode full \
  --gcmode archive \
  --apothem \
  --syncfromblock 56000000 \
  --port 30303 \
  --bootnodes "enode://..."
```

### Systemd Service

```ini
[Unit]
Description=XDC Apothem Checkpoint Sync
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/XDC \
  --datadir /mnt/data/xdc-apothem-checkpoint \
  --networkid 51 \
  --syncmode full \
  --gcmode archive \
  --apothem \
  --syncfromblock 56000000 \
  --port 30303 \
  --bootnodes "enode://a8a3ab01e6235fc4e62f121201d8bf8c18d36c0e052968648277a6896de0cb89e1ad300f38eef08d09fc58d2a36b765e372b68bb043af736f63b133a3afba942@167.235.13.113:30326" \
  --ethstats "node-name:xdc_openscan_stats_2026@stats.xdcindia.com:443"
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
```

Enable and start:
```bash
systemctl daemon-reload
systemctl enable xdc-apothem-checkpoint
systemctl start xdc-apothem-checkpoint
journalctl -u xdc-apothem-checkpoint -f
```

## Configuration

### Trusted Checkpoints

Checkpoints are configured in the genesis config (`TrustedSyncCheckpoints` array):

```go
TrustedSyncCheckpoints: []*params.TrustedSyncCheckpoint{
    {
        Number: 50000000,
        Hash:   common.HexToHash("0xaa1490d9dfca4e1da57be6a3701f0d8595d82e83eb00c6863f1092aca0df1a59"),
    },
    {
        Number: 55000000,
        Hash:   common.HexToHash("0x8d46eed913abf4942eb6154512bee3b46ec8605e2499ec68a6177dd4fa6d5c5f"),
    },
    {
        Number: 56000000,
        Hash:   common.HexToHash("0x631c8d6db706b2b3380c9c38f649eeb5db0c5c457b85a1d43c3252a1b0ba8bd3"),
    },
    {
        Number: 56828700,
        Hash:   common.HexToHash("0x5ac967a20d0826edb4e50d0d6ceb6c2f3ae3356b43b28b307756e42e0bd35905"),
    },
}
```

### Flags

| Flag | Description | Default |
|------|-------------|---------|
| `--syncfromblock` | Block number to start syncing from (skips bodies/receipts before this) | 0 (disabled) |
| `--syncmode` | Sync mode: `full` or `snap` | `snap` |
| `--gcmode` | Garbage collection mode: `archive` or `full` | `full` |

## Performance

### Sync Speed Comparison

| Connection Type | Headers/sec | ETA to 56M |
|----------------|-------------|-----------|
| Single peer (192 headers/response) | ~960 | ~13.6 hours |
| Direct v2.6.8 (768 headers/response) | ~5,453 | ~2.8 hours |
| Multiple peers (parallel) | ~3,000-6,000 | ~3-5 hours |

### Factors Affecting Speed

1. **Peer header batch size** — v2.6.8 sends 768 headers, GP5 sends 192
2. **Network latency** — local connections are faster
3. **Peer count** — more peers = parallel header download
4. **Disk I/O** — header insertion is write-heavy

## Monitoring

### Check Sync Progress

```bash
# Docker
docker logs xdc-apothem-checkpoint | grep -E "received headers|parallel header progress"

# Native / Systemd
journalctl -u xdc-apothem-checkpoint | grep -E "received headers|parallel header progress"
```

### Expected Log Output

```
INFO [05-01|10:08:48.922] XDC sync: checkpoint anchor inserted     number=56,000,000 hash=0x631c8d...
INFO [05-01|10:08:48.922] XDC sync: checkpoint anchor installed    checkpoint=56,000,000 mode=full
INFO [05-01|10:09:00.974] XDC sync: received headers               count=192 first=78721
DEBUG[05-01|10:09:00.974] Inserted headers before cutoff           number=78720  hash=...
```

### Check for Errors

```bash
# Look for these error patterns (should NOT appear):
# - "Error: unknown ancestor"
# - "synchronisation failed"
# - "errInvalidChain"

docker logs xdc-apothem-checkpoint | grep -E "Error|error|failed"
```

## Troubleshooting

### "Unknown Ancestor" Error

**Cause**: The checkpoint block's parent is not in the database.

**Solution**: Ensure headers are downloading from genesis (not from the cutoff). The v110-checkpoints image fixes this by always downloading headers from origin+1.

### Slow Sync

**Cause**: Limited peers or low header batch size.

**Solutions**:
1. Connect to v2.6.8 nodes (send 768 headers/response)
2. Add more bootnodes
3. Check peer count: `admin.peers.length` in console

### Checkpoint Validation Fails

**Cause**: The downloaded checkpoint block hash doesn't match the trusted checkpoint.

**Solution**: Verify the checkpoint hash in the genesis config matches the actual chain.

## Implementation Details

### Code Changes

The checkpoint sync feature involves these files:

- `eth/downloader/downloader.go` — Queue preparation and fetcher setup
- `eth/downloader/downloader_xdc.go` — XDC-specific sync logic, checkpoint anchor insertion
- `eth/downloader/downloader_xdc_parallel.go` — Parallel header download
- `core/blockchain.go` — `InsertHeadersBeforeCutoff` function

### Key Logic

1. **Checkpoint Anchor Insertion** (`insertCheckpointAnchor`):
   - Fetches the checkpoint block from a peer
   - Inserts it into the database as a trusted block
   - Does NOT advance origin (headers still download from genesis)

2. **Header Processing** (`InsertHeadersBeforeCutoff`):
   - Checks if the first header in a batch matches any checkpoint
   - If match: skips full validation (trusted)
   - If no match: validates header chain normally
   - Allows gaps for sync-from-block

3. **Body/Receipt Skipping**:
   - `chainOffset` is set to `syncfromblock` value
   - Body and receipt fetchers start from `chainOffset`
   - Headers are still downloaded from genesis

## Version History

| Version | Changes |
|---------|---------|
| v107 | Initial checkpoint sync (broken — advanced origin) |
| v110-checkpoints | Fixed: download all headers from genesis, skip only bodies/receipts |

## References

- GitHub Issue: [#456](https://github.com/XDCIndia/go-ethereum/issues/456)
- Branch: `feat/trusted-checkpoint-sync`
- Commit: `3d4ce65bd`
