3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

nem / symbolAdvent Calendar 2024

Day 14

Windows と TypeScript ではじめる Symbol 通信 04【ノード情報】

Last updated at Posted at 2024-12-13

Rest の/node/infoと同等の値を取得してみましょう。

ノード情報の取得

ノードへリクエスト

ブロック高を取得するパケットタイプは、0x111です。ペイロードはありません。Catapult.tsファイルに追記します。

ノード公開鍵まで返ってこないので、ソケットを繋いだときにノード証明書が取得出来るので、これから取り出すようにします。

Catapult.ts
/** パケットタイプ */
private PacketType = {
  CHAIN_STATISTICS: 0x0_05,
  NODE_DISCOVERY_PULL_PING: 0x1_11,
  TIME_SYNC_NETWORK_TIME: 0x1_20,
  FINALIZATION_STATISTICS: 0x1_32,
}

/**
 * /node/info 同等の値を持つクラスを取得
 * @returns NodeInfo
 */
async getNodeInfo(): Promise<NodeInfo | undefined> {
  console.info('NodeInfo')
  let nodeInfo: NodeInfo | undefined
  try {
    // ピア問合せ
    const socketData = await this.request(
      this.PacketType.NODE_DISCOVERY_PULL_PING
    )
    if (socketData)
      nodeInfo = NodeInfo.deserialize(socketData, this.x509Certificate)
  } catch (e) {
    if (e instanceof Error) console.error(e.message)
    else console.error(e)
  } finally {
    this.close()
  }
  return nodeInfo
}

レスポンスデータの解析

シリアライズされたデータが返ってくるので、デシリアライズします。

項目 長さ
version 4 バイト
publicKey 32 バイト
networkGenerationHashSeed 32 バイト
roles 4 バイト
port 2 バイト
networkIdentifier 1 バイト
hostLength 1 バイト
friendlyNameLength 1 バイト
host hostLength バイト
friendlyName friendlyNameLength バイト

せっかくノード証明書を持ってきたので、ついでに有効期限も取得してみます。

src/models/ChainStatistics.ts
import { X509Certificate } from 'node:crypto'
import { PacketBuffer } from '../PacketBuffer.js'

export class NodeInfo {
  constructor(
    public version: number,
    public publicKey: string,
    public networkGenerationHashSeed: string,
    public roles: number,
    public port: number,
    public networkIdentifier: number,
    public host: string,
    public friendlyName: string,
    public nodePublicKey?: string,
    public certificateExpirationDate?: Date
  ) {}

  static deserialize(payload: Uint8Array, cert?: X509Certificate) {
    const nodeBufferView = new PacketBuffer(Buffer.from(payload))
    const version = nodeBufferView.readUInt32LE(4)
    const publicKey = nodeBufferView.readHexString(32).toUpperCase()
    const networkGenerationHashSeed = nodeBufferView
      .readHexString(32)
      .toUpperCase()
    const roles = nodeBufferView.readUInt32LE()
    const port = nodeBufferView.readUInt16LE()
    const networkIdentifier = nodeBufferView.readUInt8()
    const hostLength = nodeBufferView.readUInt8()
    const friendlyNameLength = nodeBufferView.readUInt8()
    const host = nodeBufferView.readString(hostLength)
    const friendlyName = nodeBufferView.readString(friendlyNameLength)
    // 証明書有効期限、ノード公開鍵取得
    let nodePublicKey: string | undefined
    let certificateExpirationDate: Date | undefined
    if (cert) {
      nodePublicKey = cert.publicKey
        .export({
          format: 'der',
          type: 'spki',
        })
        .toString('hex', 12, 44)
        .toUpperCase()
      const { validTo } = cert
      const validToDate = new Date(validTo)
      certificateExpirationDate = validToDate
    }
    return new NodeInfo(
      version,
      publicKey,
      networkGenerationHashSeed,
      roles,
      port,
      networkIdentifier,
      host,
      friendlyName,
      nodePublicKey,
      certificateExpirationDate
    )
  }
}

メインの作成

実行するコードを作成します。

src/mainNodeInfo.ts
import { Catapult } from './Catapult.js'

const catapult = new Catapult(
  'cert/ca.crt.pem',
  'cert/node.crt.pem',
  'cert/node.key.pem',
  'localhost'
)

const nodeInfo = await catapult.getNodeInfo()
if (nodeInfo) console.log(nodeInfo)

実行

yarn tsx .\src\mainNodeInfo.ts

実行すると以下の様にノード情報が出力されます。

NodeInfo
socket connected.
NodeInfo {
  version: 16777991,
  publicKey: 'B502FCBDA9147ABDB12CB2A9BBADCBC57716AEADCCCA9B11926C1A0BDDDB7D8E',
  networkGenerationHashSeed: '49D6E1CE276A85B70EAFE52349AACCA389302E7A9754BCF1221E79494FC665A4',
  roles: 3,
  port: 7900,
  networkIdentifier: 152,
  host: 'sakia.harvestasya.com',
  friendlyName: 'sakia/.',
  nodePublicKey: '19792496483B0B71D5F997DBE8660131CFEC49E55773C5B065C106258B70F475',
  certificateExpirationDate: 2025-11-27T12:18:30.000Z
}
socket close: 273

バックナンバー

3
0
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
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?