Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Commit

Permalink
Fix backup feature to use correct fs method (#8922)
Browse files Browse the repository at this point in the history
* 🐛 Fix backup feature to use correct fs method

* 💅 Fix format

* Update framework/src/node/node.ts

Co-authored-by: Boban Milošević <milosevic.boban@gmail.com>

---------

Co-authored-by: Boban Milošević <milosevic.boban@gmail.com>
  • Loading branch information
shuse2 and bobanm authored Sep 4, 2023
1 parent ffc5406 commit a982414
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 13 deletions.
20 changes: 7 additions & 13 deletions framework/src/node/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import { EVENT_SYNCHRONIZER_SYNC_REQUIRED } from './synchronizer/base_synchroniz
import { Network } from './network';
import { BaseAsset, BaseModule } from '../modules';
import { Bus } from '../controller/bus';
import { backupDatabase } from './utils/backup';

const forgeInterval = 1000;
const { EVENT_NEW_BLOCK, EVENT_DELETE_BLOCK, EVENT_VALIDATORS_CHANGED } = chainEvents;
Expand Down Expand Up @@ -733,19 +734,12 @@ export class Node {
this._options.backup.height > 0 &&
this._options.backup.height === block.header.height
) {
const backupPath = path.resolve(this._dataPath, 'backup');
// if backup already exist, it should remove the directory and create a new checkpoint
if (fs.existsSync(backupPath)) {
fs.removeSync(backupPath);
}
this._blockchainDB
.checkpoint(backupPath)
.catch(err =>
this._logger.fatal(
{ err: err as Error, height: this._options.backup.height, path: backupPath },
'Fail to create backup',
),
);
backupDatabase(this._dataPath, this._blockchainDB).catch(err =>
this._logger.fatal(
{ err: err as Error, heght: this._options.backup.height },
'Failed to create backup',
),
);
}

// Remove any transactions from the pool on new block
Expand Down
25 changes: 25 additions & 0 deletions framework/src/node/utils/backup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright © 2023 Lisk Foundation
*
* See the LICENSE file at the top-level directory of this distribution
* for licensing information.
*
* Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation,
* no part of this software, including this file, may be copied, modified,
* propagated, or distributed except according to the terms contained in the
* LICENSE file.
*
* Removal or modification of this copyright notice is prohibited.
*/
import * as path from 'path';
import * as fs from 'fs';
import { Database } from '@liskhq/lisk-db';

export const backupDatabase = async (dataPath: string, db: Database) => {
const backupPath = path.resolve(dataPath, 'backup');
// if backup already exist, it should remove the directory and create a new checkpoint
if (fs.existsSync(backupPath)) {
fs.rmSync(backupPath, { recursive: true, force: true });
}
await db.checkpoint(backupPath);
};
60 changes: 60 additions & 0 deletions framework/test/unit/node/utils/backup.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright © 2023 Lisk Foundation
*
* See the LICENSE file at the top-level directory of this distribution
* for licensing information.
*
* Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation,
* no part of this software, including this file, may be copied, modified,
* propagated, or distributed except according to the terms contained in the
* LICENSE file.
*
* Removal or modification of this copyright notice is prohibited.
*/

import * as os from 'os';
import * as path from 'path';
import * as fs from 'fs';
import { Database } from '@liskhq/lisk-db';
import { getRandomBytes } from '@liskhq/lisk-cryptography';
import { backupDatabase } from '../../../../src/node/utils/backup';

describe('backup', () => {
const getDataPath = (name: string) => path.join(os.tmpdir(), Date.now().toString(), name);

it('should create backup', async () => {
const dbName = 'db-1';
const dataPath = getDataPath(dbName);
const db = new Database(path.join(dataPath, dbName));
const key = getRandomBytes(10);
await db.set(key, getRandomBytes(20));

await backupDatabase(dataPath, db);

expect(fs.existsSync(path.join(dataPath, 'backup'))).toBeTrue();
db.close();
});

it('should remove old backup and create new one if exist', async () => {
const dbName = 'db-2';
const dataPath = getDataPath(dbName);
const db = new Database(path.join(dataPath, dbName));
const key = getRandomBytes(10);
await db.set(key, getRandomBytes(20));

await backupDatabase(dataPath, db);
const key2 = getRandomBytes(10);
await db.set(key2, getRandomBytes(20));

expect(fs.existsSync(path.join(dataPath, 'backup'))).toBeTrue();

await backupDatabase(dataPath, db);

expect(fs.existsSync(path.join(dataPath, 'backup'))).toBeTrue();
db.close();
const backupDB = new Database(path.join(dataPath, 'backup'));

await expect(backupDB.has(key2)).resolves.toBeTrue();
backupDB.close();
});
});

0 comments on commit a982414

Please sign in to comment.