Skip to content
This repository has been archived by the owner on Jun 3, 2022. It is now read-only.

Commit

Permalink
chore(indexer): reduce the amount of RPC call from 4 to 2 for indexing (
Browse files Browse the repository at this point in the history
#742)

* optimize rpc block provider

* chore(indexer): reduce the amount of RPC call from 4 to 2 for indexing

* +1 more so that RPCBlockProvider.synchronize() can update to next block.
New behavior where RPCBlockProvider won't invalidate block on the same height as itself
  • Loading branch information
fuxingloh authored Jan 31, 2022
1 parent 442277a commit 349876d
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 17 deletions.
5 changes: 4 additions & 1 deletion src/e2e.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,11 @@ export async function invalidateFromHeight (app: NestFastifyApplication, contain
const invalidateBlockHash = await container.call('getblockhash', [invalidateHeight])
await container.call('invalidateblock', [invalidateBlockHash])
await container.call('clearmempool')
await container.generate(height - invalidateHeight + 1)
// +1 more so that RPCBlockProvider.synchronize can update to next block.
// New behavior where RPCBlockProvider won't invalidate block on the same height as itself
await container.generate(height - invalidateHeight + 2)
const blockMapper = app.get(BlockMapper)

await waitForExpect(async () => {
const block = await blockMapper.getByHeight(height)
expect(block).not.toStrictEqual(undefined)
Expand Down
39 changes: 23 additions & 16 deletions src/module.indexer/rpc.block.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { IndexStatusMapper, Status } from '@src/module.indexer/status'
import { TokenMapper } from '@src/module.model/token'
import { HexEncoder } from '@src/module.model/_hex.encoder'
import { waitForCondition } from '@defichain/testcontainers/dist/utils'
import { blockchain as defid } from '@defichain/jellyfish-api-core'

@Injectable()
export class RPCBlockProvider {
Expand Down Expand Up @@ -78,24 +79,31 @@ export class RPCBlockProvider {
return await this.indexGenesis()
}

if (await this.isBestChain(indexed)) {
const highest = await this.client.blockchain.getBlockCount()
const nextHeight = indexed.height + 1
if (nextHeight > highest) {
return false // won't attempt to index ahead
let nextHash: string
try {
nextHash = await this.client.blockchain.getBlockHash(indexed.height + 1)
} catch (err) {
if (err.payload.message === 'Block height out of range') {
return false
}
throw err
}

const nextHash = await this.client.blockchain.getBlockHash(nextHeight)
await this.index(nextHash, nextHeight)
const nextBlock = await this.client.blockchain.getBlock(nextHash, 2)
if (await RPCBlockProvider.isBestChain(indexed, nextBlock)) {
await this.index(nextBlock)
} else {
await this.invalidate(indexed.hash, indexed.height)
}
return true
}

private async isBestChain (indexed: Block): Promise<boolean> {
const hash = await this.client.blockchain.getBlockHash(indexed.height)
return hash === indexed.hash
/**
* @param {Block} indexed previous block
* @param {defid.Block<Transaction>} nextBlock to check previous block hash
*/
private static async isBestChain (indexed: Block, nextBlock: defid.Block<defid.Transaction>): Promise<boolean> {
return nextBlock.previousblockhash === indexed.hash
}

public async indexGenesis (): Promise<boolean> {
Expand Down Expand Up @@ -146,16 +154,15 @@ export class RPCBlockProvider {
await this.invalidate(status.hash, status.height)
}

private async index (hash: string, height: number): Promise<void> {
this.logger.log(`Index - hash: ${hash} - height: ${height}`)
const block = await this.client.blockchain.getBlock(hash, 2)
await this.statusMapper.put(hash, height, Status.INDEXING)
private async index (block: defid.Block<defid.Transaction>): Promise<void> {
this.logger.log(`Index - hash: ${block.hash} - height: ${block.height}`)
await this.statusMapper.put(block.hash, block.height, Status.INDEXING)

try {
await this.indexer.index(block)
await this.statusMapper.put(hash, height, Status.INDEXED)
await this.statusMapper.put(block.hash, block.height, Status.INDEXED)
} catch (err) {
await this.statusMapper.put(hash, height, Status.ERROR)
await this.statusMapper.put(block.hash, block.height, Status.ERROR)
throw err
}
}
Expand Down

0 comments on commit 349876d

Please sign in to comment.