Skip to content

Commit 12116a9

Browse files
update HIP with latest protobufs and changes
Signed-off-by: Neeharika-Sompalli <neeharika.sompalli@swirldslabs.com>
1 parent f4085bf commit 12116a9

1 file changed

Lines changed: 108 additions & 54 deletions

File tree

HIP/hip-1261.md

Lines changed: 108 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
hip: 1261
33
title: Simple Fees
44
author: Richard Bair <@rbair23>
5-
working-group: Richard Bair <@rbair23>, Jasper Potts <@jasperpotts>, Joshua Marinacci <@joshmarinacci>, Atul Mahamuni <@atul-hedera>, Keith Kowal <keith.kowal@swirldslabs.com>, Steven Sheehy <@steven-sheehy>
5+
working-group: Richard Bair <@rbair23>, Jasper Potts <@jasperpotts>, Joshua Marinacci <@joshmarinacci>, Atul Mahamuni <@atul-hedera>, Keith Kowal <keith.kowal@swirldslabs.com>, Steven Sheehy <@steven-sheehy>, Neeharika Sompalli <@Neeharika-Sompalli>
66
requested-by: Hashgraph
77
type: Standards Track
88
category: Core
@@ -16,7 +16,7 @@ hedera-acceptance-decision: Accepted
1616
discussions-to: https://github.com/hiero-ledger/hiero-improvement-proposals/pull/1261
1717
requires: 1259
1818
created: 2025-07-02
19-
updated: 2026-05-20
19+
updated: 2026-07-19
2020
---
2121

2222
# Abstract
@@ -242,53 +242,61 @@ The basic structure of this JSON follow can be seen below:
242242

243243
### Extras
244244

245-
Extras are fees *in addition to* the `baseFee`. They are defined once in the configuration, and referenced by name
246-
throughout the document. The fee **must** be defined. When computing fees, we simply tally up the number of extras, and
247-
add the tally to the `baseFee` to determine the fee component.
245+
Extras are fees *in addition to* the `baseFee`. The supported extras are defined by the `Extra` enumeration in the
246+
schema. Each configured extra is defined once in the configuration and referenced by its enum value throughout the
247+
document. The fee **must** be defined. When computing fees, we simply tally up the number of extras, and add the tally
248+
to the `baseFee` to determine the fee component.
248249

249250
```json
250251
{
251252
"extras": [
252253
{
253-
"name": "Signatures",
254+
"name": "SIGNATURES",
254255
"fee": 100000
255256
},
256257
{
257-
"name": "Bytes",
258+
"name": "PROCESSING_BYTES",
258259
"fee": 10000
259260
},
260261
{
261-
"name": "Keys",
262+
"name": "KEYS",
262263
"fee": 10000000
263264
},
264265
...
265266
]
266267
}
267268
```
268269

