@bsv/wallet-toolbox
Version:
BRC100 conforming wallet, wallet storage and wallet signer components
255 lines • 12.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const knex_1 = require("knex");
const ChaintracksStorageKnex_1 = require("../../Storage/ChaintracksStorageKnex");
const blockHeaderUtilities_1 = require("../blockHeaderUtilities");
const BulkFileDataManager_1 = require("../BulkFileDataManager");
const ChaintracksFs_1 = require("../ChaintracksFs");
const LocalCdnServer_1 = require("../../__tests/LocalCdnServer");
const runSlowTests = false;
describe('BulkFileDataManager tests', () => {
jest.setTimeout(99999999);
const chain = 'main';
const fs = ChaintracksFs_1.ChaintracksFs;
const rootFolder = './src/services/chaintracker/chaintracks/__tests/data';
let headers300_399 = [];
let headers400_499 = [];
let server349;
let server379;
let server399;
let server402;
let server499;
beforeAll(async () => {
const data300_399 = await ChaintracksFs_1.ChaintracksFs.readFile(fs.pathJoin(rootFolder, 'cdnTest499/mainNet_3.headers'));
const data400_499 = await ChaintracksFs_1.ChaintracksFs.readFile(fs.pathJoin(rootFolder, 'cdnTest499/mainNet_4.headers'));
headers300_399 = (0, blockHeaderUtilities_1.deserializeBlockHeaders)(300, data300_399);
headers400_499 = (0, blockHeaderUtilities_1.deserializeBlockHeaders)(400, data400_499);
// Start the local CDN servers
server349 = new LocalCdnServer_1.LocalCdnServer(8349, fs.pathJoin(rootFolder, 'cdnTest349'));
await server349.start();
server379 = new LocalCdnServer_1.LocalCdnServer(8379, fs.pathJoin(rootFolder, 'cdnTest379'));
await server379.start();
server399 = new LocalCdnServer_1.LocalCdnServer(8399, fs.pathJoin(rootFolder, 'cdnTest399'));
await server399.start();
server402 = new LocalCdnServer_1.LocalCdnServer(8402, fs.pathJoin(rootFolder, 'cdnTest402'));
await server402.start();
server499 = new LocalCdnServer_1.LocalCdnServer(8499, fs.pathJoin(rootFolder, 'cdnTest499'));
await server499.start();
});
afterAll(async () => {
if (server349) {
await server349.stop();
}
if (server379) {
await server379.stop();
}
if (server399) {
await server399.stop();
}
if (server402) {
await server402.stop();
}
if (server499) {
await server499.stop();
}
});
async function test0Body(manager) {
// Verify the default options and minimum expected files from default CDN
expect(manager.chain).toBe(chain);
expect(manager.maxPerFile).toBe(100000);
expect(manager.maxRetained).toBe(2);
expect(manager.fromKnownSourceUrl).toBe('https://cdn.projectbabbage.com/blockheaders');
const files = await manager.getBulkFiles();
expect(files.length).toBeGreaterThan(7);
const range = await manager.getHeightRange();
expect(range.minHeight).toBe(0);
expect(range.maxHeight).toBeGreaterThan(800000);
}
test('0 default options CDN files', async () => {
const options = BulkFileDataManager_1.BulkFileDataManager.createDefaultOptions(chain);
const manager = new BulkFileDataManager_1.BulkFileDataManager(options);
await test0Body(manager);
});
test('0a default options CDN files noDropAll', async () => {
if (!runSlowTests)
return;
const options = BulkFileDataManager_1.BulkFileDataManager.createDefaultOptions(chain);
const manager = new BulkFileDataManager_1.BulkFileDataManager(options);
const storage = await setupStorageKnex(manager, `BulkFileDataManager.test_0a`, false);
await test0Body(manager);
await storage.destroy();
});
test('0b default options CDN files dropAll', async () => {
if (!runSlowTests)
return;
const options = BulkFileDataManager_1.BulkFileDataManager.createDefaultOptions(chain);
const manager = new BulkFileDataManager_1.BulkFileDataManager(options);
const storage = await setupStorageKnex(manager, `BulkFileDataManager.test_0b`, true);
await test0Body(manager);
await storage.destroy();
});
async function test1Body(manager, minCount) {
// Verify header retrieval from different heights and data caching
expect(countDatas(manager)).toBe(minCount);
let h0 = await manager.findHeaderForHeightOrUndefined(0);
expect(h0 === null || h0 === void 0 ? void 0 : h0.hash).toBe('000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f');
expect(countDatas(manager)).toBe(minCount === 0 ? 1 : minCount);
const h101010 = await manager.findHeaderForHeightOrUndefined(101010);
expect(h101010 === null || h101010 === void 0 ? void 0 : h101010.hash).toBe('000000000001af33247fff33aae7c31baee4148d5a189e7353bf13bcee618202');
expect(countDatas(manager)).toBe(2);
h0 = await manager.findHeaderForHeightOrUndefined(0);
expect(h0 === null || h0 === void 0 ? void 0 : h0.hash).toBe('000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f');
expect(countDatas(manager)).toBe(2);
const h202020 = await manager.findHeaderForHeightOrUndefined(202020);
expect(h202020 === null || h202020 === void 0 ? void 0 : h202020.hash).toBe('00000000000003a40858736f3788edcbca3aa89ac5723a8c6b42f0227084f949');
expect(countDatas(manager)).toBe(2);
const h303030 = await manager.findHeaderForHeightOrUndefined(303030);
expect(h303030 === null || h303030 === void 0 ? void 0 : h303030.hash).toBe('00000000000000002f66589be500afbf212eabf7b10e12fe4639684df808c83b');
expect(countDatas(manager)).toBe(2);
h0 = await manager.findHeaderForHeightOrUndefined(0);
expect(h0 === null || h0 === void 0 ? void 0 : h0.hash).toBe('000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f');
expect(countDatas(manager)).toBe(2);
const h808080 = await manager.findHeaderForHeightOrUndefined(808080);
expect(h808080 === null || h808080 === void 0 ? void 0 : h808080.hash).toBe('00000000000000000a7287950fae52dac3098ba43011fd1e1315974a419b0110');
expect(countDatas(manager)).toBe(2);
// Verify a height request that is out of range returns undefined and does not affect cached data
const h909090 = await manager.findHeaderForHeightOrUndefined(909090);
expect(h909090 === null || h909090 === void 0 ? void 0 : h909090.hash).toBeUndefined();
expect(countDatas(manager)).toBe(2);
// Verify retrieval from cached data.
h0 = await manager.findHeaderForHeightOrUndefined(0);
expect(h0 === null || h0 === void 0 ? void 0 : h0.hash).toBe('000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f');
}
test('1 headers from heights maxRetained 2', async () => {
if (!runSlowTests)
return;
const options = BulkFileDataManager_1.BulkFileDataManager.createDefaultOptions(chain);
const manager = new BulkFileDataManager_1.BulkFileDataManager(options);
await test1Body(manager, 0);
});
test('1a headers from heights maxRetained 2', async () => {
if (!runSlowTests)
return;
const options = BulkFileDataManager_1.BulkFileDataManager.createDefaultOptions(chain);
const manager = new BulkFileDataManager_1.BulkFileDataManager(options);
const storage = await setupStorageKnex(manager, `BulkFileDataManager.test_1a`, true);
await test1Body(manager, 2);
await storage.destroy();
});
test('2 ReValidate', async () => {
if (!runSlowTests)
return;
const options = BulkFileDataManager_1.BulkFileDataManager.createDefaultOptions(chain);
const manager = new BulkFileDataManager_1.BulkFileDataManager(options);
// Verify full data re-validation
await manager.ReValidate();
expect(countDatas(manager)).toBe(2);
});
test('3 exportHeadersToFs', async () => {
if (!runSlowTests)
return;
const options = BulkFileDataManager_1.BulkFileDataManager.createDefaultOptions(chain);
const manager = new BulkFileDataManager_1.BulkFileDataManager(options);
for (const i of [349, 379, 399, 402, 499]) {
const folder = fs.pathJoin(rootFolder, `cdnTest${i}`);
await manager.exportHeadersToFs(ChaintracksFs_1.ChaintracksFs, 100, folder, `http://localhost:8${i}/blockheaders`, i);
}
});
async function test4Body(manager, maxCount) {
expect(countDatas(manager)).toBe(2);
const range = await manager.getHeightRange();
expect(range.maxHeight).toBe(349);
await manager.mergeIncrementalBlockHeaders(headers300_399.slice(50));
await manager.ReValidate();
expect(countDatas(manager)).toBe(maxCount);
await manager.mergeIncrementalBlockHeaders(headers400_499);
await manager.ReValidate();
expect(countDatas(manager)).toBe(maxCount);
await updateFromLocalServer(manager, server379);
await manager.ReValidate();
expect(countDatas(manager)).toBe(maxCount);
await updateFromLocalServer(manager, server399);
await manager.ReValidate();
expect(countDatas(manager)).toBe(maxCount);
await updateFromLocalServer(manager, server402);
await manager.ReValidate();
expect(countDatas(manager)).toBe(maxCount);
await updateFromLocalServer(manager, server499);
await manager.ReValidate();
expect(countDatas(manager)).toBe(2);
}
test('4 add two incremental chunks overwrite by CDN', async () => {
const manager = await setupManagerOnLocalServer(server349);
await test4Body(manager, 3);
});
test('4a add two incremental chunks overwrite by CDN', async () => {
const manager = await setupManagerOnLocalServer(server349);
const storage = await setupStorageKnex(manager, `BulkFileDataManager.test_4a`, true);
await test4Body(manager, 2);
await storage.destroy();
});
async function test5Body(manager, maxCount) {
expect(countDatas(manager)).toBe(2);
await updateFromLocalServer(manager, server379);
await manager.ReValidate();
expect(countDatas(manager)).toBe(2);
await manager.mergeIncrementalBlockHeaders(headers300_399.slice(50));
await manager.ReValidate();
expect(countDatas(manager)).toBe(maxCount);
await updateFromLocalServer(manager, server499);
await manager.ReValidate();
expect(countDatas(manager)).toBe(2);
await manager.mergeIncrementalBlockHeaders(headers400_499);
await manager.ReValidate();
expect(countDatas(manager)).toBe(2);
}
test('5 add CDN incremental CDN incremental', async () => {
const manager = await setupManagerOnLocalServer(server349);
await test5Body(manager, 3);
});
test('5a add CDN incremental CDN incremental', async () => {
const manager = await setupManagerOnLocalServer(server349);
const storage = await setupStorageKnex(manager, `BulkFileDataManager.test_5a`, true);
await test5Body(manager, 2);
await storage.destroy();
});
async function setupStorageKnex(manager, filename, deleteSqliteFile) {
const path = fs.pathJoin(rootFolder, `${filename}.sqlite`);
const localSqlite = {
client: 'better-sqlite3',
connection: { filename: path },
useNullAsDefault: true
};
if (deleteSqliteFile) {
const fs = ChaintracksFs_1.ChaintracksFs;
try {
await fs.delete(path);
}
catch (_a) { }
}
const knexOptions = ChaintracksStorageKnex_1.ChaintracksStorageKnex.createStorageKnexOptions(chain, (0, knex_1.knex)(localSqlite));
knexOptions.bulkFileDataManager = manager;
const storage = new ChaintracksStorageKnex_1.ChaintracksStorageKnex(knexOptions);
await storage.makeAvailable();
return storage;
}
async function setupManagerOnLocalServer(server) {
const options = BulkFileDataManager_1.BulkFileDataManager.createDefaultOptions(chain);
options.fromKnownSourceUrl = undefined;
const manager = new BulkFileDataManager_1.BulkFileDataManager(options);
await updateFromLocalServer(manager, server);
return manager;
}
});
async function updateFromLocalServer(manager, server) {
await manager.updateFromUrl(`http://localhost:${server.port}/blockheaders`);
}
function countDatas(manager) {
let count = 0;
for (const file of manager['bfds']) {
if (file.data)
count += 1;
}
return count;
}
//# sourceMappingURL=BulkFileDataManager.test.js.map