From eda79d07f804839d35fbd544dfc1c774c33c43a4 Mon Sep 17 00:00:00 2001 From: Matthew Little Date: Mon, 28 Oct 2024 13:00:25 +0100 Subject: [PATCH] fix: do not store duplicate MockProposals, MockSignatures, or MockBlocks --- migrations/1729684505758_mock_proposals.ts | 4 ++++ migrations/1729684505759_mock_signature.ts | 4 ++++ migrations/1729684505760_mock_blocks.ts | 8 +++++++ src/pg/chainhook/chainhook-pg-store.ts | 28 ++++++++++++++++++---- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/migrations/1729684505758_mock_proposals.ts b/migrations/1729684505758_mock_proposals.ts index a354180..683b857 100644 --- a/migrations/1729684505758_mock_proposals.ts +++ b/migrations/1729684505758_mock_proposals.ts @@ -58,4 +58,8 @@ export function up(pgm: MigrationBuilder): void { pgm.createIndex('mock_proposals', ['stacks_tip']); pgm.createIndex('mock_proposals', ['index_block_hash']); pgm.createIndex('mock_proposals', ['burn_block_height']); + + pgm.createConstraint('mock_proposals', 'mock_proposals_idb_unique', { + unique: ['index_block_hash'], + }); } diff --git a/migrations/1729684505759_mock_signature.ts b/migrations/1729684505759_mock_signature.ts index 68d4062..dcc1ab2 100644 --- a/migrations/1729684505759_mock_signature.ts +++ b/migrations/1729684505759_mock_signature.ts @@ -71,4 +71,8 @@ export function up(pgm: MigrationBuilder): void { pgm.createIndex('mock_signatures', ['stacks_tip']); pgm.createIndex('mock_signatures', ['index_block_hash']); pgm.createIndex('mock_signatures', ['burn_block_height']); + + pgm.createConstraint('mock_signatures', 'mock_signatures_signer_key_idb_unique', { + unique: ['signer_key', 'index_block_hash'], + }); } diff --git a/migrations/1729684505760_mock_blocks.ts b/migrations/1729684505760_mock_blocks.ts index a316192..d330187 100644 --- a/migrations/1729684505760_mock_blocks.ts +++ b/migrations/1729684505760_mock_blocks.ts @@ -65,6 +65,10 @@ export function up(pgm: MigrationBuilder): void { pgm.createIndex('mock_blocks', ['index_block_hash']); pgm.createIndex('mock_blocks', ['burn_block_height']); + pgm.createConstraint('mock_blocks', 'mock_blocks_idb_unique', { + unique: ['index_block_hash'], + }); + // Mock block signer signatures pgm.createTable('mock_block_signer_signatures', { id: { @@ -99,4 +103,8 @@ export function up(pgm: MigrationBuilder): void { pgm.createIndex('mock_block_signer_signatures', ['stacks_tip']); pgm.createIndex('mock_block_signer_signatures', ['stacks_tip_height']); pgm.createIndex('mock_block_signer_signatures', ['index_block_hash']); + + pgm.createConstraint('mock_block_signer_signatures', 'mock_block_signers_idb_unique', { + unique: ['index_block_hash', 'signer_key'], + }); } diff --git a/src/pg/chainhook/chainhook-pg-store.ts b/src/pg/chainhook/chainhook-pg-store.ts index 752ddfe..e31612f 100644 --- a/src/pg/chainhook/chainhook-pg-store.ts +++ b/src/pg/chainhook/chainhook-pg-store.ts @@ -188,10 +188,18 @@ export class ChainhookPgStore extends BasePgStoreModule { network_id: messageData.mock_proposal.peer_info.network_id, index_block_hash: normalizeHexString(messageData.mock_proposal.peer_info.index_block_hash), }; - await sql` + const result = await sql` INSERT INTO mock_blocks ${sql(dbMockBlock)} + ON CONFLICT ON CONSTRAINT mock_blocks_idb_unique DO NOTHING `; + if (result.count === 0) { + logger.info( + `Skipped inserting duplicate mock block height=${dbMockBlock.stacks_tip_height}, hash=${dbMockBlock.stacks_tip}` + ); + return; + } + for (const batch of batchIterate(messageData.mock_signatures, 500)) { const sigs = batch.map(sig => { const dbSig: DbMockBlockSignerSignature = { @@ -235,9 +243,15 @@ export class ChainhookPgStore extends BasePgStoreModule { // Metadata fields metadata_server_version: messageData.metadata.server_version, }; - await sql` + const result = await sql` INSERT INTO mock_signatures ${sql(dbMockSignature)} + ON CONFLICT ON CONSTRAINT mock_signatures_signer_key_idb_unique DO NOTHING `; + if (result.count === 0) { + logger.info( + `Skipped inserting duplicate mock signature height=${dbMockSignature.stacks_tip_height}, hash=${dbMockSignature.stacks_tip}, signer=${dbMockSignature.signer_key}` + ); + } } private async applyMockProposal( @@ -258,9 +272,15 @@ export class ChainhookPgStore extends BasePgStoreModule { network_id: messageData.network_id, index_block_hash: normalizeHexString(messageData.index_block_hash), }; - await sql` + const result = await sql` INSERT INTO mock_proposals ${sql(dbMockProposal)} + ON CONFLICT ON CONSTRAINT mock_proposals_idb_unique DO NOTHING `; + if (result.count === 0) { + logger.info( + `Skipped inserting duplicate mock proposal height=${dbMockProposal.stacks_tip_height}, hash=${dbMockProposal.stacks_tip}` + ); + } } private async applyBlockProposal( @@ -332,7 +352,7 @@ export class ChainhookPgStore extends BasePgStoreModule { if (result.count === 0) { logger.info( - `Skipped inserting duplicate block response signer_key=${dbBlockResponse.signer_key}, hash=${dbBlockResponse.signer_sighash}` + `Skipped inserting duplicate block response signer=${dbBlockResponse.signer_key}, hash=${dbBlockResponse.signer_sighash}` ); } }