269-
The following table lists each extra, its name, and the description.
270-
| Extra | Description |
271-
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
272-
| Signatures | Number of signatures on the transaction (at most one verification per signature). |
273-
| Bytes | Size of the transaction in protobuf bytes. |
274-
| Keys | The number of keys being defined on this transaction. For example, when creating an account, this is the number of keys on the account. A threshold key with 10 keys counts as 10 keys. Nested key structures count up all keys. |
275-
| TokenTypes | Number of token types referenced. |
276-
| NFTSerials | Number of distinct NFT serials. |
277-
| Accounts | Number of accounts loaded to handle the transaction. |
278-
| StandardFungibleTokens | Number of standard fungible tokens (no custom fees). |
279-
| StandardNonFungibleTokens | Number of standard NFTs (no custom fees). |
280-
| CustomFeeFungibleTokens | Number of fungible tokens with custom fees. |
281-
| CustomFeeNonFungibleTokens | Number of NFTs with custom fees. |
282-
| CreatedAutoAssociations | Number of auto-associations created. |
283-
| CreatedAccounts | Number of hollow accounts created (e.g., via transfers to aliases). |
284-
| CustomFee | If custom fees are defined for the created entity. |
285-
| Gas | Gas cost (includes execution of hook programs). |
286-
| Allowances | Number of allowances. |
287-
| Airdrops | Number of airdrops executed. |
288-
| HooksCreated | Number of hooks created on an account or contract. |
289-
| HooksDeleted | Number of hooks deleted from an account or contract. |
290-
| HooksModified | Number of hooks modified on an account or contract (e.g., updated admin key, storage). |
291-
| HookInvocations | Number of hook programs invoked during transaction execution (e.g., pre-/post-transaction hook calls). |
270+
The `Extra` enumeration in the schema is authoritative. It currently defines the following extras:
271+
272+
| Extra | Description |
273+
| --- | --- |
274+
| `SIGNATURES` | Number of transaction signatures verified. |
275+
| `KEYS` | Number of keys processed, including nested keys. |
276+
| `NFT_SERIALS` | Number of distinct NFT serials processed. |
277+
| `ACCOUNTS` | Number of accounts involved in the operation. |
278+
| `TOKEN_TYPES` | Number of token types involved in the operation. |
279+
| `GAS` | Gas consumed or configured as included gas. |
280+
| `ALLOWANCES` | Number of allowances processed. |
281+
| `AIRDROPS` | Number of airdrops processed. |
282+
| `HOOK_UPDATES` | Number of hook updates processed. |
283+
| `TOKEN_TRANSFER_BASE` | Base surcharge for a token transfer without custom fees. |
284+
| `TOKEN_TRANSFER_BASE_CUSTOM_FEES` | Base surcharge for a token transfer with custom fees. |
285+
| `HOOK_EXECUTION` | Hook execution work performed by an operation. |
286+
| `TOKEN_CREATE_WITH_CUSTOM_FEE` | Surcharge for creating a token with custom fees. |
287+
| `TOKEN_MINT_NFT` | Number of NFTs minted. |
288+
| `CONSENSUS_CREATE_TOPIC_WITH_CUSTOM_FEE` | Surcharge for creating a topic with custom fees. |
289+
| `CONSENSUS_SUBMIT_MESSAGE_WITH_CUSTOM_FEE` | Surcharge for submitting a message to a topic with custom fees. |
290+
| `SCHEDULE_CREATE_CONTRACT_CALL_BASE` | Base surcharge for scheduling a contract call. |
291+
| `TOKEN_ASSOCIATE` | Number of token associations created. |
292+
| `HOOK_SLOT_UPDATE` | Number of hook storage slots updated. |
293+
| `TOKEN_MINT_NFT_BASE` | Base surcharge for an NFT mint. |
294+
| `NFT_UPDATE` | Number of NFTs updated. |
295+
| `RECORDS` | Number of records produced or returned. |
296+
| `STATE_BYTES` | Bytes persisted in state. |
297+
| `PROCESSING_BYTES` | Bytes processed by the node or network. |
298+
| `CONSENSUS_SUBMIT_MESSAGE_WITH_CUSTOM_FEE_BYTES` | Message bytes submitted to a topic with custom fees. |
299+
| `CONSENSUS_SUBMIT_MESSAGE_WITHOUT_CUSTOM_FEE_BYTES` | Message bytes submitted to a topic without custom fees. |
292300
### Node
293301

294302
The *node* fee is computed exactly the same way for all transactions. It is therefore defined in one place in the
@@ -299,8 +307,8 @@ configuration and applicable to all transactions.
299307
"node": {
300308
"baseFee": 100000,
301309
"extras": [
302-
{"name": "Bytes", "includedCount": 1024},
303-
{"name": "Signatures", "includedCount": 1}
310+
{"name": "PROCESSING_BYTES", "includedCount": 1024},
311+
{"name": "SIGNATURES", "includedCount": 1}
304312
]
305313
}
306314
}
@@ -332,7 +340,7 @@ such `extra`, an `includedCount` *may* be specified, indicating how many of that
332340
"baseFee": 499000000,
333341
"extras": [
334342
{
335-
"name": "Keys",
343+
"name": "KEYS",
336344
"includedCount": 1
337345
}
338346
]
@@ -361,8 +369,19 @@ totalFee = 100000 + 900000 + 499000000
361369

362370
</aside>
363371

364-
`extras` are referred to by name. The `includedCount`, if specified, must be a non-negative integer value. If not
365-
specified, the default value for an `includedCount` is 0.
372+
`extras` are referred to by their `Extra` enum value. The `includedCount`, if specified, must be a non-negative integer
373+
value. If not specified, the default value for an `includedCount` is 0.
374+
375+
#### Free and node/network-exempt operations
376+
377+
The `free` field applies to both transactions and queries. If `free` is `true`, the operation has no node, network, or
378+
service fee; `baseFee` and `extras` are ignored.
379+
380+
Some operations are paid through another mechanism or are privileged system operations. A service fee definition can
381+
set `nodeNetworkFeeExempt` to `true` for these operations. In this case the node and network components are not charged,
382+
but the configured service component still applies. If both `free` and `nodeNetworkFeeExempt` are `true`, `free` takes
383+
precedence and the entire operation is free.
384+
366385

367386
### Unreadable Transactions
368387

