You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于NODE_PROPERTIES等节点表的用途、操作及CordaRPCClient功能问询

Corda Node Metadata Tables & RPC Usage Guide

Great questions! Let's break this down step by step, since you're looking to extend node metadata in Corda.

1. What's the purpose of the NODE_PROPERTIES table?

The NODE_PROPERTIES table is Corda's built-in storage for custom node-level key-value attributes. It’s designed specifically to let you store extra, user-defined metadata for your nodes that isn’t covered by Corda’s default node info tables (like NODE_INFOS). Common use cases include storing business-specific identifiers, environment tags, or custom configuration flags that need to persist with the node.

2. How to populate and query NODE_PROPERTIES

You have two reliable approaches here: using Corda's official RPC APIs (recommended) or direct database operations (use cautiously for edge cases).

Populating Key-Value Pairs

Via Corda RPC (Recommended)

Use the NodeManagementService from CordaRPCClient to safely set properties without touching the database directly. Here's a Kotlin example:

import net.corda.client.rpc.CordaRPCClient
import net.corda.core.messaging.start
import net.corda.node.services.api.NodeManagementService

fun setNodeProperty(host: String, port: Int, username: String, password: String, key: String, value: String) {
    val hostAndPort = CordaRPCClientConfiguration.HostAndPort(host, port)
    CordaRPCClient(hostAndPort).start(username, password).use { connection ->
        val nodeManagementService = connection.proxy.serviceHub.cordaService(NodeManagementService::class.java)
        nodeManagementService.setNodeProperty(key, value)
    }
}

This method handles duplicate keys automatically (updating the value if the key already exists).

Direct Database Operation

If you need to bulk-load properties or work outside the RPC context, you can use SQL. Syntax varies slightly by database:

  • MySQL/MariaDB:
    INSERT INTO NODE_PROPERTIES (KEY, VALUE) VALUES ('custom.business.unit', 'retail')
    ON DUPLICATE KEY UPDATE VALUE = 'retail';
    
  • PostgreSQL:
    INSERT INTO NODE_PROPERTIES (KEY, VALUE) VALUES ('custom.business.unit', 'retail')
    ON CONFLICT (KEY) DO UPDATE SET VALUE = EXCLUDED.VALUE;
    

Querying NODE_PROPERTIES

Via Corda RPC

Again, use RPC to stay aligned with Corda's design:

fun getNodeProperties(host: String, port: Int, username: String, password: String): Map<String, String> {
    val hostAndPort = CordaRPCClientConfiguration.HostAndPort(host, port)
    return CordaRPCClient(hostAndPort).start(username, password).use { connection ->
        val nodeManagementService = connection.proxy.serviceHub.cordaService(NodeManagementService::class.java)
        nodeManagementService.getNodeProperties()
    }
}

// To get a single property:
fun getSingleNodeProperty(host: String, port: Int, username: String, password: String, key: String): String? {
    val hostAndPort = CordaRPCClientConfiguration.HostAndPort(host, port)
    return CordaRPCClient(hostAndPort).start(username, password).use { connection ->
        val nodeManagementService = connection.proxy.serviceHub.cordaService(NodeManagementService::class.java)
        nodeManagementService.getNodeProperty(key)
    }
}

Direct Database Query

-- Get all properties
SELECT * FROM NODE_PROPERTIES;

-- Get a specific property value
SELECT VALUE FROM NODE_PROPERTIES WHERE KEY = 'custom.business.unit';

3. Querying other node tables (NODE_INFOS, NODE_NAMED_IDENTITIES, NODE_INFO_HOSTS)

These tables store Corda's core node metadata. You can access this data via RPC (preferred) or direct SQL.

Via Corda RPC

Use the NodeInfoService to fetch structured, type-safe data:

import net.corda.core.node.NodeInfo

fun getCurrentNodeInfo(host: String, port: Int, username: String, password: String): NodeInfo {
    val hostAndPort = CordaRPCClientConfiguration.HostAndPort(host, port)
    return CordaRPCClient(hostAndPort).start(username, password).use { connection ->
        connection.proxy.nodeInfo()
    }
}

// Extract data corresponding to the tables:
val nodeInfo = getCurrentNodeInfo("localhost", 10006, "user1", "test")
// NODE_INFOS: Core node details
val nodeId = nodeInfo.nodeId
val platformVersion = nodeInfo.platformVersion
// NODE_NAMED_IDENTITIES: Legal identities
val legalIdentities = nodeInfo.legalIdentitiesAndCerts.map { it.name.toString() }
// NODE_INFO_HOSTS: Network addresses
val nodeAddresses = nodeInfo.addresses.map { it.hostAndPort }

// To get all nodes in the network:
fun getAllNetworkNodes(host: String, port: Int, username: String, password: String): List<NodeInfo> {
    val hostAndPort = CordaRPCClientConfiguration.HostAndPort(host, port)
    return CordaRPCClient(hostAndPort).start(username, password).use { connection ->
        connection.proxy.networkMapSnapshot()
    }
}

Direct Database Queries

  • NODE_INFOS:
    SELECT ID, NODE_HASH, PLATFORM_VERSION, SERIAL FROM NODE_INFOS;
    
  • NODE_NAMED_IDENTITIES (join with NODE_INFOS for context):
    SELECT ni.NAME, ni.IDENTITY, n.NODE_HASH
    FROM NODE_NAMED_IDENTITIES ni
    JOIN NODE_INFOS n ON ni.NODE_INFO_ID = n.ID;
    
  • NODE_INFO_HOSTS (join with NODE_INFOS):
    SELECT nh.HOST, nh.PORT, n.NODE_HASH
    FROM NODE_INFO_HOSTS nh
    JOIN NODE_INFOS n ON nh.NODE_INFO_ID = n.ID;
    

4. Does CordaRPCClient provide service-level functions for this?

Absolutely! Corda exposes two key RPC services to handle node metadata operations:

  • NodeInfoService: Provides read-only access to node info and network map data (maps directly to NODE_INFOS, NODE_NAMED_IDENTITIES, NODE_INFO_HOSTS). Use nodeInfo() for the current node, networkMapSnapshot() for all network nodes.
  • NodeManagementService: Handles write operations for node properties (via setNodeProperty) and other node management tasks. It's the official way to modify NODE_PROPERTIES safely.

Recommendation for Storing Extra Node Attributes

Stick to using NODE_PROPERTIES with the NodeManagementService RPC calls. This ensures compatibility across Corda versions (direct database queries risk breaking if table structures change) and follows Corda's security and transactional guarantees.

内容的提问来源于stack exchange,提问作者N.S.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:53:22