Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example.compose
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@ JAEGER_FRONTEND=16686
JAEGER_LOG_PORT=14268

BLOCK_RANGE_SIZE=10000
ZKAPP_COMMAND_RANGE_SIZE=1000
ZKAPP_COMMAND_ACCOUNT_UPDATE_LIMIT=5000
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ PG_CONN='postgres://postgres:postgres@localhost:5432/archive' \
| `ENABLE_GRAPHIQL` | `false` | Serve the GraphiQL playground at `/` |
| `ENABLE_INTROSPECTION` | `false` | Allow GraphQL schema introspection |
| `ENABLE_LOGGING` | `false` | Enable request logging |
| `BLOCK_RANGE_SIZE` | `10000` | Max block range a single query may span |
| `ZKAPP_COMMAND_RANGE_SIZE` | `1000` | Max block range for `zkappCommands` |
| `ZKAPP_COMMAND_ACCOUNT_UPDATE_LIMIT` | `5000` | Max expanded account updates for one `zkappCommands` query |
| `ENABLE_JAEGER` | `false` | Emit traces to a Jaeger collector |
| `JAEGER_ENDPOINT` | — | e.g. `http://localhost:14268/api/traces` |

Expand Down
2 changes: 2 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ The server reads config from environment variables. `PG_CONN` is the only requir
| `ENABLE_INTROSPECTION` | `false` | If `true`, allows GraphQL schema introspection |
| `ENABLE_LOGGING` | `false` | Enable request logging |
| `BLOCK_RANGE_SIZE` | `10000` | Max block range a single query may span |
| `ZKAPP_COMMAND_RANGE_SIZE` | `1000` | Max block range for `zkappCommands` |
| `ZKAPP_COMMAND_ACCOUNT_UPDATE_LIMIT` | `5000` | Max expanded account updates for one `zkappCommands` query |
| `ENABLE_BLOCK_TRANSACTION_DETAILS` | `false` | Include `userCommands` / `zkappCommands` / `feeTransfers` |
| `ENABLE_JAEGER` | `false` | Emit traces to a Jaeger collector |
| `JAEGER_SERVICE_NAME` | `archive-api` | Service name reported to Jaeger |
Expand Down
77 changes: 77 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,31 @@ input ActionFilterOptionsInput {
endActionState: String
}

"""
Filter successful zkApp commands by block range.

Both `from` and `to` are required. The range is bounded by `ZKAPP_COMMAND_RANGE_SIZE`, and the server may reject dense ranges that expand to too many account updates.
"""
input ZkappCommandFilterOptionsInput {
blockStatus: BlockStatusFilter
"""
Mina block height to filter zkApp commands from, inclusive
"""
from: Int!
"""
Mina block height to filter zkApp commands to, exclusive
"""
to: Int!
"""
Optional account update public key filter.
"""
accountPublicKey: String
"""
Optional account update token id filter.
"""
tokenId: String
}

