Skip to content

Commit

Permalink
fix: improve cache.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
fabiorigam committed Oct 27, 2023
1 parent eb39028 commit 3fb9c75
Showing 1 changed file with 56 additions and 32 deletions.
88 changes: 56 additions & 32 deletions packages/network/src/driver/cache.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,79 @@
import { LRUCache } from 'lru-cache';

/**
* Constant that defines the window length used for determining irreversibility.
*/
const WINDOW_LEN = 12;

/**
* Represents a Slot in the cache, combining information about a block, accounts, transactions, receipts, and a tied map.
*/
type Slot = Connex.Thor.Status['head'] & {
block?: Connex.Thor.Block;

accounts: Map<string, Account>;
txs: Map<string, Connex.Thor.Transaction>;
receipts: Map<string, Connex.Thor.Transaction.Receipt>;
tied: Map<string, never>;
block?: Connex.Thor.Block; // Holds a reference to a blockchain block if available.
accounts: Map<string, Account>; // Maps account addresses to Account objects.
txs: Map<string, Connex.Thor.Transaction>; // Maps transaction IDs to Transaction objects.
receipts: Map<string, Connex.Thor.Transaction.Receipt>; // Maps transaction IDs to Transaction Receipt objects.
tied: Map<string, never>; // An empty map for a specific purpose.
};

export class Cache {
/**
* Cache class for managing caching of Thor blockchain data.
*/
class Cache {
/**
* Irreversible cache for blocks, transactions, and receipts using LRUCache.
*/
private readonly irreversible = {
blocks: new LRUCache<number | string, Connex.Thor.Block>({
max: 256
}),
txs: new LRUCache<string, Connex.Thor.Transaction>({ max: 512 }),
}), // Cache for storing blockchain blocks.
txs: new LRUCache<string, Connex.Thor.Transaction>({
max: 512
}), // Cache for storing transactions.
receipts: new LRUCache<string, Connex.Thor.Transaction.Receipt>({
max: 512
})
}) // Cache for storing transaction receipts.
};

/**
* Window to store Slot objects.
*/
private readonly window: Slot[] = [];

/**
* Retrieves a block based on its revision (number or ID).
*
* @param revision - The revision (number or ID) of the block to fetch.
* @param fetch - A function that fetches the block if not found in the cache.
* @returns A Promise that resolves to the fetched block or null if not found.
*/
public async getBlock(
revision: number | string,
fetch: () => Promise<Connex.Thor.Block | null | undefined>
): Promise<Connex.Thor.Block | null | undefined> {
let block = this.irreversible.blocks.get(revision) ?? null;

// If the block is found in the irreversible cache, return it.
if (block != null) {
return block;
}

const { slot } = this.findSlot(revision);

// If the block is available in a slot, return it.
if (slot?.block != null) {
return slot.block;
}

block = (await fetch()) ?? null;

// If a block is fetched, update the cache.
if (block != null) {
if (slot != null && slot.id === block.id) {
slot.block = block;
}

const a = block.number;
this.isIrreversible(a);

// Check if the block is irreversible and update the irreversible cache accordingly.
if (this.isIrreversible(block.number)) {
this.irreversible.blocks.set(block.id, block);
if (block.isTrunk) {
Expand All @@ -58,6 +84,12 @@ export class Cache {
return block;
}

/**
* Finds the slot associated with the given revision (number or ID).
*
* @param revision - The revision (number or ID) to find in the window.
* @returns An object containing the slot (if found) and its index in the window.
*/
private findSlot(revision: string | number): {
slot?: Slot;
index: number;
Expand All @@ -71,6 +103,12 @@ export class Cache {
return { index };
}

/**
* Checks if a given block number is irreversible based on the window length.
*
* @param n - The block number to check for irreversibility.
* @returns True if the block is irreversible, otherwise false.
*/
private isIrreversible(n: number): boolean {
if (this.window.length > 0) {
return n < this.window[this.window.length - 1].number - WINDOW_LEN;
Expand All @@ -79,28 +117,14 @@ export class Cache {
}
}

/**
* Represents an Account with Thor account data and an initialization timestamp.
*/
class Account {
constructor(
readonly obj: Connex.Thor.Account,
readonly initTimestamp: number
) {}

// public snapshot(timestamp: number) {
// return { ...this.obj, energy: this.energyAt(timestamp) };
// }

// private energyAt(timestamp: number) {
// if (timestamp < this.initTimestamp) {
// return this.obj.energy;
// }
// return (
// '0x' +
// new BigNumber(this.obj.balance)
// .times(timestamp - this.initTimestamp)
// .times(ENERGY_GROWTH_RATE)
// .dividedToIntegerBy(1e18)
// .plus(this.obj.energy)
// .toString(16)
// );
// }
}

export { Cache };

0 comments on commit 3fb9c75

Please sign in to comment.