@@ -417,8 +436,8 @@ The validation process checks the following, in any order:
417436
1. **Parsing and Schema Compliance**: The JSON file must parse successfully and conform exactly to the `FeeSchedule`
418437
Protobuf message defined in this HIP. This includes:
419438
- All required fields are present (e.g., `node` and `network` must exist; `multiplier` must be defined in`network`).
420-
- Field types match (e.g., `baseFee` and `fee` are unsigned 64-bit integers; `name` fields are strings;
421-
`includedCount` is an unsigned 32-bit integer).
439+
- Field types match (e.g., `baseFee` and `fee` are unsigned 64-bit integers; extra and operation `name` fields use
440+
their respective enums; service `name` fields are strings; `includedCount` is an unsigned 32-bit integer).
422441
- Optional fields, if present, follow their constraints (e.g., `unreadable` may be absent or have `fee` set to 0).
423442
- No extra unrecognized fields are included.
424443
2. **Monetary Values**: All fields representing USD amounts in tinycents (`baseFee` in node and service definitions,
@@ -430,8 +449,8 @@ The validation process checks the following, in any order:
430449
- All extra names (in the `extras` list) must be unique.
431450
- All service names (in the `services` list) must be unique.
432451
- Within each service's `schedule` list, all transaction and query names must be unique.
433-
6. **Name Format**: Every `name` field (for extras, services, transactions, and queries) must match the regular
434-
expression `[A-Za-z].*[A-Za-z0-9]*`—starting with a letter, followed by letters, digits, or both, and not empty.
452+
6. **Names**: Every extra name must be a member of `Extra`, and every transaction or query name must be a member of
453+
`HederaFunctionality`. Service names must match `[A-Za-z].*[A-Za-z0-9]*` and identify a supported network service.
435454
7. **Extra References**: Every reference to an extra (in `node.extras`, or in any service's transaction/query `extras`)
436455
must point to a defined extra in the top-level `extras` list. No duplicate references to the same extra are allowed
437456
within a single list of extras.
@@ -440,12 +459,15 @@ The validation process checks the following, in any order:
440459
9. **Free Queries and Transactions**: If a transaction or query sets `free` to true, its `baseFee` and `extras` are
441460
ignored during fee calculation, but they must still comply with all other validation rules if present (e.g., valid
442461
types, non-negative values, valid references).
443-
462+
10. **Node and Network Fee Exemption**: If `nodeNetworkFeeExempt` is true, only the service fee is charged. If `free` is
463+
also true, `free` takes precedence.
444464
### Schema
445465

446466
The schema is defined in Protobuf. The wire format is JSON.
447467

448468
```protobuf
469+
import "services/basic_types.proto";
470+
449471
/**
450472
* Network fee schedule definition.<br/>
451473
* This message defines how fees are charged for transactions.
@@ -464,7 +486,7 @@ message FeeSchedule {
464486
*
465487
* <p>The node fee schedule MUST be specified.
466488
*/
467-
NodeFeeSchedule node = 1;
489+
NodeFee node = 1;
468490
469491
/**
470492
* Defines the method by which the <i>network fee component</i> is computed.
@@ -476,7 +498,7 @@ message FeeSchedule {
476498
*
477499
* <p>The network fee schedule MUST be specified.
478500
*/
479-
NetworkFeeSchedule network = 2;
501+
NetworkFee network = 2;
480502
481503
/**
482504
* This fee is charged to the node that submitted the transaction when a
@@ -485,7 +507,7 @@ message FeeSchedule {
485507
*
486508
* <p>This configuration SHOULD be specified.
487509
*/
488-
UnreadableTransactionFeeSchedule unreadable = 3;
510+
UnreadableTransactionFee unreadable = 3;
489511
490512
/**
491513
* Every "extra" that can be assigned to a given fee is defined in this list.
@@ -505,15 +527,45 @@ message FeeSchedule {
505527
repeated ServiceFeeSchedule services = 5;
506528
}
507529
530+
/** Defines every supported extra fee. */
531+
enum Extra {
532+
SIGNATURES = 0;
533+
KEYS = 1;
534+
NFT_SERIALS = 2;
535+
ACCOUNTS = 3;
536+
TOKEN_TYPES = 4;
537+
GAS = 5;
538+
ALLOWANCES = 6;
539+
AIRDROPS = 7;
540+
HOOK_UPDATES = 8;
541+
TOKEN_TRANSFER_BASE = 9;
542+
TOKEN_TRANSFER_BASE_CUSTOM_FEES = 10;
543+
HOOK_EXECUTION = 11;
544+
TOKEN_CREATE_WITH_CUSTOM_FEE = 12;
545+
TOKEN_MINT_NFT = 13;
546+
CONSENSUS_CREATE_TOPIC_WITH_CUSTOM_FEE = 14;
547+
CONSENSUS_SUBMIT_MESSAGE_WITH_CUSTOM_FEE = 15;
548+
SCHEDULE_CREATE_CONTRACT_CALL_BASE = 16;
549+
TOKEN_ASSOCIATE = 17;
550+
HOOK_SLOT_UPDATE = 18;
551+
TOKEN_MINT_NFT_BASE = 19;
552+
NFT_UPDATE = 20;
553+
RECORDS = 21;
554+
STATE_BYTES = 22;
555+
PROCESSING_BYTES = 23;
556+
CONSENSUS_SUBMIT_MESSAGE_WITH_CUSTOM_FEE_BYTES = 24;
557+
CONSENSUS_SUBMIT_MESSAGE_WITHOUT_CUSTOM_FEE_BYTES = 25;
558+
}
559+
508560
/**
509561
* Defines an "extra" fee. Each fee has a name and a fee amount defined in tinycents (10^8 per cent).
510562
*/
511563
message ExtraFeeDefinition {
512564
/**
513565
* The name of this "extra". The name MUST be unique within the complete FeeSchedule
514-
* and MUST be specified. A valid name MUST match `[A-Za-z].*[A-Za-z0-9]*`.
566+
* and MUST be specified.
515567
*/
516-
string name = 1;
568+
Extra name = 1;
517569
/**
518570
* The fee price, in tinycents. There are 10^8 tinycents per cent USD. The fee MUST be specified
519571
* (a value of 0 is not permitted).
@@ -524,7 +576,7 @@ message ExtraFeeDefinition {
524576
/**
525577
* The configuration for node fees. Applied to all transactions equally.
526578
*/
527-
message NodeFeeSchedule {
579+
message NodeFee {
528580
/**
529581
* The base fee price, in tinycents. There are 10^8 tinycents per cent USD.
530582
* The base fee, plus the extras, determine the node fee. The base_fee is
@@ -544,7 +596,7 @@ message NodeFeeSchedule {
544596
/**
545597
* The configuration for computing the network fee component.
546598
*/
547-
message NetworkFeeSchedule {
599+
message NetworkFee {
548600
/**
549601
* Multiplied by the node fee to determine the network fee. This value MUST be
550602
* specified and MUST be at least 1.
@@ -576,10 +628,10 @@ message ServiceFeeSchedule {
576628
message ServiceFeeDefinition {
577629
/**
578630
* The name of the transaction or query. The name MUST be specified and MUST match a name
579-
* defined by the specification for the service. Each name is unique within the file the
580-
* context of a specific service. The name must match `[A-Za-z].*[A-Za-z0-9]*`.
631+
* defined by the specification for the service. Each name is unique within the file in the
632+
* context of a specific service.
581633
*/
582-
string name = 1;
634+
proto.HederaFunctionality name = 1;
583635
/**
584636
* The base fee price, in tinycents. There are 10^8 tinycents per cent USD.
585637
* The base fee, plus the extras, determine the service fee. The base_fee is
@@ -598,6 +650,9 @@ message ServiceFeeDefinition {
598650
* will be free.
599651
*/
600652
bool free = 4;
653+
654+
/** If true, omit node and network components but continue to charge the service component. */
655+
bool node_network_fee_exempt = 6;
601656
}
602657
603658
/**
@@ -608,7 +663,7 @@ message ExtraFeeReference {
608663
* The name of the referenced "extra". This name MUST match the name of an extra
609664
* defined within the `FeeSchedule`.
610665
*/
611-
string name = 1;
666+
Extra name = 1;
612667
613668
/**
614669
* The count of this "extra" that is included for free. For example, 256 "Bytes"
@@ -621,7 +676,7 @@ message ExtraFeeReference {
621676
/**
622677
* Defines the fee to levy a node that sends bytes that cannot be parsed into a Transaction.
623678
*/
624-
message UnreadableTransactionFeeSchedule {
679+
message UnreadableTransactionFee {
625680
/**
626681
* The punitive fee, in tinycents. There are 10^8 tinycents per cent USD. This value
627682
* is optional and may be zero.
@@ -825,4 +880,3 @@ The initial design specified a fee estimation gRPC API on the mirror node. It wa
825880
would also be needed to support browser-based applications like the fee calculator website. As it would be inefficient
826881
to develop two similar APIs and the REST API could be used by all types of applications, the decision was made to
827882
drop the gRPC API in favor of a REST-only approach.
828-

0 commit comments

Comments
 (0)