HIP-1137: Block Node discoverabilty via the network address book
Author | Joseph Sinclair |
---|---|
Working Group | Joseph Sinclair, Jasper Potts, Richard Bair, Nana Essilfie-Conduah |
Requested By | Mirror Node Operators, Relay Node Operators, SDK developers |
Discussions-To | https://github.com/hashgraph/Hiero-improvement-proposal/discussions/1132 |
Status | Draft ⓘ |
Needs Council Approval | Yes ⓘ |
Type | Standards Track ⓘ |
Category | Core ⓘ |
Created | 2025-03-07 |
Updated | 2025-05-28 |
Table of Contents
Abstract
With the addition of Block Nodes to the Hiero ledger, clients will need a reliable mechanism to find functioning block nodes. This HIP proposes to add a new type of address book entry, and transactions to enable block node operators to add and manage their nodes in the network.
Motivation
Block Nodes are a critical component of any Hiero ledger. The Block Nodes manage and provide access to Block Stream and state snapshot data, as well as content proof for both blocks and state. Block Nodes may also provide additional value-add services integral to their core function, and may charge fees for providing both core and value-add services to clients. A service is of no value, however, if the service provider cannot be found. Offering a mechanism to find a Block Node by querying network state ensures a reliable and trustworthy source of data that is dynamically managed and updated by the Block Node operators themselves.
Rationale
Discoverability of services is critical to a broadly useful network and effective development of network applications. The addition of basic service discovery functionality supports the current addition of block nodes to the network, and lays groundwork for adding additional discovery mechanisms in future proposals. While the proximate motivation for this capability is to enable discoverability of block nodes, it is also clear that block nodes are not the only form of discoverable nodes that could, or should, be published on the blockchain.
Definitions
- Discoverable Node
- A node that participates in a Hiero Ledger network, but is not a consensus node, is a discoverable node, and may be discovered via the node discovery process. Discoverable nodes do not require on-chain upgrade coordination and are generally managed as fully independent individual entities. Each type of discoverable node has its own mechanism for discovering and using resources specific to that type of node. The address book only provides the type of node and one or more service endpoints.
User stories
- As a RPC Relay client, I wish to find an RPC relay using on-chain data.
- As a Block Node, I need to connect to other block nodes found by inspecting block stream data.
- As a Mirror Node, I want to present discoverable nodes to clients using on-chain data.
- As a Hiero community member, I want to operate a discoverable node and publish the type and endpoints on-chain so that others can find my service.
- As the operator of a private Hiero ledger, I want to mange the discoverable nodes relevant to my ledger using on-chain data.
- As a discoverable node operator, I want to publish and manage my discoverable node on a Hiero ledger so that clients can reliably find and connect to my service.
Specification
This HIP proposes the introduction of additional NodeService APIs that enable a discoverable node operator to create, delete, and update discoverable nodes.
Several messages refer to a “Node ID”. This is a single entity number that is assigned on node creation by the network, and is unique within a particular shard and realm. Discoverable nodes are specific to a shard and realm, although nothing technically prevents a single system from being registered as a node in multiple shards or multiple realms. The consensus network may assign any value to a new node, except that a given Node ID must never be reused within a given shard or realm. The Node ID values for Discoverable Nodes must not match the Node ID value for any consensus node in the same network.
service AddressBookService {
[...]
/**
* A transaction to create a new discoverable node in the network
* address book.
* <p>
* This transaction, once complete, SHALL add a new discoverable node to the
* network state.<br/>
* The new discoverable node SHALL be visible and discoverable upon
* completion of this transaction.
*/
rpc createDiscoverableNode (proto.Transaction) returns (proto.TransactionResponse);
/**
* A transaction to remove a discoverable node from the network address
* book.
* <p>
* This transaction, once complete, SHALL remove the identified discoverable
* node from the network state.
*/
rpc deleteDiscoverableNode (proto.Transaction) returns (proto.TransactionResponse);
/**
* A transaction to update an existing discoverable node in the network
* address book.
* <p>
* This transaction, once complete, SHALL modify the identified discoverable
* node state as requested.
*/
rpc updateDiscoverableNode (proto.Transaction) returns (proto.TransactionResponse);
}
A new Hiero API element will be added, named DiscoverableServiceEndpoint.
/**
* A discoverable network node endpoint.<br/>
* Each discoverable network node in the global address book publishes one or
* more endpoints which enable the nodes to communicate both with other
* nodes and with clients to receive requests.
*
* This message supports a TCP port and IP address (V4 or V6),
* or MAY include a FQDN _instead of_ an IP address.<br/>
*/
message DiscoverableServiceEndpoint {
oneof address {
/**
* A 32-bit IPv4 address or 128-bit IPv6 address.<br/>
* This is the address of the endpoint, encoded in pure "big-endian"
* (i.e. left to right) order (e.g. `127.0.0.1` has hex bytes in the
* order `7F`, `00`, `00`, `01` and `::1` is `00`, `00`, `00`, `00`,
* `00`, `00`, `00`, `00`, `00`, `00`, `00`, `00`, `00`, `00`,
* `00`, `01`).
*/
bytes ip_address = 1;
/**
* A node domain name.
* <p>
* This MUST be the fully qualified domain name of the node.<br/>
* This value MUST NOT exceed 250 ASCII characters.<br/>
* This value MUST meet all other DNS name requirements.
*/
string domain_name = 2;
}
/**
* A network port to use.
* <p>
* This value MUST be between 0 and 65535, inclusive.<br/>
* This value is REQUIRED.
*/
uint32 port = 3;
}
A new Hiero API will be added called DiscoverableNodeCreate, which falls under the Node Service category. This function is used by the node operator to create a new node.
message DiscoverableNodeCreateTransactionBody {
/**
* An administrative key controlled by the node operator.
* <p>
* This key MUST sign this transaction.<br/>
* This key MUST sign each transaction to update this node.<br/>
* This field MUST contain a valid `Key` value.<br/>
* This field is REQUIRED and MUST NOT be set to an empty `KeyList`.<br/>
* It is RECOMMENDED that this key be composed of one or more unique public
* keys that are not associated with any network account.<br/>
* This key MAY be a complex key containing `KeyList` or `ThresholdKey`
* elements, but SHOULD NOT be a contract ID key.
*/
proto.Key admin_key = 1;
/**
* A node type.<br/>
* This declares the type of discoverable node. Examples might include
* a block node, an rpc relay, or a mirror node.
* <p>
* This field is REQUIRED.
*/
DiscoverableNodeType node_type = 2;
/**
* A short description of the node.
* <p>
* This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8.<br/>
* This field is OPTIONAL.
*/
string description = 3;
/**
* A list of service endpoints for client calls.
* <p>
* These endpoints SHALL represent the published endpoints to which
* clients may submit requests.<br/>
* Endpoints in this list MAY supply either IP address or FQDN, but MUST
* NOT supply both values for the same endpoint.<br/>
* This list MUST NOT be empty.<br/>
* This list MUST NOT contain more than `10` entries.
*/
repeated DiscoverableServiceEndpoint service_endpoint = 4;
}
/**
* An enumeration of discoverable node types.
*
* These values SHALL represent all _supported_ discoverable nodes.
*/
enum DiscoverableNodeType {
/**
* This value indicates unset or missing data and MUST NOT be used.
*/
UNKNOWN = 0;
/**
* A Block Node.<br/>
* A Block Node stores the block chain, provides content proof services,
* and delivers the block stream to other clients.
*/
BLOCK_NODE = 1;
/**
* A Hiero Mirror Node.<br/>
* A Mirror Node is an advanced indexing and query service that provides
* fast and flexible access to query the block chain and transaction
* history. A Mirror Node typically stores all recent blockchain data, and
* some store the entire history of the network.
*/
MIRROR_NODE = 2;
/**
* A RPC Relay node.<br/>
* A RPC Relay Node is a proxy and translator between EVM tooling and a
* Hiero consensus network.
*/
RPC_RELAY = 3;
}
A new Hiero API called DiscoverableNodeDelete will be added under the Node Service. This API function is used by the node operator to delete a node.
message DiscoverableNodeDeleteTransactionBody {
/**
* A discoverable node identifier in the network state.
* <p>
* The node identified MUST exist in the discoverable address book.<br/>
* The node identified MUST NOT be deleted.<br/>
* This value is REQUIRED.
* <p>
* A given value for `node_id` SHALL be unique within a given
* shard or realm.<br/>
* A given value for `node_id` SHALL NOT be reused, even if the
* corresponding entry is deleted.
*/
uint64 node_id = 1;
}
A new Hiero API called DiscoverableNodeUpdate will be added under the Node Service. This function is used by the node operator to update a node.
message DiscoverableNodeUpdateTransactionBody {
/**
* A discoverable node identifier in the network state.
* <p>
* The node identified MUST exist in the discoverable address book.<br/>
* The node identified MUST NOT be deleted.<br/>
* This value is REQUIRED.
* <p>
* A given value for `node_id` SHALL be unique within a given
* shard or realm.<br/>
* A given value for `node_id` SHALL NOT be reused, even if the
* corresponding entry is deleted.
*/
uint64 node_id = 1;
/**
* An administrative key controlled by the node operator.
* <p>
* This field is OPTIONAL.<br/>
* If set, this key MUST sign this transaction.<br/>
* If set, this key MUST sign each subsequent transaction to
* update this node.<br/>
* If set, this field MUST contain a valid `Key` value.<br/>
* If set, this field MUST NOT be set to an empty `KeyList`.<br/>
* It is RECOMMENDED that this key be composed of one or more unique public
* keys that are not associated with any network account.<br/>
* This key MAY be a complex key containing `KeyList` or `ThresholdKey`
* elements, but SHOULD NOT be a contract ID key.
*/
proto.Key admin_key = 2;
/**
* A short description of the node.
* <p>
* This field is OPTIONAL.<br/>
* This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8.<br/>
* If set, this value SHALL replace the previous value.
*/
google.protobuf.StringValue description = 3;
/**
* A list of service endpoints for client calls.
* <p>
* This field is OPTIONAL.<br/>
* These endpoints SHALL represent the published endpoints to which
* clients may submit requests.<br/>
* Endpoints in this list MAY supply either IP address or FQDN, but MUST
* NOT supply both values for the same endpoint.<br/>
* If set, this list MUST NOT be empty.<br/>
* If set, this list MUST NOT contain more than `10` entries.<br/>
* If set, this list SHALL _replace_ the previous list.
*/
repeated DiscoverableServiceEndpoint service_endpoint = 4;
}
The Hiero consensus network will store discoverable node information in state with the following message structure.
message DiscoverableAddressBookNode {
/**
* A discoverable node identifier.
* <p>
* This value SHALL be set.<br/>
* This value SHALL be unique within a given network.<br/>
* This value SHALL NOT match any consensus node ID in the same network.
* <p>
* A given value for `node_id` MUST be unique within a given
* shard or realm.<br/>
* A given value for `node_id` MUST NOT be reused, even if the
* corresponding entry is later deleted.
*/
uint64 node_id = 1;
/**
* An administrative key controlled by the node operator.
* <p>
* This key MUST sign each transaction to update this node.<br/>
* This field SHALL contain a valid `Key` value.<br/>
* This field SHALL NOT be set to an empty `KeyList`.<br/>
* It is RECOMMENDED that this key be composed of one or more unique public
* keys that are not associated with any network account.<br/>
* This key MAY be a complex key containing `KeyList` or `ThresholdKey`
* elements, but SHOULD NOT be a contract ID key.
*/
proto.Key admin_key = 2;
/**
* A short description of the node.
* <p>
* This value SHALL NOT exceed 100 bytes when encoded as UTF-8.
*/
string description = 3;
/**
* A list of service endpoints for client calls.
* <p>
* These endpoints SHALL represent the published endpoints to which
* clients may submit requests.<br/>
* This list SHALL NOT be empty.<br/>
* This list SHALL NOT contain more than `10` entries.
*/
repeated DiscoverableServiceEndpoint service_endpoint = 4;
}
The following are some changes to the existing API.
Added three HieroFunctionalities:
enum HieroFunctionality {
[...]
/**
* Create a discoverable node
*/
DiscoverableNodeCreate = 101;
/**
* Update a discoverable node
*/
DiscoverableNodeUpdate = 102;
/**
* Delete a discoverable node
*/
DiscoverableNodeDelete = 103;
}
Adjusted node_id
in TransactionReceipt
:
message TransactionReceipt {
[...]
/**
* The identifier of a newly created Node or DiscoverableNode.
* <p>
* This value SHALL be set following a `createNode` transaction.<br/>
* This value SHALL be set following a `createDiscoverableNode`
* transaction.<br/>
* This value SHALL NOT be set following any other transaction.<br/>
* This value SHALL be unique within a given network.<br/>
* This value SHALL NOT match any consensus node ID in the same network.
*/
uint64 node_id = 15;
}
Mirror node update
The mirror node will process the new Discoverable Node transactions and
discoverable_service_endpoint information, then return that information through
extensions to its existing APIs or new APIs, as needed.
One possible extension would be to add a /api/v1/network/discoverableNodes
resource which accepts a nodeType
query parameter and returns a list of nodes
with that type, or a list of all discoverable nodes if the parameter is not
supplied.
SDK Considerations
Each SDK will need to implement the following new transactions.
createDiscoverableNode
updateDiscoverableNode
deleteDiscoverableNode
There is no change to existing transactions. The create transaction sets the samenode_id
field in the transaction receipt used by the existing non-discoverable nodeCreate transaction.
Backwards Compatibility
All changes for this HIP are net-new functionality. There is no predicted impact or change for existing functionality.
Security Implications
The signatory for all discoverable node transactions (create, update, delete)
is the assigned admin_key
value for that node. This maintains management of
each discoverable node firmly with the creator/operator. Discoverable nodes do
not participate in any form of consensus network rewards, so no account
identifier is required for a discoverable node. It is RECOMMENDED that the
admin_key
be composed of one or more unique public keys that are not
associated with any network account.
The network throttles will need to be updated to place appropriate limits on the number of discoverable node transactions. Such transactions should not be frequent, and relevant throttles should have corresponding limits.
We do not expect to place any restriction on who can create a discoverable node,
and the only limitation to who can update or delete a discoverable node is that
the transaction must be signed by the admin_key
for that node.
How to Teach This
TBD
Reference Implementation
Rejected Ideas
- Use of the existing consensus node address book and transactions was
considered.
- This was rejected for three reasons.
- The existing Node transactions and state objects include a substantial amount of data that has no relevancy to discoverable nodes
- The consensus nodes do not, and should not, include the additional information specific to discoverable nodes
- The modification of discoverable nodes and consensus nodes have vastly different risk profiles, and mandate very different signatory requirements.
- This was rejected for three reasons.
Open Issues
- We intended to store a uint64 “reputation” value for each discoverable node,
but have not determined an appropriate and workable mechanism for allowing
network entities to “vote” on that reputation.
- One concept discussed is to use something similar to a “proof of space-time” and a “proof of streaming” for block nodes (as one example) as an automated “reputation” modifier. How this would be integrated with community sentiment remains an open question.
- This concept should be the subject of a future HIP.
References
Copyright/license
This document is licensed under the Apache License, Version 2.0 – see LICENSE or (https://www.apache.org/licenses/LICENSE-2.0)
Citation
Please cite this document as: