Skip to content

Commit b2fee48

Browse files
authored
fix(core-database): fix delete blocks (#3814)
1 parent 4e68514 commit b2fee48

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

__tests__/functional/core-database/repositories/block-repository.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,31 @@ describe("BlockRepository.deleteBlocks", () => {
226226
const promise = blockRepository.deleteBlocks([block2.data]);
227227
await expect(promise).rejects.toThrow("Removing blocks from the middle");
228228
});
229+
230+
it("should throw when deleting non-continuous chunk (order in reverse)", async () => {
231+
const blockRepository = getCustomRepository(BlockRepository);
232+
await blockRepository.saveBlocks([block1, block2, block3]);
233+
const promise = blockRepository.deleteBlocks([block3.data, block2.data, block1.data]);
234+
await expect(promise).rejects.toThrow("Blocks chunk to delete isn't continuous");
235+
});
236+
237+
it("should throw when deleting non-continuous chunk (missing block)", async () => {
238+
const blockRepository = getCustomRepository(BlockRepository);
239+
await blockRepository.saveBlocks([block1, block2, block3]);
240+
const promise = blockRepository.deleteBlocks([block3.data, block1.data]);
241+
await expect(promise).rejects.toThrow("Blocks chunk to delete isn't continuous");
242+
});
243+
244+
it("should throw when deleted count doesn't match expected", async () => {
245+
const blockRepository = getCustomRepository(BlockRepository);
246+
await blockRepository.saveBlocks([block1, block2, block3]);
247+
const promise = blockRepository.deleteBlocks([
248+
block1.data,
249+
block2.data,
250+
{ ...block3.data, id: "non-existing" },
251+
]);
252+
await expect(promise).rejects.toThrow("Failed to delete all blocks from database");
253+
});
229254
});
230255

231256
describe("BlockRepository.findManyByExpression", () => {

packages/core-blockchain/src/blockchain.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ export class Blockchain implements Contracts.Blockchain.Blockchain {
330330

331331
await __removeBlocks(nblocks);
332332

333-
await this.blockRepository.deleteBlocks(removedBlocks);
333+
await this.blockRepository.deleteBlocks(removedBlocks.reverse());
334334

335335
if (this.transactionPool) {
336336
this.transactionPool.readdTransactions(removedTransactions.reverse());

packages/core-database/src/repositories/block-repository.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,14 @@ export class BlockRepository extends AbstractRepository<Block> {
181181
}
182182

183183
public async deleteBlocks(blocks: Interfaces.IBlockData[]): Promise<void> {
184+
const continuousChunk = blocks.every((block, i, arr) => {
185+
return i === 0 ? true : block.height - arr[i - 1].height === 1;
186+
});
187+
188+
if (!continuousChunk) {
189+
throw new Error("Blocks chunk to delete isn't continuous");
190+
}
191+
184192
return this.manager.transaction(async (manager) => {
185193
const lastBlockHeight: number = blocks[blocks.length - 1].height;
186194
const targetBlockHeight: number = blocks[0].height - 1;
@@ -206,13 +214,17 @@ export class BlockRepository extends AbstractRepository<Block> {
206214
.where("block_id IN (:...blockIds)", { blockIds })
207215
.execute();
208216

209-
await manager
217+
const deleteBlocksResult = await manager
210218
.createQueryBuilder()
211219
.delete()
212220
.from(Block)
213221
.where("id IN (:...blockIds)", { blockIds })
214222
.execute();
215223

224+
if (deleteBlocksResult.affected !== blockIds.length) {
225+
throw new Error("Failed to delete all blocks from database");
226+
}
227+
216228
await manager
217229
.createQueryBuilder()
218230
.delete()

0 commit comments

Comments
 (0)