snapshot v3: fix numUtxos update seek offset corrupting numBlocks

The writer seek calculation (contentHashPos - sizeof(numUtxos)) was
correct for v1/v2. In v3 the layout inserted numBlocks between
numUtxos and numStakeSeen, so the seek landed on the numBlocks field
and the updated count was written there, corrupting both fields.

Fix: compute the offset relative to contentHashPos, skipping the
contentHash, numStakeSeen, and numBlocks fields inserted in v2/v3.
This commit is contained in:
Krystie
2026-07-01 11:25:31 -07:00
parent 41ba9f8bc9
commit 5c312bb7da
+10 -2
View File
@@ -213,9 +213,17 @@ bool DumpSnapshot(const fs::path& destPath,
// Update actual count (in case it changed during iteration) // Update actual count (in case it changed during iteration)
if (nWritten != numUtxos) { if (nWritten != numUtxos) {
numUtxos = nWritten; numUtxos = nWritten;
// Seek back and update numUtxos in header // Seek back and update numUtxos in header.
// Header layout (v3):
// magic(4) + version(4) + network(4) + height(4) + blockHash(32)
// + moneySupply(8) + numHeaders(4) + numUtxos(4)
// + numBlocks(4) + numStakeSeen(4) + contentHash(32)
// contentHashPos is the offset of contentHash. numUtxos is at
// contentHashPos - sizeof(contentHash) - sizeof(numStakeSeen)
// - sizeof(numBlocks) - sizeof(numUtxos).
long currentPos = ftell(file); long currentPos = ftell(file);
fseek(file, contentHashPos - sizeof(numUtxos), SEEK_SET); fseek(file, contentHashPos - sizeof(uint256) - sizeof(numStakeSeen)
- sizeof(numBlocks) - sizeof(numUtxos), SEEK_SET);
fwrite(&numUtxos, sizeof(numUtxos), 1, file); fwrite(&numUtxos, sizeof(numUtxos), 1, file);
fseek(file, currentPos, SEEK_SET); fseek(file, currentPos, SEEK_SET);
} }