4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Windows と TypeScript ではじめる Symbol 通信 03【ブロック高】

Last updated at Posted at 2024-12-12

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

バックナンバー

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?