Skip to content

Commit

Permalink
Fix pruning of canonical block if null block is encountered
Browse files Browse the repository at this point in the history
  • Loading branch information
nikugogoi committed Dec 27, 2023
1 parent 78e43bc commit 1898c97
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 19 deletions.
4 changes: 2 additions & 2 deletions packages/codegen/src/templates/database-template.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,8 @@ export class Database implements DatabaseInterface {
await this._baseDatabase.deleteEntitiesByConditions(queryRunner, entity, findConditions);
}

async getAncestorAtDepth (blockHash: string, depth: number): Promise<string> {
return this._baseDatabase.getAncestorAtDepth(blockHash, depth);
async getAncestorAtHeight (blockHash: string, height: number): Promise<string> {
return this._baseDatabase.getAncestorAtHeight(blockHash, height);
}

_getPropertyColumnMapForEntity (entityName: string): Map<string, string> {
Expand Down
4 changes: 2 additions & 2 deletions packages/codegen/src/templates/indexer-template.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -744,8 +744,8 @@ export class Indexer implements IndexerInterface {
return this._baseIndexer.updateBlockProgress(block, lastProcessedEventIndex);
}

async getAncestorAtDepth (blockHash: string, depth: number): Promise<string> {
return this._baseIndexer.getAncestorAtDepth(blockHash, depth);
async getAncestorAtHeight (blockHash: string, height: number): Promise<string> {
return this._baseIndexer.getAncestorAtHeight(blockHash, height);
}

async resetWatcherToBlock (blockNumber: number): Promise<void> {
Expand Down
4 changes: 2 additions & 2 deletions packages/graph-node/test/utils/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ export class Indexer implements IndexerInterface {
return [];
}

async getAncestorAtDepth (blockHash: string, depth: number): Promise<string> {
async getAncestorAtHeight (blockHash: string, height: number): Promise<string> {
assert(blockHash);
assert(depth);
assert(height);

return '';
}
Expand Down
12 changes: 5 additions & 7 deletions packages/util/src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -457,15 +457,14 @@ export class Database {
await repo.delete(findConditions);
}

async getAncestorAtDepth (blockHash: string, depth: number): Promise<string> {
async getAncestorAtHeight (blockHash: string, height: number): Promise<string> {
const heirerchicalQuery = `
WITH RECURSIVE cte_query AS
(
SELECT
block_hash,
block_number,
parent_hash,
0 as depth
parent_hash
FROM
block_progress
WHERE
Expand All @@ -474,14 +473,13 @@ export class Database {
SELECT
b.block_hash,
b.block_number,
b.parent_hash,
c.depth + 1
b.parent_hash
FROM
block_progress b
INNER JOIN
cte_query c ON c.parent_hash = b.block_hash
WHERE
c.depth < $2
b.block_number >= $2
)
SELECT
block_hash, block_number
Expand All @@ -492,7 +490,7 @@ export class Database {
`;

// Get ancestor block hash using heirarchical query.
const [{ block_hash: ancestorBlockHash }] = await this._conn.query(heirerchicalQuery, [blockHash, depth]);
const [{ block_hash: ancestorBlockHash }] = await this._conn.query(heirerchicalQuery, [blockHash, height]);

return ancestorBlockHash;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/util/src/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -709,8 +709,8 @@ export class Indexer {
}
}

async getAncestorAtDepth (blockHash: string, depth: number): Promise<string> {
return this._db.getAncestorAtDepth(blockHash, depth);
async getAncestorAtHeight (blockHash: string, height: number): Promise<string> {
return this._db.getAncestorAtHeight(blockHash, height);
}

async saveEventEntity (dbEvent: EventInterface): Promise<EventInterface> {
Expand Down
12 changes: 10 additions & 2 deletions packages/util/src/job-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -445,10 +445,18 @@ export class JobRunner {
// We have more than one node at this height, so prune all nodes not reachable from indexed block at max reorg depth from prune height.
// This will lead to orphaned nodes, which will get pruned at the next height.
if (blocksAtHeight.length > 1) {
const [indexedBlock] = await this._indexer.getBlocksAtHeight(pruneBlockHeight + MAX_REORG_DEPTH, false);
let indexedBlock: BlockProgressInterface | undefined;
let indexedBlockHeight = pruneBlockHeight + MAX_REORG_DEPTH;

// Loop to find latest indexed block incase null block is encountered
while (!indexedBlock) {
[indexedBlock] = await this._indexer.getBlocksAtHeight(indexedBlockHeight, false);
--indexedBlockHeight;
assert(indexedBlockHeight > pruneBlockHeight, `No blocks found above pruneBlockHeight ${pruneBlockHeight}`);
}

// Get ancestor blockHash from indexed block at prune height.
const ancestorBlockHash = await this._indexer.getAncestorAtDepth(indexedBlock.blockHash, MAX_REORG_DEPTH);
const ancestorBlockHash = await this._indexer.getAncestorAtHeight(indexedBlock.blockHash, pruneBlockHeight);
newCanonicalBlockHash = ancestorBlockHash;

const blocksToBePruned = blocksAtHeight.filter(block => ancestorBlockHash !== block.blockHash);
Expand Down
4 changes: 2 additions & 2 deletions packages/util/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ export interface IndexerInterface {
getLatestCanonicalBlock (): Promise<BlockProgressInterface | undefined>
getLatestStateIndexedBlock (): Promise<BlockProgressInterface>
getBlockEvents (blockHash: string, where: Where, queryOptions: QueryOptions): Promise<Array<EventInterface>>
getAncestorAtDepth (blockHash: string, depth: number): Promise<string>
getAncestorAtHeight (blockHash: string, height: number): Promise<string>
saveBlockAndFetchEvents (block: DeepPartial<BlockProgressInterface>): Promise<[
BlockProgressInterface,
DeepPartial<EventInterface>[],
Expand Down Expand Up @@ -248,7 +248,7 @@ export interface DatabaseInterface {
getBlockEvents (blockHash: string, where?: Where, queryOptions?: QueryOptions): Promise<EventInterface[]>;
getEvent (id: string): Promise<EventInterface | undefined>
getSyncStatus (queryRunner: QueryRunner): Promise<SyncStatusInterface | undefined>
getAncestorAtDepth (blockHash: string, depth: number): Promise<string>
getAncestorAtHeight (blockHash: string, height: number): Promise<string>
getProcessedBlockCountForRange (fromBlockNumber: number, toBlockNumber: number): Promise<{ expected: number, actual: number }>;
getEventsInRange (fromBlockNumber: number, toBlockNumber: number): Promise<Array<EventInterface>>;
markBlocksAsPruned (queryRunner: QueryRunner, blocks: BlockProgressInterface[]): Promise<void>;
Expand Down

0 comments on commit 1898c97

Please sign in to comment.