Skip to content

Commit

Permalink
chore: code reuse
Browse files Browse the repository at this point in the history
  • Loading branch information
zone117x committed Nov 12, 2024
1 parent b58f164 commit 7635c18
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 190 deletions.
151 changes: 52 additions & 99 deletions src/api/routes/block-proposals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
BlockProposalsResponseSchema,
} from '../schemas';
import { NotFoundError } from '../errors';
import { DbBlockProposalQueryResponse } from '../../pg/types';

export const BlockProposalsRoutes: FastifyPluginCallback<
Record<never, never>,
Expand Down Expand Up @@ -49,57 +50,7 @@ export const BlockProposalsRoutes: FastifyPluginCallback<
limit: request.query.limit,
offset: request.query.offset,
});
const blockProposals = results.map(r => {
const signerData = r.signer_data.map(s => {
const data: BlockProposalSignerData = {
signer_key: s.signer_key,
slot_index: s.slot_index,
response: s.response,
weight: s.weight,
weight_percentage: Number(
BigNumber(s.weight).div(r.total_signer_weight).times(100).toFixed(3)
),
stacked_amount: s.stacked_amount,
version: s.version,
received_at: s.received_at ? new Date(s.received_at).toISOString() : null,
response_time_ms: s.received_at
? differenceInMilliseconds(new Date(s.received_at), r.received_at)
: null,
reason_string: s.reason_string,
reason_code: s.reason_code,
reject_code: s.reject_code,
};
return data;
});

const entry: BlockProposalsEntry = {
received_at: r.received_at.toISOString(),
block_height: r.block_height,
block_hash: r.block_hash,
index_block_hash: r.index_block_hash,
burn_block_height: r.burn_block_height,
block_time: r.block_time,
cycle_number: r.cycle_number,
status: r.status,

// cycle data
total_signer_count: r.total_signer_count,
total_signer_weight: r.total_signer_weight,
total_signer_stacked_amount: r.total_signer_stacked_amount,

accepted_count: r.accepted_count,
rejected_count: r.rejected_count,
missing_count: r.missing_count,

accepted_weight: r.accepted_weight,
rejected_weight: r.rejected_weight,
missing_weight: r.missing_weight,

signer_data: signerData,
};
return entry;
});
return blockProposals;
return results.map(r => parseDbBlockProposalData(r));
});
await reply.send({
limit: request.query.limit,
Expand Down Expand Up @@ -146,60 +97,62 @@ export const BlockProposalsRoutes: FastifyPluginCallback<
if (results.length === 0) {
throw new NotFoundError('Block proposal not found');
}
return parseDbBlockProposalData(results[0]);
});
await reply.send(result);
}
);

const r = results[0];
const signerData = r.signer_data.map(s => {
const data: BlockProposalSignerData = {
signer_key: s.signer_key,
slot_index: s.slot_index,
response: s.response,
weight: s.weight,
weight_percentage: Number(
BigNumber(s.weight).div(r.total_signer_weight).times(100).toFixed(3)
),
stacked_amount: s.stacked_amount,
version: s.version,
received_at: s.received_at ? new Date(s.received_at).toISOString() : null,
response_time_ms: s.received_at
? differenceInMilliseconds(new Date(s.received_at), r.received_at)
: null,
reason_string: s.reason_string,
reason_code: s.reason_code,
reject_code: s.reject_code,
};
return data;
});
function parseDbBlockProposalData(r: DbBlockProposalQueryResponse): BlockProposalsEntry {
const signerData = r.signer_data.map(s => {
const data: BlockProposalSignerData = {
signer_key: s.signer_key,
slot_index: s.slot_index,
response: s.response,
weight: s.weight,
weight_percentage: Number(
BigNumber(s.weight).div(r.total_signer_weight).times(100).toFixed(3)
),
stacked_amount: s.stacked_amount,
version: s.version,
received_at: s.received_at ? new Date(s.received_at).toISOString() : null,
response_time_ms: s.received_at
? differenceInMilliseconds(new Date(s.received_at), r.received_at)
: null,
reason_string: s.reason_string,
reason_code: s.reason_code,
reject_code: s.reject_code,
};
return data;
});

const entry: BlockProposalsEntry = {
received_at: r.received_at.toISOString(),
block_height: r.block_height,
block_hash: r.block_hash,
index_block_hash: r.index_block_hash,
burn_block_height: r.burn_block_height,
block_time: r.block_time,
cycle_number: r.cycle_number,
status: r.status,
const entry: BlockProposalsEntry = {
received_at: r.received_at.toISOString(),
block_height: r.block_height,
block_hash: r.block_hash,
index_block_hash: r.index_block_hash,
burn_block_height: r.burn_block_height,
block_time: r.block_time,
cycle_number: r.cycle_number,
status: r.status,

// cycle data
total_signer_count: r.total_signer_count,
total_signer_weight: r.total_signer_weight,
total_signer_stacked_amount: r.total_signer_stacked_amount,
// cycle data
total_signer_count: r.total_signer_count,
total_signer_weight: r.total_signer_weight,
total_signer_stacked_amount: r.total_signer_stacked_amount,

accepted_count: r.accepted_count,
rejected_count: r.rejected_count,
missing_count: r.missing_count,
accepted_count: r.accepted_count,
rejected_count: r.rejected_count,
missing_count: r.missing_count,

accepted_weight: r.accepted_weight,
rejected_weight: r.rejected_weight,
missing_weight: r.missing_weight,
accepted_weight: r.accepted_weight,
rejected_weight: r.rejected_weight,
missing_weight: r.missing_weight,

signer_data: signerData,
};
return entry;
});
await reply.send(result);
}
);
signer_data: signerData,
};
return entry;
}

