Rest の/chain/info
と同等の値を取得してみましょう。
ただ、今回はブロック高とファイナライズとパケットタイプが分かれているので、2 つリクエストすることになります。
ブロック高の取得
ノードへリクエスト (ブロック高)
ブロック高を取得するパケットタイプは、0x005
です。もちろん、ペイロードはありません。Catapult.ts
ファイルに追記します。
また、続けてファイナライズもリクエストするので、ソケットを閉じないオプションも付けます。
Catapult.ts
/** パケットタイプ */
private PacketType = {
CHAIN_STATISTICS: 0x0_05,
TIME_SYNC_NETWORK_TIME: 0x1_20,
}
/**
* ChainStatistics取得
* @param isCloase ソケットをクローズするか
* @returns ChainStatistics
*/
async getChainStatistics(isCloase = true) {
let chainStatistics: ChainStatistics | undefined
try {
const socketData = await this.request(this.PacketType.CHAIN_STATISTICS)
if (socketData) chainStatistics = ChainStatistics.deserialize(socketData)
} catch (e) {
if (e instanceof Error) console.error(e.message)
else console.error(e)
} finally {
if (isCloase) this.close()
}
return chainStatistics
}
レスポンスデータの解析(ブロック高)
シリアライズされたデータが返ってくるので、デシリアライズします。
項目 | 長さ |
---|---|
height | 8 バイト |
finalizedHeight | 8 バイト |
scoreHigh | 8 バイト |
scoreLow | 8 バイト |
src/models/ChainStatistics.ts
import { PacketBuffer } from '../PacketBuffer.js'
export class ChainStatistics {
constructor(
public height: bigint,
public finalizedHeight: bigint,
public scoreHigh: bigint,
public scoreLow: bigint
) {}
static deserialize(payload: Uint8Array) {
const bufferView = new PacketBuffer(Buffer.from(payload))
const height = bufferView.readBigUInt64LE()
const finalizedHeight = bufferView.readBigUInt64LE()
const scoreHigh = bufferView.readBigUInt64LE()
const scoreLow = bufferView.readBigUInt64LE()
return new ChainStatistics(height, finalizedHeight, scoreHigh, scoreLow)
}
toJson() {
return {
height: this.height.toString(),
finalizedHeight: this.finalizedHeight.toString(),
scoreHigh: this.scoreHigh.toString(),
scoreLow: this.scoreLow.toString(),
}
}
}
ファイナライズの取得
ノードへリクエスト(ファイナライズ)
ファイナライズを取得するパケットタイプは、0x132
です。これもペイロードはありません。Catapult.ts
ファイルに追記します。
これも同じようにソケットを閉じないオプションを付けます。
Catapult.ts
/** パケットタイプ */
private PacketType = {
CHAIN_STATISTICS: 0x0_05,
TIME_SYNC_NETWORK_TIME: 0x1_20,
FINALIZATION_STATISTICS: 0x1_32,
}
/**
* FinalizationStatistics取得
* @param isCloase ソケットをクローズするか
* @returns FinalizationStatistics
*/
async getFinalizationStatistics(isCloase = true) {
let finalizationStatistics: FinalizationStatistics | undefined
try {
const socketData = await this.request(
this.PacketType.FINALIZATION_STATISTICS
)
if (socketData)
finalizationStatistics = FinalizationStatistics.deserialize(socketData)
} catch (e) {
if (e instanceof Error) console.error(e.message)
else console.error(e)
} finally {
if (isCloase) this.close()
}
return finalizationStatistics
}
レスポンスデータの解析(ファイナライズ)
シリアライズされたデータが返ってくるので、デシリアライズします。
項目 | 長さ |
---|---|
epoch | 4 バイト |
point | 4 バイト |
height | 8 バイト |
hash | 32 バイト |
src/models/FinalizationStatistics.ts
import { PacketBuffer } from "../PacketBuffer.js";
export class FinalizationStatistics {
constructor(
public epoch: number,
public point: number,
public height: bigint,
public hash: string
) {}
static deserialize(payload: Uint8Array) {
const bufferView = new PacketBuffer(Buffer.from(payload));
const epoch = bufferView.readUInt32LE();
const point = bufferView.readUInt32LE();
const height = bufferView.readBigUInt64LE();
const hash = bufferView.readHexString(32).toUpperCase();
return new FinalizationStatistics(epoch, point, height, hash);
}
toJson() {
return {
epoch: this.epoch,
point: this.point,
height: this.height.toString(),
hash: this.hash,
};
}
}
ブロック高とファイナライズをまとめる
2 つをまとめて/chain/info
の形にします。
このメソッドの終わりにソケットを切断します。
Catapult.ts
/**
* /chain/info 同等の値を持つクラスを取得
* @returns ChainInfo
*/
async getChainInfo() {
console.info('ChainInfo')
let chainInfo: ChainInfo | undefined
try {
const chainStat = await this.getChainStatistics(false)
const finalStat = await this.getFinalizationStatistics(false)
if (chainStat && finalStat)
chainInfo = ChainInfo.create(chainStat, finalStat)
} catch (e) {
if (e instanceof Error) console.error(e.message)
else console.error(e)
} finally {
this.close()
}
return chainInfo
}
/chain/info
の形のクラスです。
src/models/ChainInfo.ts
import { ChainStatistics } from "./ChainStatistics.js";
import { FinalizationStatistics } from "./FinalizationStatistics.js";
export class ChainInfo {
constructor(
public height: string,
public scoreHigh: string,
public scoreLow: string,
public latestFinalizedBlock: LatestFinalizedBlock
) {}
static create(chainStat: ChainStatistics, finalStat: FinalizationStatistics) {
const latestFinalizedBlock = new LatestFinalizedBlock(
finalStat.epoch,
finalStat.point,
finalStat.height.toString(),
finalStat.hash
);
return new ChainInfo(
chainStat.height.toString(),
chainStat.scoreHigh.toString(),
chainStat.scoreLow.toString(),
latestFinalizedBlock
);
}
toJson() {
return {
height: this.height.toString(),
scoreHigh: this.scoreHigh.toString(),
scoreLow: this.scoreLow.toString(),
latestFinalizedBlock: this.latestFinalizedBlock.toJson(),
};
}
}
export class LatestFinalizedBlock {
constructor(
public finalizationEpoch: number,
public finalizationPoint: number,
public height: string,
public hash: string
) {}
toJson() {
return {
finalizationEpoch: this.finalizationEpoch,
finalizationPoint: this.finalizationPoint,
height: this.height,
hash: this.hash,
};
}
}
メインの作成
実行するコードを作成します。
src/mainChainInfo.ts
import { Catapult } from './Catapult.js'
const catapult = new Catapult(
'cert/ca.crt.pem',
'cert/node.crt.pem',
'cert/node.key.pem',
'localhost'
)
const chainInfo = await catapult.getChainInfo()
if (chainInfo) console.log(chainInfo)
実行
yarn tsx .\src\mainChainInfo.ts
実行すると以下の様にチェーン情報が出力されます。
ChainInfo
socket connected.
ChainInfo {
height: '141667',
scoreHigh: '0',
scoreLow: '1418022653461819074',
latestFinalizedBlock: LatestFinalizedBlock {
finalizationEpoch: 67,
finalizationPoint: 62,
height: '47520',
hash: 'C820B5484FBE24A2084A33C913E83352E883911B8BE294633786846BA3591317'
}
}
socket close: 5
socket close: 306
バックナンバー