Skip to content

Commit 643a113

Browse files
authored
fix: sort cell indices before calling recoverCellsAndKzgProofs (#8450)
For context please view https://discord.com/channels/593655374469660673/1229813597501395028/1419794786121945141 . The latest spec requires cell indices to be sorted in [`recover_cells_and_kzg_proofs `](https://github.com/jtraglia/consensus-specs/blob/340d23358a0cdb4f4b547226dadd36d1cf775f20/specs/fulu/polynomial-commitments-sampling.md?plain=1#L805) so we need to sort them before passing it to kzg.
1 parent 83de5b8 commit 643a113

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

packages/beacon-node/src/util/blobs.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,10 @@ export async function dataColumnMatrixRecovery(
8484
return Array.from(partialSidecars.values());
8585
}
8686

87-
const firstDataColumn = partialSidecars.values().next().value;
87+
// Sort data columns by index in ascending order before passing for kzg operations
88+
const partialSidecarsSorted = Array.from(partialSidecars.values()).sort((a, b) => a.index - b.index);
89+
90+
const firstDataColumn = partialSidecarsSorted[0];
8891
if (firstDataColumn == null) {
8992
// should not happen because we check the size of the cache before this
9093
throw new Error("No data column found in cache to recover from");
@@ -101,8 +104,8 @@ export async function dataColumnMatrixRecovery(
101104
blobProofs.map((_, blobIndex) => {
102105
const cellIndices: number[] = [];
103106
const cells: Uint8Array[] = [];
104-
for (const [columnIndex, dataColumn] of partialSidecars.entries()) {
105-
cellIndices.push(columnIndex);
107+
for (const dataColumn of partialSidecarsSorted) {
108+
cellIndices.push(dataColumn.index);
106109
cells.push(dataColumn.column[blobIndex]);
107110
}
108111
// recovered cells and proofs are of the same row/blob, their length should be NUMBER_OF_COLUMNS

packages/beacon-node/test/spec/general/kzg.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,11 @@ type RecoverCellsAndKzgProofsInput = {
169169
cells: string[];
170170
};
171171
function recoverCellsAndKzgProofs(input: RecoverCellsAndKzgProofsInput): [string[], string[]] | null {
172+
const isSorted = input.cell_indices.every((val, i, arr) => i === 0 || arr[i - 1] < val);
173+
// If cell indices are not in ascending order, they are deemed invalid and cannot pass it to kzg
174+
// Though in practice, we sort them before passing to kzg, here we follow the spec test case expectation
175+
// See https://github.com/ChainSafe/lodestar/pull/8450/files#r2372830108 for context
176+
if (!isSorted) return null;
172177
const cellIndices = input.cell_indices.map(BigInt);
173178
const cells = input.cells.map(fromHexString);
174179
try {

0 commit comments

Comments
 (0)