done();
};
93 changes: 3 additions & 90 deletions src/pg/pg-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import * as path from 'path';
import { ChainhookPgStore } from './chainhook/chainhook-pg-store';
import { BlockIdParam, normalizeHexString, sleep } from '../helpers';
import { Fragment } from 'postgres';
import { DbBlockProposalQueryResponse } from './types';

export const MIGRATIONS_DIR = path.join(__dirname, '../../migrations');

Expand Down Expand Up @@ -110,51 +111,7 @@ export class PgStore extends BasePgStore {
limit: number;
offset: number;
}) {
const result = await sql<
{
// block proposal data (from block_proposals):
received_at: Date;
block_height: number;
block_hash: string;
index_block_hash: string;
burn_block_height: number;
block_time: number;
cycle_number: number;

// proposal status (from blocks table, matched using block_hash and block_height):
status: 'pending' | 'rejected' | 'accepted';

// cycle data (from reward_set_signers, matched using cycle_number AKA reward_cycle):
total_signer_count: number;
total_signer_weight: number;
total_signer_stacked_amount: string;

// aggregate signer response data (from block_responses, matched using block_hash AKA signer_sighash, where missing is detected by the absence of a block_response for a given signer_key from the reward_set_signers table):
accepted_count: number;
rejected_count: number;
missing_count: number;
accepted_weight: number;
rejected_weight: number;
missing_weight: number;

// signer responses (from block_responses, matched using block_hash AKA signer_sighash, using the signer_key from the reward_set_signers table for some of the fields):
signer_data: {
signer_key: string;
slot_index: number;
response: 'accepted' | 'rejected' | 'missing';
weight: number;
stacked_amount: string;

version: string | null; // null for missing responses
received_at: string | null; // null for missing responses

// rejected fields (null for accepted and missing responses):
reason_string: string | null;
reason_code: string | null;
reject_code: string | null;
}[];
}[]
>`
const result = await sql<DbBlockProposalQueryResponse[]>`
SELECT
bp.received_at,
bp.block_height,
Expand Down Expand Up @@ -250,51 +207,7 @@ export class PgStore extends BasePgStore {
}

async getBlockProposal({ sql, blockHash }: { sql: PgSqlClient; blockHash: string }) {
const result = await sql<
{
// block proposal data (from block_proposals):
received_at: Date;
block_height: number;
block_hash: string;
index_block_hash: string;
burn_block_height: number;
block_time: number;
cycle_number: number;

// proposal status (from blocks table, matched using block_hash and block_height):
status: 'pending' | 'rejected' | 'accepted';

// cycle data (from reward_set_signers, matched using cycle_number AKA reward_cycle):
total_signer_count: number;
total_signer_weight: number;
total_signer_stacked_amount: string;

// aggregate signer response data (from block_responses, matched using block_hash AKA signer_sighash, where missing is detected by the absence of a block_response for a given signer_key from the reward_set_signers table):
accepted_count: number;
rejected_count: number;
missing_count: number;
accepted_weight: number;
rejected_weight: number;
missing_weight: number;

// signer responses (from block_responses, matched using block_hash AKA signer_sighash, using the signer_key from the reward_set_signers table for some of the fields):
signer_data: {
signer_key: string;
slot_index: number;
response: 'accepted' | 'rejected' | 'missing';
weight: number;
stacked_amount: string;

version: string | null; // null for missing responses
received_at: string | null; // null for missing responses

// rejected fields (null for accepted and missing responses):
reason_string: string | null;
reason_code: string | null;
reject_code: string | null;
}[];
}[]
>`
const result = await sql<DbBlockProposalQueryResponse[]>`
SELECT
bp.received_at,
bp.block_height,
Expand Down
44 changes: 44 additions & 0 deletions src/pg/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,47 @@ export type DbMockBlockSignerSignature = {
stacks_tip_height: number;
index_block_hash: PgBytea;
};

export type DbBlockProposalQueryResponse = {
// block proposal data (from block_proposals):
received_at: Date;
block_height: number;
block_hash: string;
index_block_hash: string;
burn_block_height: number;
block_time: number;
cycle_number: number;

// proposal status (from blocks table, matched using block_hash and block_height):
status: 'pending' | 'rejected' | 'accepted';

// cycle data (from reward_set_signers, matched using cycle_number AKA reward_cycle):
total_signer_count: number;
total_signer_weight: number;
total_signer_stacked_amount: string;

// aggregate signer response data (from block_responses, matched using block_hash AKA signer_sighash, where missing is detected by the absence of a block_response for a given signer_key from the reward_set_signers table):
accepted_count: number;
rejected_count: number;
missing_count: number;
accepted_weight: number;
rejected_weight: number;
missing_weight: number;

// signer responses (from block_responses, matched using block_hash AKA signer_sighash, using the signer_key from the reward_set_signers table for some of the fields):
signer_data: {
signer_key: string;
slot_index: number;
response: 'accepted' | 'rejected' | 'missing';
weight: number;
stacked_amount: string;

version: string | null; // null for missing responses
received_at: string | null; // null for missing responses

// rejected fields (null for accepted and missing responses):
reason_string: string | null;
reason_code: string | null;
reject_code: string | null;
}[];
};

Check warning on line 150 in src/pg/types.ts

View check run for this annotation

Codecov / codecov/patch

src/pg/types.ts#L107-L150

Added lines #L107 - L150 were not covered by tests
2 changes: 1 addition & 1 deletion tests/db/endpoints.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ describe('Endpoint tests', () => {
});
});

test('get blocks proposals', async () => {
test('get block proposals', async () => {
const responseTest = await supertest(apiServer.server)
.get('/signer-metrics/v1/block_proposals?limit=50')
.expect(200);
Expand Down

0 comments on commit 7635c18

Please sign in to comment.