-
Notifications
You must be signed in to change notification settings - Fork 140
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
HIP-991 update according to latest discussion #1079
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
hip: 991 | ||
title: Permissionless revenue-generating Topic Ids for Topic Operators | ||
author: Michael Kantor (@kantorcodes), Ty Smith (@ty-swirldslabs) | ||
working-group: Michael Heinrichs (@netopyr) | ||
requested-by: TierBot | ||
type: Standards Track | ||
category: Core | ||
|
@@ -10,7 +11,7 @@ status: Accepted | |
last-call-date-time: 2024-07-24T07:00:00Z | ||
created: 2024-06-14 | ||
discussions-to: https://github.com/hashgraph/hedera-improvement-proposal/pull/991 | ||
updated: 2024-09-11 | ||
updated: 2024-11-18 | ||
--- | ||
|
||
## Abstract | ||
|
@@ -90,28 +91,12 @@ We propose adding a fixed fee mechanism to the Hedera Consensus Service (HCS) fo | |
* The Fee Schedule Key can be updated according to the same rules that currently apply to the Submit key. In addition, to update the Fee Schedule Key, the new key must sign the transaction. | ||
* If the topic was created without a Fee Schedule Key, the key cannot be added later. | ||
|
||
#### Fee Payment Pre-Requisites | ||
|
||
* The fee payer must set an allowance (total fees and maximum fee per message) in HBAR or HTS tokens to be used to pay fees for message submissions on an HCS topic basis. | ||
* Allowance granted to a Topic ID does not allow the Topic's Admin Key (or any of the Topic's keys) to spend that allowance outside of fee payments. | ||
|
||
#### Fee Payment Pre-Requisites (SDK) | ||
|
||
* When using the official SDK, the allowance transaction uses the `MAX_FEES` value for total fees and maximum fees per message by default. Developers must explicitly set these values if they don't want the defaults to be applied. | ||
* When sending HCS messages via the SDKs, applications must set the `allowCustomFeesPayment` flag to `true`. | ||
* The default value of the `allowCustomFeesPayment` flag is false. | ||
* If the `allowCustomFeesPayment` flag is not set or is not true, the SDK returns an error. | ||
* The `allowCustomFeesPayment` flag exists only in the SDK and isn't enforced by the network. | ||
|
||
#### Allowance Transactions | ||
|
||
* An account submits a transaction to grant an allowance (total fees and maximum fee per message) to a topic for both HBAR and HTS tokens. This transaction type reuses the existing allowance concept, with no need for a separate delete allowance transaction. To remove an allowance, the user will submit the same transaction with the allowance values set to 0 or a dedicated flag indicating allowance removal. | ||
* This allowance only permits the topic to pay for the custom fees when messages are submitted, not for any other purpose. | ||
|
||
#### Fee Payment | ||
|
||
* The account submitting a message to the topic will cover network transaction fees, and if necessary, a custom fee via the approved allowance. The topic initiates the transfer of the custom fee to the fee collector using `transferFrom`, moving funds from the message sender's account to the designated fee collector. | ||
* No balance will be held by the topic itself. Funds remain in the sender's account, and insufficient funds will result in the message submission failing with an appropriate error. The sender still pays network fees for failed transactions. | ||
* A `ConsensusSubmitMessageTransactionBody` will include a new optional field `max_custom_fee` that a user can set to limit the paid custom fees. | ||
* The account submitting a message to the topic will cover network transaction fees, and if necessary, a custom fee. The topic initiates the transfer of the custom fee to the fee collector using a synthetic `CryptoTransfer`, moving funds from the message sender's account to the designated fee collector. | ||
* If the fee of submitting a message exceeds the `max_custom_fee`, the transaction will fail with an appropriate error. The sender still pays node and network fees for failed transactions. | ||
* No balance will be held by the topic itself. Funds remain in the sender's account, and insufficient funds will result in the message submission failing with an appropriate error. The sender still pays node and network fees for failed transactions. | ||
|
||
#### Fee Exclusions | ||
|
||
|
@@ -123,7 +108,7 @@ We propose adding a fixed fee mechanism to the Hedera Consensus Service (HCS) fo | |
|
||
##### Handling Duplicates | ||
|
||
If the FEKL list contains duplicate keys, the transaction will fail with an `FEKL_CONTAINS_DUPLICATED_KEYS` error. This ensures that duplicate entries are not silently ignored, preventing potential bugs or issues in the calling code. | ||
If the FEKL list contains duplicate keys, the `ConsensusCreateTopicTransaction`, respectively `ConsensusUpdateTopicTransaction`, will fail with a `FEKL_CONTAINS_DUPLICATED_KEYS` error. This ensures that duplicate entries are not silently ignored, preventing potential bugs or issues in the calling code. | ||
|
||
##### Signatures for Invalid/Inactive/Deleted Accounts | ||
|
||
|
@@ -139,16 +124,15 @@ When creating a topic, the FEKL list is independent and must be explicitly popul | |
|
||
### HIP Parameters | ||
|
||
After discussing with the engineering team, the HIP parameters are defined as follow: | ||
The HIP parameters are defined as follow: | ||
|
||
* `MAX_CUSTOM_FEE_ENTRIES_FOR_TOPICS = 10` | ||
* `MAX_ENTRIES_FOR_FEE_EXEMPT_KEY_LIST = 10` | ||
* `MAX_FEE = unsigned int 64` | ||
|
||
### User Flows and Interaction | ||
|
||
* Users will specify the fee settings during the topic creation process through a simple interface in their Hedera client (refer to the creation of token custom fees/fixed fee for reference). | ||
* Before submitting a message to a topic through an application or wallet interface, users must set an allowance and a maximum fee per message. | ||
* When submitting a message to a topic with custom fees through an application or wallet interface, users must set the maximum fee for the message. Alternatively, users can add a flag to accept all custom fees from a topic id. If the topic has no custom fees, neither is required. | ||
* In case of user wallets, applications show the custom fees to the user before submitting the message. | ||
* Operators will get fee collections and distributions automatically through the custom fees just like they do in the token service currently. | ||
|
||
|
@@ -193,7 +177,7 @@ message ConsensusCreateTopicTransactionBody { | |
repeated Key fee_exempt_key_list = 9; | ||
|
||
/** | ||
* The custom fee to be assessed during a message submission to this topic | ||
* The custom fee to be assessed during a message submission to this topic. Empty if no custom fees are applied. | ||
*/ | ||
repeated ConsensusCustomFee custom_fees = 10; | ||
} | ||
|
@@ -207,17 +191,17 @@ The `ConsensusUpdateTopicTransactionBody` message is updated to include the opti | |
message ConsensusUpdateTopicTransactionBody { | ||
[..] | ||
/** | ||
* Access control for update/delete of custom fees. Null if there is no key. | ||
* Access control for update/delete of custom fees. Null if the key should not be updated. | ||
*/ | ||
Key fee_schedule_key = 10; | ||
|
||
/** | ||
* If the transaction contains a signer from this list, no custom fees are applied. | ||
* If the transaction contains a signer from this list, no custom fees are applied. Null if the list should not be updated. | ||
*/ | ||
FeeExemptKeyList fee_exempt_key_list = 11; | ||
|
||
/* | ||
* The custom fee to be assessed during a message submission to this topic | ||
* The custom fee to be assessed during a message submission to this topic. Null if the fees should not be updated. | ||
*/ | ||
ConsensusCustomFeeList custom_fees = 12; | ||
|
||
|
@@ -232,6 +216,25 @@ message ConsensusCustomFeeList { | |
} | ||
``` | ||
|
||
#### ConsensusSubmitMessageTransactionBody | ||
|
||
The `ConsensusSubmitMessageTransactionBody` message is updated to include the optional `max_custom_fees` property for specifying the maximum fee that the user is willing to pay for the message. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to call out that there's a method to set accepts all fees in this section? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added the flag There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that the user must set either a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is needed. If a topic has custom fees and neither |
||
|
||
```protobuf | ||
message ConsensusSubmitMessageTransactionBody { | ||
[..] | ||
/** | ||
* The maximum custom fee that the user is willing to pay for the message. This field will be ignored if `accept_all_custom_fees` is set to `true`. | ||
*/ | ||
repeated FixedFee max_custom_fees = 4; | ||
|
||
/** | ||
* If set to true, the transaction will accept all custom fees from the topic id | ||
*/ | ||
bool accept_all_custom_fees = 5; | ||
} | ||
``` | ||
|
||
#### ConsensusTopicInfo | ||
|
||
The `ConsensusTopicInfo` message is updated to include the Fee Schedule Key and the current list of custom fixed fees associated with the topic. | ||
|
@@ -256,91 +259,6 @@ message ConsensusTopicInfo { | |
} | ||
``` | ||
|
||
#### ConsensusApproveAllowanceTransactionBody | ||
|
||
The `ConsensusApproveAllowanceTransactionBody` message is added and includes one or more `ConsensusCryptoFeeScheduleAllowance` and one or more `ConsensusTokenFeeScheduleAllowance` messages. | ||
|
||
```protobuf | ||
message ConsensusApproveAllowanceTransactionBody { | ||
/** | ||
* List of hbar allowances approved by the account owner. | ||
*/ | ||
repeated ConsensusCryptoFeeScheduleAllowance consensus_crypto_fee_schedule_allowances = 4; | ||
|
||
/** | ||
* List of fungible token allowances approved by the account owner. | ||
*/ | ||
repeated ConsensusTokenFeeScheduleAllowance consensus_token_fee_schedule_allowances = 5; | ||
} | ||
``` | ||
|
||
#### ConsensusCryptoFeeScheduleAllowance | ||
|
||
This is a new protobuf message definition to enable crypto allowance for topics. | ||
|
||
```protobuf | ||
/** | ||
* An approved allowance of hbar transfers for a spender. | ||
*/ | ||
message ConsensusCryptoFeeScheduleAllowance { | ||
/** | ||
* The account ID of the hbar owner (ie. the grantor of the allowance). | ||
*/ | ||
AccountID owner = 1; | ||
|
||
/** | ||
* The topic ID enabled to spend fees from the hbar allowance. | ||
*/ | ||
TopicID spender = 2; | ||
|
||
/** | ||
* The amount of the spender's allowance in tinybars. | ||
*/ | ||
uint64 amount = 3; | ||
|
||
/** | ||
* The maximum amount of the spender's token allowance per message. | ||
*/ | ||
uint64 amount_per_message = 4; | ||
} | ||
``` | ||
|
||
#### ConsensusTokenFeeScheduleAllowance | ||
|
||
This is a new protobuf message definition to enable token allowance for topics. | ||
|
||
```protobuf | ||
/** | ||
* An approved allowance of fungible token transfers for a spender. | ||
*/ | ||
message ConsensusTokenFeeScheduleAllowance { | ||
/** | ||
* The token that the allowance pertains to. | ||
*/ | ||
TokenID tokenId = 1; | ||
|
||
/** | ||
* The account ID of the token owner (ie. the grantor of the allowance). | ||
*/ | ||
AccountID owner = 2; | ||
|
||
/** | ||
* The topic ID enabled to spend fees from the token allowance. | ||
*/ | ||
TopicID spender = 3; | ||
|
||
/** | ||
* The maximum amount of the spender's token allowance. | ||
*/ | ||
uint64 amount = 4; | ||
|
||
/** | ||
* The maximum amount of the spender's token allowance per message. | ||
*/ | ||
uint64 amount_per_message = 5; | ||
} | ||
``` | ||
|
||
### Mirror Node | ||
|
||
To comply with this HIP, the Mirror Node provides the following features: | ||
|
@@ -350,61 +268,6 @@ To comply with this HIP, the Mirror Node provides the following features: | |
|
||
#### REST API changes | ||
|
||
Here is the list of endpoints affected by this HIP and the expected changes. | ||
|
||
* `/api/v1/accounts/{idOrAliasOrEvmAddress}/allowances/crypto` | ||
* The endpoint lists allowances set by both `CONSENSUSAPPROVEALLOWANCE` and `CRYPTOAPPROVEALLOWANCE` | ||
* Changes to query parameters. Topic IDs are valid parameters for the `spender.id` field. | ||
* Changes in the body of the response. The response includes the new `amount_per_message` field, and may include topic IDs in the spender field. A sample response payload follows. | ||
|
||
```json | ||
{ | ||
"allowances": [ | ||
{ | ||
"amount": 75, | ||
"amount_per_message": 5, | ||
"amount_granted": 100, | ||
"owner": "0.0.2", | ||
"spender": "0.0.2", | ||
"timestamp": { | ||
"from": "1586567700.453054000", | ||
"to": "1586567700.453054000" | ||
} | ||
} | ||
], | ||
"links": { | ||
"next": null | ||
} | ||
} | ||
``` | ||
|
||
* `/api/v1/accounts/{idOrAliasOrEvmAddress}/allowances/tokens` | ||
* The endpoint lists allowances set by both `CONSENSUSAPPROVEALLOWANCE` and `CRYPTOAPPROVEALLOWANCE` | ||
* Changes to query parameters. Topic IDs are valid parameters for the `spender.id` field. | ||
* Changes in the body of the response. The response includes the new `amount_per_message` field, and may include topic IDs in the spender field. A sample response payload follows. | ||
|
||
```json | ||
{ | ||
"allowances": [ | ||
{ | ||
"amount": 75, | ||
"amount_per_message": 5, | ||
"amount_granted": 100, | ||
"owner": "0.0.2", | ||
"spender": "0.0.2", | ||
"timestamp": { | ||
"from": "1586567700.453054000", | ||
"to": "1586567700.453054000" | ||
}, | ||
"token_id": "0.0.2" | ||
} | ||
], | ||
"links": { | ||
"next": null | ||
} | ||
} | ||
``` | ||
|
||
* `/api/v1/topics/{topicId}` | ||
* Changes to the body of the response. The response should include three new fields: `fee_schedule_key`, `fee_exempt_key_list`, and `custom_fee`. The fields will expose any data defined in their corresponding protobuffer definition. A sample response payload follows. | ||
|
||
|
@@ -455,10 +318,6 @@ Here is the list of endpoints affected by this HIP and the expected changes. | |
} | ||
``` | ||
|
||
* `/api/v1/transactions` | ||
* Changes in query parameters. The new allowance transaction type `CONSENSUSAPPROVEALLOWANCE` is included in the list of supported transaction type for the `transactiontype` parameter. | ||
* Changes in the body of the response. The endpoint returns the same fields as `CRYPTOAPPROVEALLOWANCE`. | ||
|
||
### SDKs | ||
|
||
This document does not include the details of the implementation updates required by the SDKs to comply with the HIP-991 specifications. | ||
|
@@ -472,9 +331,7 @@ There are no known backward compatibility issues. Existing topics without custom | |
|
||
## Security Implications | ||
|
||
The introduction of custom fees adds another layer of economic control, but also introduces potential vectors for abuse, such as fee manipulation. To address these issues, this HIP adheres to current security requirements regarding the authorization of moving user funds. In particular, before being able to send paid HCS messages to a topic, users should first set an allowance for the recipient topic, just as in the case of HTS, to allow payment of fixed or custom fees. The user can also set a maximum charge per message. | ||
|
||
At the network level, the default value for both allowance parameters is 0. At SDK level, the fees (total maximum amount and maximum fee per message) are always the maximum amount `MAX_FEE`. For this reason, the SDK documentation should contain a considerable callout on this point and be clear about the implications of not changing these default values. | ||
The introduction of custom fees adds another layer of economic control, but also introduces potential vectors for abuse, such as fee manipulation. To address these issues, this HIP adheres to current security requirements regarding the authorization of moving user funds. In particular, the user can set a maximum charge for each message. | ||
|
||
## How to Teach This | ||
|
||
|
@@ -496,7 +353,7 @@ const feeCollectorAccountId = AccountId.fromString("0.0.12345"); | |
|
||
// Define the fixed fee | ||
const topicCustomFee = new TopicCustomFee() | ||
.setAmount(100) // 100 tokens are transferred to the fee collecting account each time this token is transferred | ||
.setAmount(100) // 100 tokens are transferred to the fee collecting account each time a message is submitted to the topic | ||
.setDenominatingTokenId(TokenId.fromString("0.0.56789")) // // The token to charge the fee in. HBAR if unset | ||
.setFeeCollectorAccountId(feeCollectorAccountId); // 100 tokens are sent to this account for each HCS message to the topic | ||
|
||
|
@@ -519,9 +376,14 @@ transactionResponse = new TopicAllowanceApproveTransaction() | |
|
||
[...] | ||
|
||
// Define max custom fee | ||
const maxCustomFee = new FixedFee() | ||
.setAmount(100) // a maximum of 100 tokens is paid for submitting the message | ||
.setDenominatingTokenId(TokenId.fromString("0.0.56789")); // The token to charge the fee in. HBAR if unset | ||
|
||
// Send message to the topic | ||
transactionResponse = await new TopicMessageSubmitTransaction({ topicId: topicId, message: "Hello, HCS!" }) | ||
.setAllowCustomFeesPayment(true) // Make the agreement on payment explicit at the application level. Useful for any backend / non-front-user-facing application. | ||
.setMaxCustomFees([maxCustomFee]) // Set the maximum fee for the message | ||
.execute(client); | ||
|
||
``` | ||
|
@@ -531,7 +393,6 @@ This implementation shows the creation of a topic where each message submission | |
## Rejected Ideas | ||
|
||
* Setting a mandatory network enforced `allowCustomFeesPayment` flag in HCS message transactions to allow payment of fees. | ||
* Setting 0 as default in SDKs for maximum fees. | ||
|
||
## References | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
FEKL_CONTAINS_DUPLICATED_KEYS
can be renamed toFEE_EXEMPT_KEY_LIST_CONTAINS_DUPLICATED_KEYS
.