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
バックナンバー