type EventData {
accountUpdateId: String!
transactionInfo: TransactionInfo
Expand Down Expand Up @@ -124,6 +149,57 @@ type ActionOutput {
actionState: ActionStates!
}

"""
Raw field array from the archive database.

An empty `fields` array means the archive row exists but contains no field values.
Nullable entries mean the corresponding nullable archive state slot has no field value.
"""
type ZkappFieldArray {
fields: [String]!
}

type ZkappAccountPrecondition {
state: ZkappFieldArray
actionState: ZkappFieldArray
provedState: Boolean
isNew: Boolean
}

type ZkappGlobalSlotBounds {
lowerBound: Int
upperBound: Int
}

type ZkappNetworkPrecondition {
globalSlotSinceGenesis: ZkappGlobalSlotBounds
}

type ZkappAccountUpdateOutput {
id: String!
publicKey: String!
tokenId: String!
authorizationKind: String!
balanceChange: String!
incrementNonce: Boolean!
callDepth: Int!
actions: [ZkappFieldArray!]!
events: [ZkappFieldArray!]!
appState: ZkappFieldArray
accountPrecondition: ZkappAccountPrecondition
networkPrecondition: ZkappNetworkPrecondition
}

type ZkappCommandOutput {
blockInfo: BlockInfo!
hash: String!
feePayer: String!
fee: String!
memo: String!
sequenceNumber: Int!
accountUpdates: [ZkappAccountUpdateOutput!]!
}

"""
Metadata about the network
"""
Expand Down Expand Up @@ -216,6 +292,7 @@ type Block {
type Query {
events(input: EventFilterOptionsInput!): [EventOutput]!
actions(input: ActionFilterOptionsInput!): [ActionOutput]!
zkappCommands(input: ZkappCommandFilterOptionsInput!): [ZkappCommandOutput!]!
networkState: NetworkStateOutput!
blocks(query: BlockQueryInput, limit: Int, sortBy: BlockSortByInput): [Block]!
}
51 changes: 51 additions & 0 deletions src/blockchain/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,57 @@ export type ZkAppCommand = {
failureReason: string | null;
};

export type ZkappAccountPrecondition = {
state: ZkappFieldArray | null;
actionState: ZkappFieldArray | null;
provedState: boolean | null;
isNew: boolean | null;
};

export type ZkappFieldArray = {
fields: (string | null)[];
};

export type ZkappNestedFieldArray = {
fields: string[];
};

export type ZkappGlobalSlotBounds = {
lowerBound: number | null;
upperBound: number | null;
};

export type ZkappNetworkPrecondition = {
globalSlotSinceGenesis: ZkappGlobalSlotBounds;
};

export type ZkappAccountUpdate = {
id: string;
publicKey: string;
tokenId: string;
authorizationKind: string;
balanceChange: string;
incrementNonce: boolean;
callDepth: number;
actions: ZkappNestedFieldArray[];
events: ZkappNestedFieldArray[];
appState: ZkappFieldArray | null;
accountPrecondition: ZkappAccountPrecondition;
networkPrecondition: ZkappNetworkPrecondition;
};

export type ZkappCommand = {
blockInfo: BlockInfo;
hash: string;
feePayer: string;
fee: string;
memo: string;
sequenceNumber: number;
accountUpdates: ZkappAccountUpdate[];
};

export type ZkappCommands = ZkappCommand[];

export type FeeTransfer = {
recipient: string;
fee: string;
Expand Down
18 changes: 15 additions & 3 deletions src/db/archive-node-adapter/archive-node-adapter.interface.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
import type { EventFilterOptionsInput } from '../../resolvers-types.js';
import type {
ActionFilterOptionsInput,
EventFilterOptionsInput,
ZkappCommandFilterOptionsInput,
} from '../../resolvers-types.js';
import type {
Actions,
Events,
NetworkState,
Blocks,
ZkappCommands,
} from '../../blockchain/types.js';
import type { BlockQueryInput, BlockSortByInput } from '../../resolvers-types.js';
import type {
BlockQueryInput,
BlockSortByInput,
} from '../../resolvers-types.js';

export interface DatabaseAdapter {
getEvents(input: EventFilterOptionsInput, options?: unknown): Promise<Events>;
getActions(
input: EventFilterOptionsInput,
input: ActionFilterOptionsInput,
options?: unknown
): Promise<Actions>;
getZkappCommands(
input: ZkappCommandFilterOptionsInput,
options?: unknown
): Promise<ZkappCommands>;
getNetworkState(options?: unknown): Promise<NetworkState>;
getBlocks(
query: BlockQueryInput | null | undefined,
Expand Down
13 changes: 13 additions & 0 deletions src/db/archive-node-adapter/archive-node-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,23 @@ import type {
Events,
NetworkState,
Blocks,
ZkappCommands,
} from '../../blockchain/types.js';
import type { DatabaseAdapter } from './archive-node-adapter.interface.js';
import type {
ActionFilterOptionsInput,
EventFilterOptionsInput,
BlockQueryInput,
BlockSortByInput,
ZkappCommandFilterOptionsInput,
} from '../../resolvers-types.js';
import { getTables, USED_TABLES } from '../../db/sql/events-actions/queries.js';
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 { ZkappCommandsService } from '../../services/zkapp-commands-service/zkapp-commands-service.js';
import { IZkappCommandsService } from '../../services/zkapp-commands-service/zkapp-commands-service.interface.js';
import { NetworkService } from '../../services/network-service/network-service.js';
import { INetworkService } from '../../services/network-service/network-service.interface.js';
import { BlocksService } from '../../services/blocks-service/blocks-service.js';
Expand All @@ -32,6 +36,7 @@ export class ArchiveNodeAdapter implements DatabaseAdapter {
private client: postgres.Sql;
private eventsService: IEventsService;
private actionsService: IActionsService;
private zkappCommandsService: IZkappCommandsService;
private networkService: INetworkService;
private blocksService: IBlocksService;

Expand All @@ -43,6 +48,7 @@ export class ArchiveNodeAdapter implements DatabaseAdapter {
this.client = postgres(connectionString);
this.eventsService = new EventsService(this.client);
this.actionsService = new ActionsService(this.client);
this.zkappCommandsService = new ZkappCommandsService(this.client);
this.networkService = new NetworkService(this.client);
this.blocksService = new BlocksService(this.client);
}
Expand All @@ -61,6 +67,13 @@ export class ArchiveNodeAdapter implements DatabaseAdapter {
return this.actionsService.getActions(input, options);
}

async getZkappCommands(
input: ZkappCommandFilterOptionsInput,
options: unknown
): Promise<ZkappCommands> {
return this.zkappCommandsService.getZkappCommands(input, options);
}

async getNetworkState(options: unknown): Promise<NetworkState> {
return this.networkService.getNetworkState(options);
}
Expand Down
8 changes: 8 additions & 0 deletions src/db/sql/events-actions/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -429,12 +429,20 @@ export const USED_TABLES = [
'account_identifiers',
'accounts_accessed',
'blocks_zkapp_commands',
'public_keys',
'tokens',
'zkapp_commands',
'zkapp_fee_payer_body',
'zkapp_account_update',
'zkapp_account_update_body',
'zkapp_updates',
'zkapp_events',
'zkapp_field_array',
'zkapp_field',
'zkapp_account_precondition',
'zkapp_network_precondition',
'zkapp_global_slot_bounds',
'zkapp_states_nullable',
'zkapp_verification_key_hashes',
'zkapp_verification_keys',
'zkapp_accounts',
Expand Down
Loading
Loading