Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions src/store/fileStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,21 @@ export class FileStore implements StorageAdapter {
}
}
out.sort((a, b) => a.cid - b.cid);
return out.length ? out : undefined;
// Deduplicate: the JSONL file may contain duplicate cid entries after a process
// restart re-syncs an overlapping range. Since getMerkleLeaf uses cid as an array
// index, duplicates shift all subsequent lookups and cause wrong leaf retrieval.
if (out.length > 0) {
const deduped: typeof out = [out[0]!];
for (let i = 1; i < out.length; i++) {
if (out[i]!.cid === deduped[deduped.length - 1]!.cid) {
deduped[deduped.length - 1] = out[i]!;
} else {
deduped.push(out[i]!);
}
}
return deduped;
}
return undefined;
Comment on lines +125 to +136

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The deduplication logic is correct, but it can be implemented more concisely using the reduce method. This would make the code more idiomatic and potentially easier to read for developers familiar with functional programming patterns.

Suggested change
if (out.length > 0) {
const deduped: typeof out = [out[0]!];
for (let i = 1; i < out.length; i++) {
if (out[i]!.cid === deduped[deduped.length - 1]!.cid) {
deduped[deduped.length - 1] = out[i]!;
} else {
deduped.push(out[i]!);
}
}
return deduped;
}
return undefined;
if (out.length === 0) {
return undefined;
}
return out.reduce((acc, current) => {
const last = acc[acc.length - 1];
if (last?.cid === current.cid) {
acc[acc.length - 1] = current;
} else {
acc.push(current);
}
return acc;
}, [] as typeof out);

} catch {
return undefined;
}
Expand All @@ -143,9 +157,12 @@ export class FileStore implements StorageAdapter {
const next = Number.isFinite(cid) ? Math.max(0, Math.floor(cid) + 1) : 0;
this.merkleNextCid.set(chainId, next);
return next;
} catch {
this.merkleNextCid.set(chainId, 0);
return 0;
} catch (err: unknown) {
if (err && typeof err === 'object' && 'code' in err && (err as { code: string }).code === 'ENOENT') {
this.merkleNextCid.set(chainId, 0);
return 0;
}
throw err;
}
}

Expand Down
Loading