Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
200 changes: 200 additions & 0 deletions HIP/hip-1299.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
---
hip: 1299
title: Node Account ID Refinements for Dynamic Address Book
author: Richard Bair (@rbair23), Joseph Sinclair (@jsync-swirlds)
type: Standards Track
category: Service
needs-hiero-approval: Yes
needs-hedera-review: Yes
status: Last Call
last-call-date-time: 2025-10-27T07:00:00Z
created: 2025-09-29
updated: 2025-10-13
requires: 869
---

## Abstract
This proposal refines the rules for managing the account ID associated with
Node entries in the Dynamic Address Book (DAB). The DAB is a feature that
stores information about network nodes, such as their identifiers and associated
accounts, directly in the network's state instead of in Hedera File Service (
HFS) files. This makes updates more secure and consistent.

The refinements focus on how account IDs can be updated, removed, or set, with
an emphasis on security through required signatures, preventing reuse of the
same account ID across multiple nodes, and handling cases where accounts lack
sufficient funds. These changes provide flexibility for node operators while
protecting the network from disruptions.

## Motivation
HIP-869 introduced the DAB, allowing node information to be stored and updated
dynamically. Each node entry includes an immutable unique node ID and an account
ID, which is used for receiving fees and rewards and paying penalties.

As we enable rotations of the account ID—meaning changing the account linked to
a node—we've identified new scenarios that need clear rules. For example, we
need to ensure changes are authorized, prevent one low-balance account from
affecting multiple nodes, and handle what happens if an account can't receive
rewards or pay penalties. These updates make the system more robust without
complicating day-to-day operations.

## Rationale
This design is based on a few straightforward principles:
- Changes to a node's account ID must be approved by the right parties to
prevent unauthorized access or mistakes.
- Updates take effect immediately. Rewards and penalties use the account ID in
effect at the time of calculation.
- The system checks for issues like low account balances and prevents account
deletions if they're still linked to nodes.
- No single account ID can be used for more than one node, so problems with one
account don't spread.
- If rewards can't be delivered to an account (for example, if it's invalid),
they're sent to a special system account (`0.0.801`) instead of causing
errors.

These rules balance flexibility for operators with network stability and
security.

## Specification

### Overview
This proposal does not change the NodeUpdateTransactionBody, which already
supports changes to the `account_id` field. Here's the relevant part of the
existing protocol buffer definition, with additional clarity added to the
specification text.

```protobuf
/**
* An account identifier.
* <p>
* To remove, send a transaction setting it to 0.0.0 signed by the current
* account owner or the node admin key.
* <p>
* To set or swap, send a transaction setting it to the new account_id value
* signed by (the current account owner or the node admin key) AND the new
* account owner.
* <p>
* The new account number MUST be a valid, existing account if not 0.0.0.
* <p>
* The same account_id cannot be used across multiple nodes.
* <p>
* While an account is assigned to the `account_id` for a Node, that account
* cannot be deleted.
*/
proto.AccountID account_id = 2;
```
To protect accounts, the node operator cannot delete an account if it is linked
to any node in the Node Store. The node operator must first remove the account
from the Node entry, and then the account may be deleted.

Rewards and penalties use the account ID that's active at the time. If a reward
can't be delivered, it's forfeited to account `0.0.801`. The system ignores
any "receiver signature required" settings and doesn't trigger extra actions (
hooks).

If a penalty cannot be paid because the account has zero balance, or if the
account is otherwise encumbered, the node is removed from the roster at the next
roster update, following rules from other proposals on roster updates.

No changes are made to NodeCreateTransactionBody, so new nodes still need an
initial account ID, signed by both the node admin and the account owner.

No changes are made to NodeDeleteTransactionBody, which removes the entire node
entry.

