Skip to content

Commit e459b2a

Browse files
authored
chore: Sanity check block number from archiver before returning it (#13631)
We have seen an archiver that stored blocks under the wrong block number, which caused errors in other components. This adds a sanity check before returning them.
1 parent 35dec90 commit e459b2a

File tree

3 files changed

+24
-7
lines changed

3 files changed

+24
-7
lines changed

yarn-project/archiver/src/archiver/kv_archiver_store/block_store.ts

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ export class BlockStore {
130130
* @returns The requested L2 blocks
131131
*/
132132
async *getBlocks(start: number, limit: number): AsyncIterableIterator<PublishedL2Block> {
133-
for await (const blockStorage of this.#blocks.valuesAsync(this.#computeBlockRange(start, limit))) {
134-
const block = await this.getBlockFromBlockStorage(blockStorage);
133+
for await (const [blockNumber, blockStorage] of this.#blocks.entriesAsync(this.#computeBlockRange(start, limit))) {
134+
const block = await this.getBlockFromBlockStorage(blockNumber, blockStorage);
135135
if (block) {
136136
yield block;
137137
}
@@ -148,7 +148,7 @@ export class BlockStore {
148148
if (!blockStorage || !blockStorage.header) {
149149
return Promise.resolve(undefined);
150150
}
151-
return this.getBlockFromBlockStorage(blockStorage);
151+
return this.getBlockFromBlockStorage(blockNumber, blockStorage);
152152
}
153153

154154
/**
@@ -158,12 +158,18 @@ export class BlockStore {
158158
* @returns The requested L2 block headers
159159
*/
160160
async *getBlockHeaders(start: number, limit: number): AsyncIterableIterator<BlockHeader> {
161-
for await (const blockStorage of this.#blocks.valuesAsync(this.#computeBlockRange(start, limit))) {
162-
yield BlockHeader.fromBuffer(blockStorage.header);
161+
for await (const [blockNumber, blockStorage] of this.#blocks.entriesAsync(this.#computeBlockRange(start, limit))) {
162+
const header = BlockHeader.fromBuffer(blockStorage.header);
163+
if (header.getBlockNumber() !== blockNumber) {
164+
throw new Error(
165+
`Block number mismatch when retrieving block header from archive (expected ${blockNumber} but got ${header.getBlockNumber()})`,
166+
);
167+
}
168+
yield header;
163169
}
164170
}
165171

166-
private async getBlockFromBlockStorage(blockStorage: BlockStorage) {
172+
private async getBlockFromBlockStorage(blockNumber: number, blockStorage: BlockStorage) {
167173
const header = BlockHeader.fromBuffer(blockStorage.header);
168174
const archive = AppendOnlyTreeSnapshot.fromBuffer(blockStorage.archive);
169175
const blockHash = (await header.hash()).toString();
@@ -174,6 +180,13 @@ export class BlockStore {
174180
}
175181
const body = Body.fromBuffer(blockBodyBuffer);
176182
const block = new L2Block(archive, header, body);
183+
if (block.number !== blockNumber) {
184+
throw new Error(
185+
`Block number mismatch when retrieving block from archive (expected ${blockNumber} but got ${
186+
block.number
187+
} with hash ${await block.hash()})`,
188+
);
189+
}
177190
const signatures = blockStorage.signatures.map(Signature.fromBuffer);
178191
return { block, l1: blockStorage.l1, signatures };
179192
}

yarn-project/stdlib/src/block/l2_block.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export class L2Block {
106106
}
107107

108108
get number(): number {
109-
return Number(this.header.globalVariables.blockNumber.toBigInt());
109+
return this.header.getBlockNumber();
110110
}
111111

112112
/**

yarn-project/stdlib/src/tx/block_header.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ export class BlockHeader {
6464
return this.globalVariables.slotNumber.toBigInt();
6565
}
6666

67+
getBlockNumber(): number {
68+
return Number(this.globalVariables.blockNumber.toBigInt());
69+
}
70+
6771
getSize() {
6872
return (
6973
this.lastArchive.getSize() +

0 commit comments

Comments
 (0)