Skip to content

[Advanced]: Implement HIP-1137 β€” Block Node discoverability via on-chain registryΒ #1911

@rwalworth

Description

@rwalworth

🧠 Advanced

This issue is well-suited for contributors who are very familiar with the Hiero Python SDK and enjoy working with its core abstractions and design patterns.

Advanced Issues often involve:

  • Exploring and shaping SDK architecture
  • Reasoning about trade-offs and long-term impact
  • Working across multiple modules or systems
  • Updating tests, examples, and documentation alongside code

The goal is to support thoughtful, high-impact contributions in a clear and collaborative way.

🐞 Problem Description

The Hiero Python SDK does not currently support the registered node registry introduced by HIP-1137. This means SDK users cannot create, update, delete, or discover Block Nodes (or other registered node types such as mirror nodes and RPC relays) via on-chain data.

HIP-1137 adds three new transactions to the AddressBookService and extends several existing types. Without SDK support, developers must resort to raw protobuf construction to interact with the registered node registry.

Key gaps:

  • No RegisteredNodeCreateTransaction, RegisteredNodeUpdateTransaction, or RegisteredNodeDeleteTransaction classes
  • No RegisteredServiceEndpoint hierarchy (BlockNodeServiceEndpoint, MirrorNodeServiceEndpoint, RpcRelayServiceEndpoint)
  • No BlockNodeApi enum
  • TransactionReceipt does not expose the registered_node_id field
  • NodeCreateTransaction and NodeUpdateTransaction do not support the new associated_registered_nodes field
  • No RegisteredNode, RegisteredNodeAddressBook, or RegisteredNodeAddressBookQuery types

πŸ’‘ Proposed / Expected Outcome

Implement full SDK support for HIP-1137 following the SDK design document and the patterns already established in the codebase for consensus node transactions (NodeCreateTransaction, NodeUpdateTransaction, NodeDeleteTransaction).

The implementation should deliver:

New transaction types

  • RegisteredNodeCreateTransaction β€” creates a registered node with an admin_key, optional description, optional node_account_id, and a list of service endpoints (1–50). On success the receipt contains the network-assigned registered_node_id.
  • RegisteredNodeUpdateTransaction β€” updates an existing registered node by registered_node_id. Supports changing admin_key (requires both old and new key signatures), description, node_account_id, and replacing the service endpoint list.
  • RegisteredNodeDeleteTransaction β€” removes a registered node by registered_node_id. Must be signed by the node's admin_key or authorized by network governance.

All three transactions must be schedulable via ScheduleCreateTransaction.

New data types

  • BlockNodeApi enum β€” OTHER, STATUS, PUBLISH, SUBSCRIBE_STREAM, STATE_PROOF.
  • RegisteredServiceEndpoint β€” abstract base with ip_address (bytes) or domain_name (string), port, and requires_tls. Three concrete subclasses:
    • BlockNodeServiceEndpoint β€” adds endpoint_api: BlockNodeApi
    • MirrorNodeServiceEndpoint β€” empty subclass (future-proofing)
    • RpcRelayServiceEndpoint β€” empty subclass (future-proofing)
  • RegisteredNode β€” immutable representation of a registered node as stored in network state.
  • RegisteredNodeAddressBook β€” collection of RegisteredNode objects.

New query type

  • RegisteredNodeAddressBookQuery β€” queries the mirror node for registered nodes and returns a RegisteredNodeAddressBook. Implementation should be deferred until the mirror node API is available, but the class skeleton should be defined.

Updates to existing types

  • TransactionReceipt β€” add optional registered_node_id: int field.
  • NodeCreateTransaction β€” add associated_registered_nodes: list[int] and add_associated_registered_node(registered_node_id: int).
  • NodeUpdateTransaction β€” add optional associated_registered_nodes: list[int] | None, add_associated_registered_node(registered_node_id: int), and clear_associated_registered_nodes(). The protobuf uses a wrapper message for three-state semantics (not set / empty list / non-empty list).

Wiring

  • Register the new transaction types in the Transaction body-to-class mapping (transaction/transaction.py) for deserialization.
  • Map to protobuf oneof cases and schedulable body fields.

🧠 Implementation & Design Notes

Patterns to follow

The existing NodeCreateTransaction / NodeUpdateTransaction / NodeDeleteTransaction in src/hiero_sdk_python/nodes/ serve as the primary reference. Each new registered node transaction should follow the same class structure:

  • Inherit from the base Transaction class
  • Implement _build_transaction_body() and _from_proto() methods
  • Register in the body-to-class mapping in transaction/transaction.py
  • Support scheduling via ScheduleCreateTransaction