### Implementation Details
- **Validation**: For setting a new account ID, the system checks that the
account exists and the transaction is signed by its key. If the node admin key
isn't signing, it also needs the current account's signature. For removal (
setting to `0.0.0`), it's signed by either the current account or the node
admin. Repeating the same account ID is allowed (idempotent). Invalid accounts
Comment thread
rbair23 marked this conversation as resolved.
are rejected. The system ensures no other node uses the same account ID.
- **Effective Timing**: Changes apply immediately.
- **Roster Construction**: Nodes without a valid account ID, or with
insufficient funds, when a new roster is adopted are excluded from that new
roster.
- **Reward Distribution**: Rewards go to the active account ID. If it fails,
they go to `0.0.801`. Receiver signatures are ignored, and no hooks run.
- **Penalties**: Penalties deduct from the active account ID. If balance is too
low to pay current penalties, the node is removed from the roster at the next
roster update, and may be immediately prevented from submitting new consensus
events.
Comment thread
mgarbs marked this conversation as resolved.
- **Account Deletion Interlock**: Deletion fails if the account is in any Node
entry. The Node operator must remove the account from that Node first, and
then delete the node.
- **Queries**: Mirror nodes (which provide network data) show the current Node
state from the DAB and can show pending changes if asked.
- **In-Flight Transactions**: Transactions accepted before a node update to
change an account ID are processed based on the node state at consensus time.
If the account ID has changed by then, the transaction may fail or be
redirected appropriately, but clients should retry on different nodes using
up-to-date information.

## Backward Compatibility
These changes add new options without breaking existing setups. Current nodes
keep their account IDs. Tools that use account IDs for identification continue
working.

Older clients might encounter issues if they hard-code node details and an
account ID changes. To avoid this, use software development kits (SDKs) that
automatically fetch the latest node list from mirror nodes and retry
transactions on different nodes if needed. These clients will also need to
ensure that no node account values are hardcoded or provided to the SDK without
first querying the current state of the node or nodes involved.

## Record File Effects
The Record File uploader processes will continue to use the old Account ID when
calculating file path information until the next network upgrade. This is
intended to provide stability for mirror node and other record file clients.
This *only* impacts the *path* in the cloud bucket, and does not have any
interaction with the content of record files or the signature keys (which is
determined by Roster data).

Mirror Nodes and other users of the record files will need to keep track of the
current Account ID until the next network upgrade in order to continue reading
files from the correct path. The network will continue to update file `0.0.102`
following a network upgrade, so this may be used as a clear indicator for when
the record file paths might change.

## Security Implications
Required signatures prevent unauthorized changes: removals need the current
account or node admin, additions need the new account, and swaps need
combinations to protect everyone.

Operators should watch account balances to avoid auto-removal or penalties.
Forbidding shared account IDs limits the impact of one bad account.

Undeliverable rewards are handled cleanly by forfeiture. All changes are logged
in transaction records for auditing. The extra checks add little performance
cost.

## How to Teach This
1. **For Node Operators**: You can now change your node's account ID with a
signed transaction, giving you more control over finances. Changes take
effect immediately and rewards are paid at 00:00 UTC, so plan ahead. Keep
enough balance to avoid automatic removal.
2. **For Developers**: Workflows change little. Check mirror nodes for updated
DAB entries. SDKs will handle new fields for updates. Applications that do
not use an SDK may consider pre-signing transactions for multiple nodes in
case the first node attempted rejects the transaction due to an account ID
change.
3. **Examples**:
- **Removing an Account ID**: Submit a NodeUpdateTransactionBody setting
`account_id` to `0.0.0`, signed by the current account or node admin. The
node is excluded from the next roster and transactions can no longer be
submitted to that node immediately after the transaction is executed.
- **Setting a New Account ID**: Set account_id to the new value, signed by
the node admin and the new account. If the node has no admin key, sign with
the old and new accounts.
- **Swapping Account IDs**: Similar to setting, with signatures from (old
account or admin) and new account.
Document this in guides for the Hedera API (HAPI) and DAB, including tips on
balances.

## References
- [HIP-869: Dynamic Address Book](https://hips.hedera.com/hip/hip-869)

## Copyright
This document is licensed under the Apache License, Version 2.0 —
see[LICENSE](https://hips.hedera.com/LICENSE)
or https://www.apache.org/licenses/LICENSE-2.0.
Loading