-
Notifications
You must be signed in to change notification settings - Fork 191
HIP-1299 account_id updates for Address Book Node Entries.
#1299
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | ||
| 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. | ||
|
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. | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.