## Summary

In every snapshot restore and crash-resume test, the PBSS `diskRoot` remains stuck at its genesis value. The node cannot find a valid checkpoint snapshot during walk-back, causing:
- "snapshot walk-back exceeded safe limit without finding a checkpoint snapshot"
- "Failed to load snapshot: head doesn't match snapshot"
- Sync resume failure after restart

## Test Evidence

### Crash-Resume Test (v39, prod @ ~32.2M)
| Metric | Value |
|--------|-------|
| Pre-crash block | 32,214,369 |
| Post-crash block | 32,214,625 |
| Delta | +256 blocks (no rewind!) |
| Last P1 checkpoint | 32,213,700 |
| Peers after restart | 1 |

Log: `ERROR snapshot walk-back exceeded safe limit without finding a checkpoint snapshot`

### Cold Snapshot Restore Test (v39, prod @ 4.9M)
| Metric | Value |
|--------|-------|
| Snapshot block | 4,905,223 |
| Restore block | 4,905,223 ✅ |
| diskRoot | `8e3faa..1c160f` ❌ |
| headerRoot | `1c31bc..e7155d` ❌ |
| Snapshot walk-back | `Exceeded 2M limit` ❌ |
| Sync resume | FAILED ❌ |

## Root Cause Analysis (Suspected)

In `core/blockchain.go` `writeBlockWithState()` (line ~1856):

```go
if bc.triedb.Scheme() == rawdb.PathScheme {
    return nil  // <-- returns early, NEVER calls bc.triedb.Commit()
}
```

For PBSS (path scheme), the function returns early **before** calling `bc.triedb.Commit(root)`. This is correct in upstream geth because pathdb's internal buffer flushing is supposed to handle disk persistence automatically.

However, the disk layer root (`DiskLayerRoot()`) — which is read from `rawdb.ReadAccountTrieNode(db.diskdb, nil)` at startup — appears to **never advance** from its genesis value. This suggests the pathdb buffer flush is not actually writing the updated root node to disk, or the diff-to-disk flattening is not occurring.

Additionally, PR #350 added a P1 checkpoint commit for bulk sync mode:
```go
if XdcBulkSyncMode.Load() && bc.chainConfig.ChainID != nil {
    if (chainID == 50 || chainID == 51) && current%900 == 0 {
        bc.triedb.Commit(commitRoot, false)
    }
}
```

This only fires during **bulk sync**. For a node that has already synced past the checkpoint and is running normally, or for a restored node that starts in non-bulk mode, **no explicit trie commit ever happens**.

## Code Paths

1. `core/blockchain.go:writeBlockWithState()` — early return for PBSS
2. `triedb/pathdb/buffer.go:flush()` — writes `rawdb.WriteAccountTrieNode(batch, []byte(path), n.Blob)` including root node
3. `triedb/pathdb/disklayer.go:commit()` — merges diff layer into buffer, flushes if `combined.full() || force || flush`
4. `triedb/pathdb/journal.go:loadLayers()` — reads `rawdb.ReadAccountTrieNode(db.diskdb, nil)` to get diskRoot
5. `core/blockchain.go` unclean shutdown recovery — walks back from head looking for block matching `diskRoot`

## Impact

- **Crash-resume**: Node cannot resume sync after unclean shutdown because diskRoot doesn't match any recent block
- **Snapshot restore**: Same failure mode — restored node cannot find its own state
- **Production risk**: Any restart (crash, upgrade, migration) leaves the node in a broken state

## Related

- PR #350 (v38 snapshot restore fixes)
- Issues #308, #311, #312
- Issue #60 (PBSS unclean shutdown recovery)
- Issue #190 (v37 trie corruption)

## Required Fix

1. Identify why `rawdb.ReadAccountTrieNode(db.diskdb, nil)` returns the genesis root after millions of blocks
2. Ensure the pathdb disk layer root is actually persisted during normal operation
3. Verify the fix works for both crash-resume and snapshot restore scenarios
