Skip to content

Commit

Permalink
feat: add block service
Browse files Browse the repository at this point in the history
  • Loading branch information
boray committed Jan 9, 2025
1 parent 44a437a commit 630b3d5
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 3 deletions.
6 changes: 6 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ type BlockInfo {
distanceFromMaxBlockHeight: Int!
}

type MaxBlockHeightInfo {

Check notice on line 49 in schema.graphql

View workflow job for this annotation

GitHub Actions / GraphQL Inspector

Type 'MaxBlockHeightInfo' was added

Type 'MaxBlockHeightInfo' was added
canonicalMaxBlockHeight: Int!
pendingMaxBlockHeight: Int!
}

type TransactionInfo {
status: String!
hash: String!
Expand Down Expand Up @@ -78,4 +83,5 @@ type ActionOutput {
type Query {
events(input: EventFilterOptionsInput!): [EventOutput]!
actions(input: ActionFilterOptionsInput!): [ActionOutput]!
maxBlockHeightInfo: MaxBlockHeightInfo!

Check notice on line 86 in schema.graphql

View workflow job for this annotation

GitHub Actions / GraphQL Inspector

Field 'maxBlockHeightInfo' was added to object type 'Query'

Field 'maxBlockHeightInfo' was added to object type 'Query'
}
5 changes: 5 additions & 0 deletions src/blockchain/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ export type Action = {
data: string[];
};

export type MaxBlockHeightInfo = {
canonicalMaxBlockHeight: number;
pendingMaxBlockHeight: number;
};

export type BlockInfo = {
height: number;
stateHash: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import type { EventFilterOptionsInput } from '../../resolvers-types.js';
import type { Actions, Events } from '../../blockchain/types.js';
import type {
Actions,
Events,
MaxBlockHeightInfo,
} from '../../blockchain/types.js';

export interface DatabaseAdapter {
getEvents(input: EventFilterOptionsInput, options?: unknown): Promise<Events>;
getActions(
input: EventFilterOptionsInput,
options?: unknown
): Promise<Actions>;
getMaxBlockHeightInfo(options?: unknown): Promise<MaxBlockHeightInfo>;
}
14 changes: 13 additions & 1 deletion src/db/archive-node-adapter/archive-node-adapter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import postgres from 'postgres';
import type { Actions, Events } from '../../blockchain/types.js';
import type {
Actions,
Events,
MaxBlockHeightInfo,
} from '../../blockchain/types.js';
import type { DatabaseAdapter } from './archive-node-adapter.interface.js';
import type {
ActionFilterOptionsInput,
Expand All @@ -10,6 +14,8 @@ import { EventsService } from '../../services/events-service/events-service.js';
import { IEventsService } from '../../services/events-service/events-service.interface.js';
import { ActionsService } from '../../services/actions-service/actions-service.js';
import { IActionsService } from '../../services/actions-service/actions-service.interface.js';
import { BlockService } from '../../services/blocks-service/block-service.js';
import { IBlockService } from '../../services/blocks-service/block-service.interface.js';

export class ArchiveNodeAdapter implements DatabaseAdapter {
/**
Expand All @@ -21,6 +27,7 @@ export class ArchiveNodeAdapter implements DatabaseAdapter {
private client: postgres.Sql;
private eventsService: IEventsService;
private actionsService: IActionsService;
private blockService: IBlockService;

constructor(connectionString: string | undefined) {
if (!connectionString)
Expand All @@ -30,6 +37,7 @@ export class ArchiveNodeAdapter implements DatabaseAdapter {
this.client = postgres(connectionString);
this.eventsService = new EventsService(this.client);
this.actionsService = new ActionsService(this.client);
this.blockService = new BlockService(this.client);
}

async getEvents(
Expand All @@ -46,6 +54,10 @@ export class ArchiveNodeAdapter implements DatabaseAdapter {
return this.actionsService.getActions(input, options);
}

async getMaxBlockHeightInfo(options: unknown): Promise<MaxBlockHeightInfo> {
return this.blockService.maxBlockHeightInfo(options);
}

async checkSQLSchema() {
let tables;
try {
Expand Down
18 changes: 18 additions & 0 deletions src/db/sql/events-actions/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,24 @@ export function getActionsQuery(
`;
}

export function getBlockQuery(db_client: postgres.Sql) {
return db_client`
WITH max_height AS (
SELECT MAX(height) AS max_height
FROM blocks
)
SELECT *
FROM blocks
WHERE height = (SELECT max_height FROM max_height)
AND chain_status = 'canonical'
UNION
SELECT *
FROM blocks
WHERE height = (SELECT max_height FROM max_height)
AND chain_status = 'pending'
`;
}

export function checkActionState(db_client: postgres.Sql, actionState: string) {
return db_client`
SELECT field FROM zkapp_field WHERE field = ${actionState}
Expand Down
13 changes: 13 additions & 0 deletions src/resolvers-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ export type BlockInfo = {
timestamp: Scalars['String']['output'];
};

export type MaxBlockHeightInfo = {
__typename?: 'MaxBlockHeightInfo';
canonicalMaxBlockHeight: Scalars['Int']['output'];
pendingMaxBlockHeight: Scalars['Int']['output'];
};

export { BlockStatusFilter };

export type EventData = {
Expand Down Expand Up @@ -110,6 +116,7 @@ export type Query = {
__typename?: 'Query';
actions: Array<Maybe<ActionOutput>>;
events: Array<Maybe<EventOutput>>;
block: Maybe<MaxBlockHeightInfo>;
};

export type QueryActionsArgs = {
Expand Down Expand Up @@ -242,6 +249,7 @@ export type ResolversTypes = {
ActionOutput: ResolverTypeWrapper<ActionOutput>;
ActionStates: ResolverTypeWrapper<ActionStates>;
BlockInfo: ResolverTypeWrapper<BlockInfo>;
MaxBlockHeightInfo: ResolverTypeWrapper<MaxBlockHeightInfo>;
BlockStatusFilter: BlockStatusFilter;
Boolean: ResolverTypeWrapper<Scalars['Boolean']['output']>;
EventData: ResolverTypeWrapper<EventData>;
Expand Down Expand Up @@ -438,6 +446,11 @@ export type QueryResolvers<
ContextType,
RequireFields<QueryEventsArgs, 'input'>
>;
block?: Resolver<
Maybe<ResolversTypes['MaxBlockHeightInfo']>,
ParentType,
ContextType
>;
};

export type TransactionInfoResolvers<
Expand Down
10 changes: 10 additions & 0 deletions src/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ const resolvers: Resolvers = {
tracingState: new TracingState(graphQLSpan),
});
},

block: async (_, {}, context) => {

Check failure on line 36 in src/resolvers.ts

View workflow job for this annotation

GitHub Actions / Linting

Unexpected empty object pattern
const graphQLSpan = setSpanNameFromGraphQLContext(
context,
'block.graphql'
);
return context.db_client.getMaxBlockHeightInfo({
tracingState: new TracingState(graphQLSpan),
});
},
},
};

Expand Down
5 changes: 5 additions & 0 deletions src/services/blocks-service/block-service.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { MaxBlockHeightInfo } from '../../blockchain/types.js';

export interface IBlockService {
maxBlockHeightInfo(options: unknown): Promise<MaxBlockHeightInfo>;
}
50 changes: 50 additions & 0 deletions src/services/blocks-service/block-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import type postgres from 'postgres';
import { MaxBlockHeightInfo } from '../../blockchain/types.js';
import { getBlockQuery } from '../../db/sql/events-actions/queries.js';

import { IBlockService } from './block-service.interface.js';
import {
TracingState,
extractTraceStateFromOptions,
} from '../../tracing/tracer.js';

export { BlockService };

class BlockService implements IBlockService {
private readonly client: postgres.Sql;

constructor(client: postgres.Sql) {
this.client = client;
}

async maxBlockHeightInfo(options: unknown): Promise<MaxBlockHeightInfo> {
const tracingState = extractTraceStateFromOptions(options);
return (await this.getMaxBlockHeightInfo({ tracingState })) ?? [];
}

async getMaxBlockHeightInfo({
tracingState,
}: {
tracingState: TracingState;
}): Promise<MaxBlockHeightInfo> {
const sqlSpan = tracingState.startSpan('block.SQL');
const rows = await this.executeBlockQuery();
sqlSpan.end();

const processingSpan = tracingState.startSpan('block.processing');
const blockData = {
canonicalMaxBlockHeight: Number(
rows.filter((row) => row.chain_status === 'canonical')[0]
),
pendingMaxBlockHeight: Number(
rows.filter((row) => row.chain_status === 'pending')[0]
),
};
processingSpan.end();
return blockData;
}

private async executeBlockQuery() {
return getBlockQuery(this.client);
}
}
2 changes: 1 addition & 1 deletion zkapp/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ async function updateContractState(
await zkApp.update(Field(4));
}
);
transaction.sign([senderKey]).prove();
await transaction.sign([senderKey]).prove();
await sendTransaction(transaction);
}

Expand Down

0 comments on commit 630b3d5

Please sign in to comment.