Skip to content

Commit

Permalink
almost done
Browse files Browse the repository at this point in the history
  • Loading branch information
Officeyutong committed Dec 1, 2024
1 parent 1f59662 commit 6d4b74f
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 34 deletions.
1 change: 1 addition & 0 deletions light-client-db-worker/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
/pkg
/node_modules
/index.d.ts
/package-lock.json
1 change: 1 addition & 0 deletions light-client-js/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/yarn.lock
/node_modules
/dist
/package-lock.json
8 changes: 4 additions & 4 deletions light-client-js/package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
{
{
"name": "light-client-js",
"version": "1.0.0",
"main": "dist/index.js",
"license": "MIT",
"devDependencies": {
"@ckb-ccc/ccc": "^0.0.16-alpha.7",
"@ckb-ccc/core": "^0.1.0-alpha.5",
"ts-loader": "^9.5.1",
"typescript": "^5.7.2",
"webpack": "^5.96.1",
"webpack-cli": "^5.1.4"
},
"dependencies": {
"light-client-db-worker": "file:../light-client-db-worker",
"light-client-wasm": "file:../light-client-wasm"
"light-client-wasm": "file:../light-client-wasm",
"stream-browserify": "^3.0.0",
"@ckb-ccc/core": "https://gitpkg.vercel.app/Officeyutong/ccc/packages/core?a1b8a02"
},
"scripts": {
"build-debug": "webpack --mode=development --stats-children",
Expand Down
49 changes: 25 additions & 24 deletions light-client-js/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { ClientFindCellsResponse, ClientFindTransactionsGroupedResponse, ClientFindTransactionsResponse, ClientIndexerSearchKeyLike, ClientIndexerSearchKeyTransactionLike, ClientTransactionResponse } from "@ckb-ccc/core/src/client";
import { FetchResponse, transformFetchResponse } from "./types";
import { JsonRpcTransformers } from "@ckb-ccc/core/src/client/jsonRpc/transformers";
import { Num, numFrom, NumLike, numToHex } from "@ckb-ccc/core/src/num";
import { Hex, hexFrom, HexLike, TransactionLike } from "@ckb-ccc/core/src/barrel";
import { ClientFindCellsResponse, ClientFindTransactionsGroupedResponse, ClientFindTransactionsResponse, ClientIndexerSearchKeyLike, ClientIndexerSearchKeyTransactionLike, ClientTransactionResponse } from "@ckb-ccc/core/client";
import { FetchResponse, JsonRpcLocalNode, JsonRpcRemoteNode, JsonRpcScriptStatus, LocalNode, localNodeTo, RemoteNode, remoteNodeTo, ScriptStatus, scriptStatusFrom, scriptStatusTo, transformFetchResponse } from "./types";
import { JsonRpcTransformers } from "@ckb-ccc/core/client/jsonRpc/transformers";
import { Num, numFrom, NumLike, numToHex } from "@ckb-ccc/core/num";
import { ClientBlock, ClientBlockHeader, Hex, hexFrom, HexLike, TransactionLike } from "@ckb-ccc/core/barrel";
import { JsonRpcBlockHeader } from "@ckb-ccc/core/advancedBarrel";
const DEFAULT_BUFFER_SIZE = 50 * (1 << 20);
/**
* A LightClient instance
Expand All @@ -28,17 +29,17 @@ class LightClient {
/**
* Start the light client.
*/
async start() {
async start(logLevel: "debug" | "info" = "info") {
this.dbWorker.postMessage({
inputBuffer: this.inputBuffer,
outputBuffer: this.outputBuffer,
logLevel: "info"
logLevel: logLevel
});
this.lightClientWorker.postMessage({
inputBuffer: this.inputBuffer,
outputBuffer: this.outputBuffer,
netName: "dev",
logLevel: "info"
logLevel: logLevel
});
await new Promise<void>((res, rej) => {
this.dbWorker.onmessage = () => res();
Expand Down Expand Up @@ -71,31 +72,31 @@ class LightClient {
* Returns the header with the highest block number in the canonical chain
* @returns HeaderView
*/
async getTipHeader(): Promise<any> {
return await this.invokeLightClientCommand("get_tip_header");
async getTipHeader(): Promise<ClientBlockHeader> {
return JsonRpcTransformers.blockHeaderTo(await this.invokeLightClientCommand("get_tip_header"));
}
/**
* Returns the genesis block
* @returns BlockView
*/
async getGenesisBlock(): Promise<any> {
return await this.invokeLightClientCommand("get_genesis_block");
async getGenesisBlock(): Promise<ClientBlock> {
return JsonRpcTransformers.blockTo(await this.invokeLightClientCommand("get_genesis_block"));
}
/**
* Returns the information about a block header by hash.
* @param hash the block hash, equal to Vec<u8> in Rust
* @returns HeaderView
*/
async getHeader(hash: HexLike): Promise<any> {
return await this.invokeLightClientCommand("get_header", [hexFrom(hash)]);
async getHeader(hash: HexLike): Promise<ClientBlockHeader> {
return JsonRpcTransformers.blockHeaderTo(await this.invokeLightClientCommand("get_header", [hexFrom(hash)]));
}
/**
* Fetch a header from remote node. If return status is not_found will re-sent fetching request immediately.
* @param hash the block hash, equal to Vec<u8> in Rust
* @returns FetchHeaderResponse
*/
async fetchHeader(hash: HexLike): Promise<FetchResponse<any>> {
return await this.invokeLightClientCommand("fetch_header", [hexFrom(hash)]);
async fetchHeader(hash: HexLike): Promise<FetchResponse<ClientBlockHeader>> {
return transformFetchResponse(await this.invokeLightClientCommand("fetch_header", [hexFrom(hash)]), (arg: JsonRpcBlockHeader) => JsonRpcTransformers.blockHeaderTo(arg));
}
/**
* See https://github.com/nervosnetwork/ckb/tree/develop/rpc#method-estimate_cycles
Expand All @@ -109,29 +110,29 @@ class LightClient {
* Returns the local node information.
* @returns LocalNode
*/
async localNodeInfo(): Promise<any> {
return await this.invokeLightClientCommand("local_node_info");
async localNodeInfo(): Promise<LocalNode> {
return localNodeTo(await this.invokeLightClientCommand("local_node_info") as JsonRpcLocalNode);
}
/**
* Returns the connected peers' information.
* @returns
*/
async getPeers(): Promise<any> {
return await this.invokeLightClientCommand("get_peers");
async getPeers(): Promise<RemoteNode[]> {
return (await this.invokeLightClientCommand("get_peers") as JsonRpcRemoteNode[]).map(x => remoteNodeTo(x));
}
/**
* Set some scripts to filter
* @param scripts Array of script status
* @param command An optional enum parameter to control the behavior of set_scripts
*/
async setScripts(scripts: any, command: any): Promise<void> {
await this.invokeLightClientCommand("set_scripts", [scripts, command]);
async setScripts(scripts: ScriptStatus[], command?: "all" | "partial" | "delete"): Promise<void> {
await this.invokeLightClientCommand("set_scripts", [scripts.map(x => scriptStatusFrom(x)), command]);
}
/**
* Get filter scripts status
*/
async getScripts(): Promise<any[]> {
return await this.invokeLightClientCommand("get_scripts");
async getScripts(): Promise<ScriptStatus[]> {
return (await this.invokeLightClientCommand("get_scripts") as JsonRpcScriptStatus[]).map(x => scriptStatusTo(x));
}
/**
* See https://github.com/nervosnetwork/ckb-indexer#get_cells
Expand Down
132 changes: 131 additions & 1 deletion light-client-js/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import { JsonRpcScript, JsonRpcTransformers } from "@ckb-ccc/core/advancedBarrel";
import { Script } from "@ckb-ccc/core/barrel";
import { Num } from "@ckb-ccc/core/num";

interface WorkerInitializeOptions {
inputBuffer: SharedArrayBuffer;
outputBuffer: SharedArrayBuffer;
Expand Down Expand Up @@ -28,10 +32,136 @@ export function transformFetchResponse<A, B>(input: FetchResponse<A>, fn: (arg:
return input;
}

type JsonRpcScriptType = "lock" | "type";

interface JsonRpcScriptStatus {
script: JsonRpcScript;
script_type: JsonRpcScriptType;
block_number: Num;
}

interface ScriptStatus {
script: Script,
scriptType: JsonRpcScriptType,
blockNumber: Num
}

export function scriptStatusTo(input: JsonRpcScriptStatus): ScriptStatus {
return ({
blockNumber: input.block_number,
script: JsonRpcTransformers.scriptTo(input.script),
scriptType: input.script_type
})
}

export function scriptStatusFrom(input: ScriptStatus): JsonRpcScriptStatus {
return ({
block_number: input.blockNumber,
script: JsonRpcTransformers.scriptFrom(input.script),
script_type: input.scriptType
})
}

interface NodeAddress {
address: string;
score: Num;
}

interface RemoteNodeProtocol {
id: Num;
version: string;
}

interface JsonRpcRemoteNode {
version: string;
node_id: string;
addresses: NodeAddress[];
connected_duration: Num;
sync_state?: any;
protocols: RemoteNodeProtocol[];

}

interface RemoteNode {
version: string;
nodeId: string;
addresses: NodeAddress[];
connestedDuration: Num;
syncState?: any;
protocols: RemoteNodeProtocol[];
}

export function remoteNodeTo(input: JsonRpcRemoteNode): RemoteNode {
return ({
addresses: input.addresses,
connestedDuration: input.connected_duration,
nodeId: input.node_id,
protocols: input.protocols,
version: input.version,
syncState: input.sync_state
})
}

interface JsonRpcLocalNodeProtocol {
id: Num;
name: string;
support_version: string[];
}


interface LocalNodeProtocol {
id: Num;
name: string;
supportVersion: string[];
}

export function localNodeProtocolTo(input: JsonRpcLocalNodeProtocol): LocalNodeProtocol {
return ({
id: input.id,
name: input.name,
supportVersion: input.support_version
})
}

interface JsonRpcLocalNode {
version: string;
node_id: string;
active: boolean;
addresses: NodeAddress[];
protocols: JsonRpcLocalNodeProtocol[];
connections: bigint;
}

interface LocalNode {
version: string;
nodeId: string;
active: boolean;
addresses: NodeAddress[];
protocols: LocalNodeProtocol[];
connections: bigint;
}

export function localNodeTo(input: JsonRpcLocalNode): LocalNode {
return ({
nodeId: input.node_id,
protocols: input.protocols.map(x => localNodeProtocolTo(x)),
active: input.active,
addresses: input.addresses,
connections: input.connections,
version: input.version
})
}

export type {
LightClientFunctionCall,
WorkerInitializeOptions,
DbWorkerInitializeOptions,
LightClientWorkerInitializeOptions,
FetchResponse
FetchResponse,
JsonRpcScriptStatus,
ScriptStatus,
JsonRpcRemoteNode,
RemoteNode,
LocalNode,
JsonRpcLocalNode
}
6 changes: 3 additions & 3 deletions light-client-js/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
"outDir": "./dist/",
"noImplicitAny": true,
"module": "ES2020",
"target": "ES2015",
"target": "ES2020",
"allowJs": true,
"moduleResolution": "node",
"mapRoot": "dist",
"sourceMap": true,
"declaration": true,
Expand All @@ -19,7 +18,8 @@
"lib": [
"ES2017",
"WebWorker"
]
],
"moduleResolution": "bundler"
},
"exclude": [
"webpack.config.js",
Expand Down
1 change: 1 addition & 0 deletions light-client-js/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ module.exports = {
},
resolve: {
extensions: ['.ts', '.js'],
fallback: { "stream": require.resolve("stream-browserify") }
},
mode: "production",
experiments: {
Expand Down
6 changes: 4 additions & 2 deletions light-client-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ static NET_CONTROL: OnceLock<NetworkController> = OnceLock::new();

static CONSENSUS: OnceLock<Arc<Consensus>> = OnceLock::new();

static SERIALIZER: Serializer = Serializer::new().serialize_large_number_types_as_bigints(true);
static SERIALIZER: Serializer = Serializer::new()
.serialize_large_number_types_as_bigints(true)
.serialize_maps_as_objects(true);

/// 0b0 init
/// 0b1 start
Expand Down Expand Up @@ -218,7 +220,7 @@ pub async fn light_client(net_flag: String, log_level: String) -> Result<(), JsV
}

#[wasm_bindgen]
pub async fn stop() {
pub fn stop() {
broadcast_exit_signals();
STORAGE_WITH_DATA.get().unwrap().storage().shutdown();
change_status(0b10);
Expand Down

0 comments on commit 6d4b74f

Please sign in to comment.