Endpoint hierarchy

The design document specifies inheritance-based endpoints. In Python this maps naturally to:

  • An abstract base class RegisteredServiceEndpoint holding shared fields (ip_address, domain_name, port, requires_tls)
  • BlockNodeServiceEndpoint subclass adding endpoint_api
  • MirrorNodeServiceEndpoint and RpcRelayServiceEndpoint as currently empty subclasses

Each subclass needs _from_proto() / _to_proto() round-trip support, following the pattern in src/hiero_sdk_python/address_book/endpoint.py.

Key files to create or modify

New files (under src/hiero_sdk_python/):

  • nodes/registered_node_create_transaction.py
  • nodes/registered_node_update_transaction.py
  • nodes/registered_node_delete_transaction.py
  • address_book/registered_service_endpoint.py
  • address_book/block_node_service_endpoint.py
  • address_book/mirror_node_service_endpoint.py
  • address_book/rpc_relay_service_endpoint.py
  • address_book/block_node_api.py
  • address_book/registered_node.py
  • address_book/registered_node_address_book.py
  • address_book/registered_node_address_book_query.py

Existing files to update:

  • transaction/transaction_receipt.py β€” add registered_node_id
  • nodes/node_create_transaction.py β€” add associated_registered_nodes
  • nodes/node_update_transaction.py β€” add associated_registered_nodes with three-state wrapper semantics
  • transaction/transaction.py β€” register new types in the body-to-class mapping
  • Package __init__.py files β€” export new public types

Protobuf dependencies

The implementation depends on new protobuf definitions from HIP-1137:

  • registered_node_create.proto
  • registered_node_update.proto
  • registered_node_delete.proto
  • registered_service_endpoint.proto (or equivalent)
  • Updated transaction_body.proto (fields 78–80)
  • Updated schedulable_transaction_body.proto (fields 49–51)
  • Updated transaction_receipt.proto (field 16)

Testing strategy

  1. Unit tests β€” verify serialization round-trips for all new types, field validation, and getter/setter correctness.
  2. Integration tests β€” execute the full registered node lifecycle against a test network:
    • Create a registered node with various endpoint types and verify the receipt contains a registered_node_id
    • Update the node's description, endpoints, and admin key
    • Associate a registered node with a consensus node
    • Delete the registered node
    • Verify failure cases (missing admin key, empty endpoints, non-existent node ID, already-deleted node)
  3. TCK alignment β€” corresponding test cases should be defined in the TCK repository per the design document's 18-point test plan.

Schedulability

All three transactions must be schedulable. The SDK already has internal machinery for this β€” ensure each new transaction is included in SchedulableTransactionBody handling.

Response codes

HIP-1137 does not define new response codes at this time. If consensus node implementation introduces registered-node-specific response codes, the SDK's retry logic should be evaluated and updated.

βœ… Acceptance Criteria

A pull request for this issue should:

  • Implement RegisteredNodeCreateTransaction, RegisteredNodeUpdateTransaction, and RegisteredNodeDeleteTransaction following existing transaction patterns
  • Implement the RegisteredServiceEndpoint hierarchy (BlockNodeServiceEndpoint, MirrorNodeServiceEndpoint, RpcRelayServiceEndpoint) and the BlockNodeApi enum
  • Implement RegisteredNode and RegisteredNodeAddressBook data types
  • Define the RegisteredNodeAddressBookQuery class skeleton
  • Update TransactionReceipt to expose registered_node_id
  • Update NodeCreateTransaction and NodeUpdateTransaction with associated_registered_nodes support
  • Register new transaction types in the body-to-class mapping
  • Ensure all three new transactions are schedulable
  • Include unit tests for serialization, field validation, and getter/setter correctness
  • Include integration tests covering the registered node lifecycle (create, update, associate, delete, and failure cases)
  • Export all new public types from package entry points
  • Maintain backwards compatibility with existing APIs
  • Follow existing Python conventions and architectural patterns
  • Pass all CI checks

πŸ“š Additional Context, Links, or Prior Art

Metadata

Metadata

Assignees

Labels

Blockchain / DLTIssues engineering distributed ledger functionalityadvancedrequires knowledge of multiple areas in the codebase without defined steps to implement or examples

Projects

Status

In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions