From ad02897b211a172bdea9a293a73a4ccdf387743c Mon Sep 17 00:00:00 2001 From: Jordan Ribbink Date: Fri, 29 Nov 2024 00:27:51 -0800 Subject: [PATCH] begin adding blockheader type --- .../src/subscribe/handlers/block-headers.ts | 93 +++++++++++++++++++ .../transport-http/src/subscribe/subscribe.ts | 7 +- packages/typedefs/src/index.ts | 60 ++++++++++++ .../src/sdk-transport/subscriptions.ts | 9 +- 4 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 packages/transport-http/src/subscribe/handlers/block-headers.ts diff --git a/packages/transport-http/src/subscribe/handlers/block-headers.ts b/packages/transport-http/src/subscribe/handlers/block-headers.ts new file mode 100644 index 000000000..8522ebac8 --- /dev/null +++ b/packages/transport-http/src/subscribe/handlers/block-headers.ts @@ -0,0 +1,93 @@ +import {SdkTransport} from "@onflow/typedefs" +import {BlockArgsModel, createSubscriptionHandler} from "./types" + +type BlockHeaderArgs = + SdkTransport.SubscriptionArguments + +type BlockHeaderData = + SdkTransport.SubscriptionData + +type BlockHeaderArgsModel = BlockArgsModel + +type BlockHeaderDataModel = { + // TODO: We do not know the data model types yet + header: { + id: string + height: number + timestamp: string + chain_id: string + parent_id: string + collection_guarantees: { + collection_id: string + signer_ids: string[] + }[] + block_seals: { + block_id: string + result_id: string + }[] + } +} + +export const blockHeaderHandler = createSubscriptionHandler<{ + Topic: SdkTransport.SubscriptionTopic.BLOCK_HEADERS + Args: BlockHeaderArgs + Data: BlockHeaderData + ArgsModel: BlockHeaderArgsModel + DataModel: BlockHeaderDataModel +}>({ + topic: SdkTransport.SubscriptionTopic.BLOCK_HEADERS, + createSubscriber: (initialArgs, onData, onError) => { + let resumeArgs: BlockHeaderArgs = { + ...initialArgs, + } + + return { + sendData(data: BlockHeaderDataModel) { + // Parse the raw data + const parsedData: BlockHeaderData = { + blockHeader: { + id: data.header.id, + height: data.header.height, + timestamp: data.header.timestamp, + chainId: data.header.chain_id, + }, + } + + // Update the resume args + resumeArgs = { + blockStatus: resumeArgs.blockStatus, + startBlockHeight: data.header.height + 1, + } + + onData(parsedData) + }, + sendError(error: Error) { + onError(error) + }, + encodeArgs(args: BlockHeaderArgs) { + let encodedArgs: BlockHeaderArgsModel = { + block_status: args.blockStatus, + } + + if ("startBlockHeight" in args) { + return { + ...encodedArgs, + start_block_height: args.startBlockHeight, + } + } + + if ("startBlockId" in args) { + return { + ...encodedArgs, + start_block_id: args.startBlockId, + } + } + + return encodedArgs + }, + get connectionArgs() { + return resumeArgs + }, + } + }, +}) diff --git a/packages/transport-http/src/subscribe/subscribe.ts b/packages/transport-http/src/subscribe/subscribe.ts index 49d0a71c5..556be62f1 100644 --- a/packages/transport-http/src/subscribe/subscribe.ts +++ b/packages/transport-http/src/subscribe/subscribe.ts @@ -2,8 +2,13 @@ import {SdkTransport} from "@onflow/typedefs" import {SubscriptionManager} from "./subscription-manager" import {blocksHandler} from "./handlers/blocks" import {blockDigestsHandler} from "./handlers/block_digests" +import {blockHeaderHandler} from "./handlers/block-headers" -const SUBSCRIPTION_HANDLERS = [blocksHandler, blockDigestsHandler] +const SUBSCRIPTION_HANDLERS = [ + blocksHandler, + blockDigestsHandler, + blockHeaderHandler, +] // Map of SubscriptionManager instances by access node URL let subscriptionManagerMap: Map< diff --git a/packages/typedefs/src/index.ts b/packages/typedefs/src/index.ts index 8a6728d8e..f96a0eecf 100644 --- a/packages/typedefs/src/index.ts +++ b/packages/typedefs/src/index.ts @@ -137,6 +137,66 @@ export type BlockDigest = { */ timestamp: string } +/** + * Header contains all meta-data for a block, as well as a hash representing + * the combined payload of the entire block. It is what consensus nodes agree + * on after validating the contents against the payload hash. + */ +// TODO: We do not know the data model types yet and are waiting for the AN team. +export type BlockHeader = { + /** + * TA chain-specific value to prevent replay attacks. + */ + chainId: string + /** + * - The id of the block + */ + id: string + /** + * - The id of the parent block + */ + parentId: string + /** + * - The height of the block + */ + height: number + /** + * - The hash of the block's payload + */ + payloadHash: string + /** + * - The timestamp of the block + */ + timestamp: string + /** + * - The view of the block + */ + view: number + /** + * - The view of the parent block + */ + parentView: number + /** + * - The bitvector that represents all the voters for the parent block + */ + parentVoterIndices: string + /** + * - The aggregated signature over the parent block + */ + parentVoterSigData: string + /** + * - The proposer id of the block + */ + proposerId: string + /** + * - The aggregated signature over the block + */ + proposerSigData: string + /** + * - The last view timeout certificate + */ + lastViewTC: any +} export type CompositeSignature = { /** * - A type identifier used internally by FCL diff --git a/packages/typedefs/src/sdk-transport/subscriptions.ts b/packages/typedefs/src/sdk-transport/subscriptions.ts index b0ecf2f15..a08b9cea6 100644 --- a/packages/typedefs/src/sdk-transport/subscriptions.ts +++ b/packages/typedefs/src/sdk-transport/subscriptions.ts @@ -1,4 +1,4 @@ -import {Block, BlockDigest} from ".." +import {Block, BlockDigest, BlockHeader} from ".." export type SubscriptionSchema = { [SubscriptionTopic.BLOCKS]: SchemaItem< @@ -13,11 +13,18 @@ export type SubscriptionSchema = { blockDigest: BlockDigest } > + [SubscriptionTopic.BLOCK_HEADERS]: SchemaItem< + BlockArgs, + { + blockHeader: BlockHeader + } + > } export enum SubscriptionTopic { BLOCKS = "blocks", BLOCK_DIGESTS = "block_digests", + BLOCK_HEADERS = "block_headers", } type BlockArgs =