Skip to content

Commit

Permalink
fix(ref-imp): error thrown in blockchain time refresh can crash core
Browse files Browse the repository at this point in the history
  • Loading branch information
thehenrytsai authored Feb 18, 2021
1 parent 4c4014a commit 6c20245
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 8 deletions.
15 changes: 13 additions & 2 deletions lib/core/Blockchain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,21 @@ export default class Blockchain implements IBlockchain {
}

/**
* The function that starts periodically anchoring operation batches to blockchain.
* Starts periodically refreshing the cached blockchain time.
*/
public startPeriodicCachedBlockchainTimeRefresh () {
setInterval(async () => this.getLatestTime(), Blockchain.cachedBlockchainTimeRefreshInSeconds * 1000);
this.periodicallyRefreshCachedBlockchainTime();
}

private async periodicallyRefreshCachedBlockchainTime () {
try {
await this.getLatestTime();
} catch (error) {
Logger.error(`Encountered error fetching latest blockchain time: ${error}`);
} finally {
Logger.info(`Waiting for ${Blockchain.cachedBlockchainTimeRefreshInSeconds} seconds before refresh blockchain time again.`);
setTimeout(async () => this.periodicallyRefreshCachedBlockchainTime(), Blockchain.cachedBlockchainTimeRefreshInSeconds * 1000);
}
}

public async write (anchorString: string, minimumFee: number): Promise<void> {
Expand Down
37 changes: 31 additions & 6 deletions tests/core/Blockchain.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ import ValueTimeLockModel from '../../lib/common/models/ValueTimeLockModel';

describe('Blockchain', async () => {
describe('startPeriodicCachedBlockchainTimeRefresh', () => {
it('should call periodicallyRefreshCachedBlockchainTime().', async () => {
const blockchainClient = new Blockchain('Unused URI');
const periodicallyRefreshCachedBlockchainTimeSpy =
spyOn(blockchainClient as any, 'periodicallyRefreshCachedBlockchainTime');

blockchainClient.startPeriodicCachedBlockchainTimeRefresh();

expect(periodicallyRefreshCachedBlockchainTimeSpy).toHaveBeenCalled();
});
});

describe('periodicallyRefreshCachedBlockchainTime', () => {
beforeEach(() => {
// Freeze time
jasmine.clock().install();
Expand All @@ -22,17 +34,30 @@ describe('Blockchain', async () => {
jasmine.clock().uninstall();
});

it('should setInterval correctly', () => {
it('should trigger another blockchain time refresh.', async () => {
const blockchainClient = new Blockchain('Unused URI');
const getLatestTimeSpy = spyOn(blockchainClient, 'getLatestTime').and.returnValue({} as any);

blockchainClient.startPeriodicCachedBlockchainTimeRefresh();
// Time is frozen so it should not have have been called.
expect(getLatestTimeSpy).not.toHaveBeenCalled();
// Time is advanced by (refresh time + 1), so the getLatestTimeSpy should be called once.
jasmine.clock().tick(Blockchain.cachedBlockchainTimeRefreshInSeconds * 1000 + 1);

await (blockchainClient as any).periodicallyRefreshCachedBlockchainTime();
expect(getLatestTimeSpy).toHaveBeenCalledTimes(1);

// Time is advanced by refresh time, so the getLatestTimeSpy should be called again.
jasmine.clock().tick(Blockchain.cachedBlockchainTimeRefreshInSeconds * 1000);
expect(getLatestTimeSpy).toHaveBeenCalledTimes(2);
});

it('should trigger another blockchain time refresh even if exception is thrown.', async () => {
const blockchainClient = new Blockchain('Unused URI');
const getLatestTimeSpy = spyOn(blockchainClient, 'getLatestTime').and.throwError('any error');

expect(getLatestTimeSpy).not.toHaveBeenCalled();

await (blockchainClient as any).periodicallyRefreshCachedBlockchainTime();
expect(getLatestTimeSpy).toHaveBeenCalledTimes(1);
// Time is advanced by (refresh time) again, so getLatestTimeSpy should be called another time.

// Time is advanced by refresh time, so the getLatestTimeSpy should be called again.
jasmine.clock().tick(Blockchain.cachedBlockchainTimeRefreshInSeconds * 1000);
expect(getLatestTimeSpy).toHaveBeenCalledTimes(2);
});
Expand Down

0 comments on commit 6c20245

Please sign in to comment.