Skip to content

Commit

Permalink
fix: Moves the LRUcache to Controller level (#1489)
Browse files Browse the repository at this point in the history
* Moves the LRUcache to Controller level

* fix cache key

* fix blocks extrinsics cachekey
  • Loading branch information
filvecchiato authored Sep 20, 2024
1 parent a5b8a36 commit 890c06b
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 127 deletions.
1 change: 1 addition & 0 deletions src/controllers/AbstractController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type SidecarRequestHandler =
*/
export default abstract class AbstractController<T extends AbstractService> {
private _router: Router = express.Router();

constructor(
protected api: ApiPromise,
private _path: string,
Expand Down
48 changes: 42 additions & 6 deletions src/controllers/blocks/BlocksController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type { ApiPromise } from '@polkadot/api';
import { isHex } from '@polkadot/util';
import { RequestHandler, Response } from 'express';
import { BadRequest } from 'http-errors';
import type { LRUCache } from 'lru-cache';
import type client from 'prom-client';

import { validateBoolean } from '../../middleware/validate';
Expand Down Expand Up @@ -102,16 +103,14 @@ import AbstractController from '../AbstractController';
* - `OnFinalize`: https://crates.parity.io/frame_support/traits/trait.OnFinalize.html
*/
export default class BlocksController extends AbstractController<BlocksService> {
private blockStore: LRUCache<string, IBlock>;
constructor(
api: ApiPromise,
private readonly options: ControllerOptions,
) {
super(
api,
'/blocks',
new BlocksService(api, options.minCalcFeeRuntime, options.blockStore, options.hasQueryFeeApi),
);
super(api, '/blocks', new BlocksService(api, options.minCalcFeeRuntime, options.hasQueryFeeApi));
this.initRoutes();
this.blockStore = options.blockStore;
}

protected initRoutes(): void {
Expand Down Expand Up @@ -205,10 +204,28 @@ export default class BlocksController extends AbstractController<BlocksService>
checkDecodedXcm: decodedXcmMsgsArg,
paraId: paraIdArg,
};
// Create a key for the cache that is a concatenation of the block hash and all the query params included in the request
const cacheKey =
hash.toString() +
Number(options.eventDocs) +
Number(options.extrinsicDocs) +
Number(options.checkFinalized) +
Number(options.noFees) +
Number(options.checkDecodedXcm) +
Number(options.paraId);

const isBlockCached = this.blockStore.get(cacheKey);

if (isBlockCached) {
BlocksController.sanitizedSend(res, isBlockCached);
return;
}

const historicApi = await this.api.at(hash);

const block = await this.service.fetchBlock(hash, historicApi, options);
this.blockStore.set(cacheKey, block);

BlocksController.sanitizedSend(res, block);

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
Expand Down Expand Up @@ -263,9 +280,28 @@ export default class BlocksController extends AbstractController<BlocksService>
paraId: paraIdArg,
};

// Create a key for the cache that is a concatenation of the block hash and all the query params included in the request

const cacheKey =
hash.toString() +
Number(options.eventDocs) +
Number(options.extrinsicDocs) +
Number(options.checkFinalized) +
Number(options.noFees) +
Number(options.checkDecodedXcm) +
Number(options.paraId);

const isBlockCached = this.blockStore.get(cacheKey);

if (isBlockCached) {
BlocksController.sanitizedSend(res, isBlockCached);
return;
}
// HistoricApi to fetch any historic information that doesnt include the current runtime
const historicApi = await this.api.at(hash);
const block = await this.service.fetchBlock(hash, historicApi, options);

this.blockStore.set(cacheKey, block);
// We set the last param to true because we haven't queried the finalizedHead
BlocksController.sanitizedSend(res, block);
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
Expand Down Expand Up @@ -348,7 +384,7 @@ export default class BlocksController extends AbstractController<BlocksService>
}

const blocks = (await Promise.all(blocksPromise)) as IBlock[];

blocksPromise.length = 0;
/**
* Sort blocks from least to greatest.
*/
Expand Down
21 changes: 19 additions & 2 deletions src/controllers/blocks/BlocksExtrinsicsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,24 @@

import type { ApiPromise } from '@polkadot/api';
import { RequestHandler } from 'express';
import { LRUCache } from 'lru-cache';
import { IBlock } from 'src/types/responses';

import { BlocksService } from '../../services';
import type { ControllerOptions } from '../../types/chains-config';
import type { INumberParam } from '../../types/requests';
import AbstractController from '../AbstractController';

export default class BlocksExtrinsicsController extends AbstractController<BlocksService> {
private blockStore: LRUCache<string, IBlock>;
constructor(api: ApiPromise, options: ControllerOptions) {
super(
api,
'/blocks/:blockId/extrinsics',
new BlocksService(api, options.minCalcFeeRuntime, options.blockStore, options.hasQueryFeeApi),
new BlocksService(api, options.minCalcFeeRuntime, options.hasQueryFeeApi),
);
this.initRoutes();
this.blockStore = options.blockStore;
}

protected initRoutes(): void {
Expand Down Expand Up @@ -62,10 +66,23 @@ export default class BlocksExtrinsicsController extends AbstractController<Block
paraId: undefined,
};

const cacheKey =
hash.toString() +
Number(options.eventDocs) +
Number(options.extrinsicDocs) +
Number(options.checkFinalized) +
Number(options.noFees) +
Number(options.checkDecodedXcm);

const isBlockCached = this.blockStore.get(cacheKey);

const historicApi = await this.api.at(hash);

const block = await this.service.fetchBlock(hash, historicApi, options);
const block = isBlockCached ? isBlockCached : await this.service.fetchBlock(hash, historicApi, options);

if (!isBlockCached) {
this.blockStore.set(cacheKey, block);
}
/**
* Verify our param `extrinsicIndex` is an integer represented as a string
*/
Expand Down
2 changes: 1 addition & 1 deletion src/controllers/blocks/BlocksRawExtrinsicsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default class BlocksRawExtrinsicsController extends AbstractController<Bl
super(
api,
'/blocks/:blockId/extrinsics-raw',
new BlocksService(api, options.minCalcFeeRuntime, options.blockStore, options.hasQueryFeeApi),
new BlocksService(api, options.minCalcFeeRuntime, options.hasQueryFeeApi),
);
this.initRoutes();
}
Expand Down
Loading

0 comments on commit 890c06b

Please sign in to comment.