|
| 1 | +--- |
| 2 | +hip: 1299 |
| 3 | +title: Node Account ID Refinements for Dynamic Address Book |
| 4 | +author: Richard Bair (@rbair23), Joseph Sinclair (@jsync-swirlds) |
| 5 | +type: Standards Track |
| 6 | +category: Service |
| 7 | +needs-hiero-approval: Yes |
| 8 | +needs-hedera-review: Yes |
| 9 | +status: Draft |
| 10 | +created: 2025-09-29 |
| 11 | +updated: 2025-10-07 |
| 12 | +requires: HIP-869 |
| 13 | +--- |
| 14 | + |
| 15 | +## Abstract |
| 16 | +This proposal refines the rules for managing the account ID associated with |
| 17 | +Node entries in the Dynamic Address Book (DAB). The DAB is a feature that |
| 18 | +stores information about network nodes, such as their identifiers and associated |
| 19 | +accounts, directly in the network's state instead of in Hedera File Service ( |
| 20 | +HFS) files. This makes updates more secure and consistent. |
| 21 | + |
| 22 | +The refinements focus on how account IDs can be updated, removed, or set, with |
| 23 | +an emphasis on security through required signatures, preventing reuse of the |
| 24 | +same account ID across multiple nodes, and handling cases where accounts lack |
| 25 | +sufficient funds. These changes provide flexibility for node operators while |
| 26 | +protecting the network from disruptions. |
| 27 | + |
| 28 | +## Motivation |
| 29 | +HIP-869 introduced the DAB, allowing node information to be stored and updated |
| 30 | +dynamically. Each node entry includes an immutable unique node ID and an account |
| 31 | +ID, which is used for receiving fees and rewards and paying penalties. |
| 32 | + |
| 33 | +As we enable rotations of the account ID—meaning changing the account linked to |
| 34 | +a node—we've identified new scenarios that need clear rules. For example, we |
| 35 | +need to ensure changes are authorized, prevent one low-balance account from |
| 36 | +affecting multiple nodes, and handle what happens if an account can't receive |
| 37 | +rewards or pay penalties. These updates make the system more robust without |
| 38 | +complicating day-to-day operations. |
| 39 | + |
| 40 | +## Rationale |
| 41 | +This design is based on a few straightforward principles: |
| 42 | +- Changes to a node's account ID must be approved by the right parties to |
| 43 | + prevent unauthorized access or mistakes. |
| 44 | +- Updates take effect immediately. Rewards and penalties use the account ID in |
| 45 | + effect at the time of calculation. |
| 46 | +- The system checks for issues like low account balances and prevents account |
| 47 | + deletions if they're still linked to nodes. |
| 48 | +- No single account ID can be used for more than one node, so problems with one |
| 49 | + account don't spread. |
| 50 | +- If rewards can't be delivered to an account (for example, if it's invalid), |
| 51 | + they're sent to a special system account (`0.0.801`) instead of causing |
| 52 | + errors. |
| 53 | + |
| 54 | +These rules balance flexibility for operators with network stability and |
| 55 | +security. |
| 56 | + |
| 57 | +## Specification |
| 58 | + |
| 59 | +### Overview |
| 60 | +This proposal does not change the NodeUpdateTransactionBody, which already |
| 61 | +supports changes to the `account_id` field. Here's the relevant part of the |
| 62 | +existing protocol buffer definition, with additional clarity added to the |
| 63 | +specification text. |
| 64 | + |
| 65 | +```protobuf |
| 66 | +/** |
| 67 | + * An account identifier. |
| 68 | + * <p> |
| 69 | + * To remove, send a transaction setting it to 0.0.0 signed by the current |
| 70 | + * account owner or the node admin key. |
| 71 | + * <p> |
| 72 | + * To set or swap, send a transaction setting it to the new account_id value |
| 73 | + * signed by (the current account owner or the node admin key) AND the new |
| 74 | + * account owner. |
| 75 | + * <p> |
| 76 | + * The new account number MUST be a valid, existing account if not 0.0.0. |
| 77 | + * <p> |
| 78 | + * The same account_id cannot be used across multiple nodes. |
| 79 | + * <p> |
| 80 | + * While an account is assigned to the `account_id` for a Node, that account |
| 81 | + * cannot be deleted. |
| 82 | + */ |
| 83 | + proto.AccountID account_id = 2; |
| 84 | +``` |
| 85 | +To protect accounts, the node operator cannot delete an account if it is linked |
| 86 | +to any node in the Node Store. The node operator must first remove the account |
| 87 | +from the Node entry, and then the account may be deleted. |
| 88 | + |
| 89 | +Rewards and penalties use the account ID that's active at the time. If a reward |
| 90 | +can't be delivered, it's forfeited to account `0.0.801`. The system ignores |
| 91 | +any "receiver signature required" settings and doesn't trigger extra actions ( |
| 92 | +hooks). |
| 93 | + |
| 94 | +If a penalty cannot be paid because the account has zero balance, or if the |
| 95 | +account is otherwise encumbered, the node is removed from the roster at the next |
| 96 | +roster update, following rules from other proposals on roster updates. |
| 97 | + |
| 98 | +No changes are made to NodeCreateTransactionBody, so new nodes still need an |
| 99 | +initial account ID, signed by both the node admin and the account owner. |
| 100 | + |
| 101 | +No changes are made to NodeDeleteTransactionBody, which removes the entire node |
| 102 | +entry. |
| 103 | + |
| 104 | +### Implementation Details |
| 105 | +- **Validation**: For setting a new account ID, the system checks that the |
| 106 | + account exists and the transaction is signed by its key. If the node admin key |
| 107 | + isn't signing, it also needs the current account's signature. For removal ( |
| 108 | + setting to `0.0.0`), it's signed by either the current account or the node |
| 109 | + admin. Repeating the same account ID is allowed (idempotent). Invalid accounts |
| 110 | + are rejected. The system ensures no other node uses the same account ID. |
| 111 | +- **Effective Timing**: Changes apply immediately. |
| 112 | +- **Roster Construction**: Nodes without a valid account ID, or with |
| 113 | + insufficient funds, when a new roster is adopted are excluded from that new |
| 114 | + roster. |
| 115 | +- **Reward Distribution**: Rewards go to the active account ID. If it fails, |
| 116 | + they go to `0.0.801`. Receiver signatures are ignored, and no hooks run. |
| 117 | +- **Penalties**: Penalties deduct from the active account ID. If balance is too |
| 118 | + low to pay current penalties, the node is removed from the roster at the next |
| 119 | + roster update, and may be immediately prevented from submitting new consensus |
| 120 | + events. |
| 121 | +- **Account Deletion Interlock**: Deletion fails if the account is in any Node |
| 122 | + entry. The Node operator must remove the account from that Node first, and |
| 123 | + then delete the node. |
| 124 | +- **Queries**: Mirror nodes (which provide network data) show the current Node |
| 125 | + state from the DAB and can show pending changes if asked. |
| 126 | +- **In-Flight Transactions**: Transactions accepted before a node update to |
| 127 | + change an account ID are processed based on the node state at consensus time. |
| 128 | + If the account ID has changed by then, the transaction may fail or be |
| 129 | + redirected appropriately, but clients should retry on different nodes using |
| 130 | + up-to-date information. |
| 131 | + |
| 132 | +## Backward Compatibility |
| 133 | +These changes add new options without breaking existing setups. Current nodes |
| 134 | +keep their account IDs. Tools that use account IDs for identification continue |
| 135 | +working. |
| 136 | + |
| 137 | +Older clients might encounter issues if they hard-code node details and an |
| 138 | +account ID changes. To avoid this, use software development kits (SDKs) that |
| 139 | +automatically fetch the latest node list from mirror nodes and retry |
| 140 | +transactions on different nodes if needed. These clients will also need to |
| 141 | +ensure that no node account values are hardcoded or provided to the SDK without |
| 142 | +first querying the current state of the node or nodes involved. |
| 143 | + |
| 144 | +## Record File Effects |
| 145 | +The Record File uploader processes will continue to use the old Account ID when |
| 146 | +calculating file path information until the next network upgrade. This is |
| 147 | +intended to provide stability for mirror node and other record file clients. |
| 148 | +This *only* impacts the *path* in the cloud bucket, and does not have any |
| 149 | +interaction with the content of record files or the signature keys (which is |
| 150 | +determined by Roster data). |
| 151 | + |
| 152 | +Mirror Nodes and other users of the record files will need to keep track of the |
| 153 | +current Account ID until the next network upgrade in order to continue reading |
| 154 | +files from the correct path. The network will continue to update file `0.0.102` |
| 155 | +following a network upgrade, so this may be used as a clear indicator for when |
| 156 | +the record file paths might change. |
| 157 | + |
| 158 | +## Security Implications |
| 159 | +Required signatures prevent unauthorized changes: removals need the current |
| 160 | +account or node admin, additions need the new account, and swaps need |
| 161 | +combinations to protect everyone. |
| 162 | + |
| 163 | +Operators should watch account balances to avoid auto-removal or penalties. |
| 164 | +Forbidding shared account IDs limits the impact of one bad account. |
| 165 | + |
| 166 | +Undeliverable rewards are handled cleanly by forfeiture. All changes are logged |
| 167 | +in transaction records for auditing. The extra checks add little performance |
| 168 | +cost. |
| 169 | + |
| 170 | +## How to Teach This |
| 171 | +1. **For Node Operators**: You can now change your node's account ID with a |
| 172 | + signed transaction, giving you more control over finances. Changes take |
| 173 | + effect immediately and rewards are paid at 00:00 UTC, so plan ahead. Keep |
| 174 | + enough balance to avoid automatic removal. |
| 175 | +2. **For Developers**: Workflows change little. Check mirror nodes for updated |
| 176 | + DAB entries. SDKs will handle new fields for updates. Applications that do |
| 177 | + not use an SDK may consider pre-signing transactions for multiple nodes in |
| 178 | + case the first node attempted rejects the transaction due to an account ID |
| 179 | + change. |
| 180 | +3. **Examples**: |
| 181 | + - **Removing an Account ID**: Submit a NodeUpdateTransactionBody setting |
| 182 | + `account_id` to `0.0.0`, signed by the current account or node admin. The |
| 183 | + node is excluded from the next roster and transactions can no longer be |
| 184 | + submitted to that node immediately after the transaction is executed. |
| 185 | + - **Setting a New Account ID**: Set account_id to the new value, signed by |
| 186 | + the node admin and the new account. If the node has no admin key, sign with |
| 187 | + the old and new accounts. |
| 188 | + - **Swapping Account IDs**: Similar to setting, with signatures from (old |
| 189 | + account or admin) and new account. |
| 190 | +Document this in guides for the Hedera API (HAPI) and DAB, including tips on |
| 191 | +balances. |
| 192 | + |
| 193 | +## References |
| 194 | +- [HIP-869: Dynamic Address Book](https://hips.hedera.com/hip/hip-869) |
| 195 | + |
| 196 | +## Copyright |
| 197 | +This document is licensed under the Apache License, Version 2.0 — |
| 198 | +see[LICENSE](https://hips.hedera.com/LICENSE) |
| 199 | +or https://www.apache.org/licenses/LICENSE-2.0. |
0 commit comments