Skip to content

Commit

Permalink
fix: skip expensive view refreshes when not streaming new blocks (#116)
Browse files Browse the repository at this point in the history
* feat: skip automatic predicate registration via env

* fix: refresh views only when streaming
  • Loading branch information
rafaelcr committed Jun 30, 2023
1 parent 9840a64 commit baec17c
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 12 deletions.
1 change: 1 addition & 0 deletions src/chainhook/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ const ChainhookPayload = Type.Object({
scope: Type.String(),
operation: Type.String(),
}),
is_streaming_blocks: Type.Boolean(),
}),
});
export type ChainhookPayload = Static<typeof ChainhookPayload>;
Expand Down
6 changes: 4 additions & 2 deletions src/chainhook/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,10 @@ export async function buildChainhookServer(args: { db: PgStore }) {

fastify.decorate('db', args.db);
fastify.addHook('onReady', waitForChainhookNode);
fastify.addHook('onReady', registerChainhookPredicates);
fastify.addHook('onClose', removeChainhookPredicates);
if (ENV.CHAINHOOK_AUTO_PREDICATE_REGISTRATION) {
fastify.addHook('onReady', registerChainhookPredicates);
fastify.addHook('onClose', removeChainhookPredicates);
}
await fastify.register(Chainhook);

return fastify;
Expand Down
5 changes: 5 additions & 0 deletions src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ const schema = Type.Object({
* coming from the valid instance
*/
CHAINHOOK_NODE_AUTH_TOKEN: Type.String(),
/**
* Register chainhook predicates automatically when the API is first launched. Set this to `false`
* if you're configuring your predicates manually for any reason.
*/
CHAINHOOK_AUTO_PREDICATE_REGISTRATION: Type.Boolean({ default: true }),

PGHOST: Type.String(),
PGPORT: Type.Number({ default: 5432, minimum: 0, maximum: 65535 }),
Expand Down
13 changes: 8 additions & 5 deletions src/pg/pg-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,12 @@ export class PgStore extends BasePgStore {
});
await this.normalizeInscriptionLocations({ inscription_id: Array.from(updatedInscriptionIds) });
await this.refreshMaterializedView('chain_tip');
await this.refreshMaterializedView('inscription_count');
await this.refreshMaterializedView('mime_type_counts');
await this.refreshMaterializedView('sat_rarity_counts');
// Skip expensive view refreshes if we're not streaming any live blocks yet.
if (payload.chainhook.is_streaming_blocks) {
await this.refreshMaterializedView('inscription_count');
await this.refreshMaterializedView('mime_type_counts');
await this.refreshMaterializedView('sat_rarity_counts');
}
}

async getChainTipBlockHeight(): Promise<number> {
Expand All @@ -229,7 +232,7 @@ export class PgStore extends BasePgStore {
async getMimeTypeInscriptionCount(mimeType?: string[]): Promise<number> {
if (!mimeType) return 0;
const result = await this.sql<{ count: number }[]>`
SELECT SUM(count) AS count
SELECT COALESCE(SUM(count), 0) AS count
FROM mime_type_counts
WHERE mime_type IN ${this.sql(mimeType)}
`;
Expand All @@ -239,7 +242,7 @@ export class PgStore extends BasePgStore {
async geSatRarityInscriptionCount(satRarity?: SatoshiRarity[]): Promise<number> {
if (!satRarity) return 0;
const result = await this.sql<{ count: number }[]>`
SELECT SUM(count) AS count
SELECT COALESCE(SUM(count), 0) AS count
FROM sat_rarity_counts
WHERE sat_rarity IN ${this.sql(satRarity)}
`;
Expand Down
6 changes: 6 additions & 0 deletions tests/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export class TestChainhookPayloadBuilder {
scope: 'ordinals_protocol',
operation: 'inscription_feed',
},
is_streaming_blocks: true,
},
};
private action: 'apply' | 'rollback' = 'apply';
Expand All @@ -38,6 +39,11 @@ export class TestChainhookPayloadBuilder {
return this.lastBlock.transactions[this.lastBlock.transactions.length - 1];
}

streamingBlocks(streaming: boolean): this {
this.payload.chainhook.is_streaming_blocks = streaming;
return this;
}

apply(): this {
this.action = 'apply';
return this;
Expand Down
90 changes: 90 additions & 0 deletions tests/inscriptions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2362,6 +2362,96 @@ describe('/inscriptions', () => {
expect(responseJson2.results[2].genesis_block_height).toStrictEqual(775617);
});
});

describe('when not streaming', () => {
test('counts are returned as zero', async () => {
await db.updateInscriptions(
new TestChainhookPayloadBuilder()
.streamingBlocks(false)
.apply()
.block({
height: 778575,
hash: '0x00000000000000000002a90330a99f67e3f01eb2ce070b45930581e82fb7a91d',
timestamp: 1676913207,
})
.transaction({
hash: '9f4a9b73b0713c5da01c0a47f97c6c001af9028d6bdd9e264dfacbc4e6790201',
})
.inscriptionRevealed({
content_bytes: '0x48656C6C6F',
content_type: 'text/plain;charset=utf-8',
content_length: 5,
inscription_number: 7,
inscription_fee: 705,
inscription_id: '9f4a9b73b0713c5da01c0a47f97c6c001af9028d6bdd9e264dfacbc4e6790201i0',
inscription_output_value: 10000,
inscriber_address: 'bc1pscktlmn99gyzlvymvrezh6vwd0l4kg06tg5rvssw0czg8873gz5sdkteqj',
ordinal_number: 0,
ordinal_block_height: 0,
ordinal_offset: 0,
satpoint_post_inscription:
'9f4a9b73b0713c5da01c0a47f97c6c001af9028d6bdd9e264dfacbc4e6790201:0:0',
})
.build()
);
await db.updateInscriptions(
new TestChainhookPayloadBuilder()
.streamingBlocks(false)
.apply()
.block({
height: 775617,
hash: '00000000000000000002a90330a99f67e3f01eb2ce070b45930581e82fb7a91d',
timestamp: 1676913207,
})
.transaction({
hash: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dc',
})
.inscriptionRevealed({
content_bytes: '0x48656C6C6F',
content_type: 'image/png',
content_length: 5,
inscription_number: 1,
inscription_fee: 2805,
inscription_id: '38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dci0',
inscription_output_value: 10000,
inscriber_address: 'bc1p3cyx5e2hgh53w7kpxcvm8s4kkega9gv5wfw7c4qxsvxl0u8x834qf0u2td',
ordinal_number: 257418248345364,
ordinal_block_height: 650000,
ordinal_offset: 0,
satpoint_post_inscription:
'38c46a8bf7ec90bc7f6b797e7dc84baa97f4e5fd4286b92fe1b50176d03b18dc:0:0',
})
.build()
);

const response1 = await fastify.inject({
method: 'GET',
url: '/ordinals/v1/inscriptions?mime_type=text/plain',
});
expect(response1.statusCode).toBe(200);
const responseJson1 = response1.json();
expect(responseJson1.total).toBe(0);
expect(responseJson1.results.length).toBeGreaterThan(0);

const response2 = await fastify.inject({
method: 'GET',
url: '/ordinals/v1/inscriptions?rarity=mythic',
});
expect(response2.statusCode).toBe(200);
const responseJson2 = response2.json();
expect(responseJson2.total).toBe(0);
expect(responseJson2.results.length).toBeGreaterThan(0);

const response3 = await fastify.inject({
method: 'GET',
url: '/ordinals/v1/inscriptions',
});
expect(response3.statusCode).toBe(200);
const responseJson3 = response3.json();
expect(responseJson3.total).toBe(0);
expect(responseJson3.results.length).toBeGreaterThan(0);
});
});
});

test('returns not found for invalid inscriptions', async () => {
Expand Down
16 changes: 11 additions & 5 deletions tests/server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ENV } from '../src/env';
import { cycleMigrations } from '../src/pg/migrations';
import { PgStore } from '../src/pg/pg-store';
import { TestChainhookPayloadBuilder, TestFastifyServer } from './helpers';
import { ChainhookPayload } from '../src/chainhook/schemas';

describe('EventServer', () => {
let db: PgStore;
Expand Down Expand Up @@ -149,7 +150,7 @@ describe('EventServer', () => {
};

// Apply
const payload1 = {
const payload1: ChainhookPayload = {
apply: [reveal],
rollback: [],
chainhook: {
Expand All @@ -158,6 +159,7 @@ describe('EventServer', () => {
scope: 'ordinals_protocol',
operation: 'inscription_feed',
},
is_streaming_blocks: true,
},
};
const response = await fastify.inject({
Expand Down Expand Up @@ -208,7 +210,7 @@ describe('EventServer', () => {
expect(inscr.value).toBe('10000');

// Rollback
const payload2 = {
const payload2: ChainhookPayload = {
apply: [],
rollback: [reveal],
chainhook: {
Expand All @@ -217,6 +219,7 @@ describe('EventServer', () => {
scope: 'ordinals_protocol',
operation: 'inscription_feed',
},
is_streaming_blocks: true,
},
};
const response2 = await fastify.inject({
Expand Down Expand Up @@ -303,7 +306,7 @@ describe('EventServer', () => {
};

// Apply
const payload1 = {
const payload1: ChainhookPayload = {
apply: [transfer],
rollback: [],
chainhook: {
Expand All @@ -312,6 +315,7 @@ describe('EventServer', () => {
scope: 'ordinals_protocol',
operation: 'inscription_feed',
},
is_streaming_blocks: true,
},
};
const response = await fastify.inject({
Expand Down Expand Up @@ -362,7 +366,7 @@ describe('EventServer', () => {
expect(inscr.value).toBe('10000');

// Rollback
const payload2 = {
const payload2: ChainhookPayload = {
apply: [],
rollback: [transfer],
chainhook: {
Expand All @@ -371,6 +375,7 @@ describe('EventServer', () => {
scope: 'ordinals_protocol',
operation: 'inscription_feed',
},
is_streaming_blocks: true,
},
};
const response2 = await fastify.inject({
Expand Down Expand Up @@ -435,7 +440,7 @@ describe('EventServer', () => {
};

// Apply
const payload1 = {
const payload1: ChainhookPayload = {
apply: [reveal],
rollback: [],
chainhook: {
Expand All @@ -444,6 +449,7 @@ describe('EventServer', () => {
scope: 'ordinals_protocol',
operation: 'inscription_feed',
},
is_streaming_blocks: true,
},
};
const response = await fastify.inject({
Expand Down

0 comments on commit baec17c

Please sign in to comment.