Skip to content

Commit fcbe66d

Browse files
feat: Simple Fees file support (#21899)
Signed-off-by: Josh Marinacci <[email protected]>
1 parent 76e9d4f commit fcbe66d

File tree

55 files changed

+1136
-130
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1136
-130
lines changed

hedera-node/hapi-fees/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
exports com.hedera.node.app.hapi.fees.calc;
1515
exports com.hedera.node.app.hapi.fees.usage.contract;
1616
exports com.hedera.node.app.hapi.fees.usage.token.entities;
17+
exports org.hiero.hapi.fees;
1718

1819
requires transitive com.hedera.node.app.hapi.utils;
1920
requires transitive com.hedera.node.hapi;

hedera-node/hapi-fees/src/main/java/org/hiero/hapi/fees/FeeModel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@ public interface FeeModel {
2020
String getDescription();
2121

2222
/** Compute the fee for a specific transaction. */
23-
FeeResult computeFee(Map<Extra, Object> params, FeeSchedule feeSchedule);
23+
FeeResult computeFee(Map<Extra, Long> params, FeeSchedule feeSchedule);
2424
}

hedera-node/hapi-fees/src/main/java/org/hiero/hapi/fees/FeeModelRegistry.java

Lines changed: 54 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -61,89 +61,70 @@
6161
public class FeeModelRegistry {
6262
private static final Map<HederaFunctionality, FeeModel> registry = new LinkedHashMap<>();
6363

64+
private static void register(FeeModel feeModel) {
65+
registry.put(feeModel.getApi(), feeModel);
66+
}
67+
6468
static {
65-
registry.put(CONSENSUS_CREATE_TOPIC, new StandardFeeModel(CONSENSUS_CREATE_TOPIC, "Create a new topic"));
66-
registry.put(CONSENSUS_UPDATE_TOPIC, new StandardFeeModel(CONSENSUS_UPDATE_TOPIC, "Update topic"));
67-
registry.put(CONSENSUS_DELETE_TOPIC, new StandardFeeModel(CONSENSUS_DELETE_TOPIC, "Delete topic"));
68-
registry.put(
69-
CONSENSUS_GET_TOPIC_INFO, new StandardFeeModel(CONSENSUS_GET_TOPIC_INFO, "Get metadata for a topic"));
70-
registry.put(
71-
CONSENSUS_SUBMIT_MESSAGE, new StandardFeeModel(CONSENSUS_SUBMIT_MESSAGE, "Submit message to topic"));
69+
register(new StandardFeeModel(CONSENSUS_CREATE_TOPIC, "Create a new topic"));
70+
register(new StandardFeeModel(CONSENSUS_UPDATE_TOPIC, "Update topic"));
71+
register(new StandardFeeModel(CONSENSUS_DELETE_TOPIC, "Delete topic"));
72+
register(new StandardFeeModel(CONSENSUS_GET_TOPIC_INFO, "Get metadata for a topic"));
73+
register(new StandardFeeModel(CONSENSUS_SUBMIT_MESSAGE, "Submit message to topic"));
7274

73-
registry.put(FILE_CREATE, new StandardFeeModel(FILE_CREATE, "Create file"));
74-
registry.put(FILE_APPEND, new StandardFeeModel(FILE_APPEND, "Append to file"));
75-
registry.put(FILE_UPDATE, new StandardFeeModel(FILE_UPDATE, "Update file"));
76-
registry.put(FILE_DELETE, new StandardFeeModel(FILE_DELETE, "Delete file"));
77-
registry.put(FILE_GET_CONTENTS, new StandardFeeModel(FILE_GET_CONTENTS, "Get file contents"));
78-
registry.put(FILE_GET_INFO, new StandardFeeModel(FILE_GET_INFO, "Get file info"));
75+
register(new StandardFeeModel(FILE_CREATE, "Create file"));
76+
register(new StandardFeeModel(FILE_APPEND, "Append to file"));
77+
register(new StandardFeeModel(FILE_UPDATE, "Update file"));
78+
register(new StandardFeeModel(FILE_DELETE, "Delete file"));
79+
register(new StandardFeeModel(FILE_GET_CONTENTS, "Get file contents"));
80+
register(new StandardFeeModel(FILE_GET_INFO, "Get file info"));
7981

80-
registry.put(CRYPTO_TRANSFER, new StandardFeeModel(CRYPTO_TRANSFER, "Transfer tokens among accounts"));
81-
registry.put(CRYPTO_UPDATE, new StandardFeeModel(CRYPTO_UPDATE, "Update an account"));
82-
registry.put(CRYPTO_DELETE, new StandardFeeModel(CRYPTO_DELETE, "Delete an account"));
83-
registry.put(CRYPTO_CREATE, new StandardFeeModel(CRYPTO_CREATE, "Create a new account"));
84-
registry.put(
85-
CRYPTO_APPROVE_ALLOWANCE,
86-
new StandardFeeModel(CRYPTO_APPROVE_ALLOWANCE, "Approve an allowance for a spender"));
87-
registry.put(
88-
CRYPTO_DELETE_ALLOWANCE,
89-
new StandardFeeModel(CRYPTO_DELETE_ALLOWANCE, "Delete an allowance for a spender"));
82+
register(new StandardFeeModel(CRYPTO_TRANSFER, "Transfer tokens among accounts"));
83+
register(new StandardFeeModel(CRYPTO_UPDATE, "Update an account"));
84+
register(new StandardFeeModel(CRYPTO_DELETE, "Delete an account"));
85+
register(new StandardFeeModel(CRYPTO_CREATE, "Create a new account"));
86+
register(new StandardFeeModel(CRYPTO_APPROVE_ALLOWANCE, "Approve an allowance for a spender"));
87+
register(new StandardFeeModel(CRYPTO_DELETE_ALLOWANCE, "Delete an allowance for a spender"));
9088

91-
registry.put(CONTRACT_CALL, new StandardFeeModel(CONTRACT_CALL, "Execute a smart contract call"));
92-
registry.put(CONTRACT_CREATE, new StandardFeeModel(CONTRACT_CREATE, "Create a smart contract"));
93-
registry.put(CONTRACT_UPDATE, new StandardFeeModel(CONTRACT_UPDATE, "Update a smart contract"));
94-
registry.put(
95-
CONTRACT_GET_INFO, new StandardFeeModel(CONTRACT_GET_INFO, "Get information about a smart contract"));
96-
registry.put(
97-
CONTRACT_GET_BYTECODE,
98-
new StandardFeeModel(CONTRACT_GET_BYTECODE, "Get the compiled bytecode for a smart contract"));
99-
registry.put(CONTRACT_DELETE, new StandardFeeModel(CONTRACT_DELETE, "Delete a smart contract"));
89+
register(new StandardFeeModel(CONTRACT_CALL, "Execute a smart contract call"));
90+
register(new StandardFeeModel(CONTRACT_CREATE, "Create a smart contract"));
91+
register(new StandardFeeModel(CONTRACT_UPDATE, "Update a smart contract"));
92+
register(new StandardFeeModel(CONTRACT_GET_INFO, "Get information about a smart contract"));
93+
register(new StandardFeeModel(CONTRACT_GET_BYTECODE, "Get the compiled bytecode for a smart contract"));
94+
register(new StandardFeeModel(CONTRACT_DELETE, "Delete a smart contract"));
10095

101-
registry.put(TOKEN_CREATE, new StandardFeeModel(TOKEN_CREATE, "Create a token"));
102-
registry.put(TOKEN_GET_INFO, new StandardFeeModel(TOKEN_GET_INFO, "Get metadata for a token"));
103-
registry.put(
104-
TOKEN_FREEZE_ACCOUNT,
105-
new StandardFeeModel(TOKEN_FREEZE_ACCOUNT, "Freeze a specific account with respect to a token"));
106-
registry.put(
107-
TOKEN_UNFREEZE_ACCOUNT,
108-
new StandardFeeModel(TOKEN_UNFREEZE_ACCOUNT, "Unfreeze a specific account with respect to a token"));
109-
registry.put(
110-
TOKEN_GRANT_KYC_TO_ACCOUNT,
111-
new StandardFeeModel(
112-
TOKEN_GRANT_KYC_TO_ACCOUNT, "Grant KYC status to an account for a specific token"));
113-
registry.put(
114-
TOKEN_REVOKE_KYC_FROM_ACCOUNT,
115-
new StandardFeeModel(
116-
TOKEN_REVOKE_KYC_FROM_ACCOUNT, "Revoke KYC status from an account for a specific token"));
117-
registry.put(TOKEN_DELETE, new StandardFeeModel(TOKEN_DELETE, "Delete a specific token"));
118-
registry.put(TOKEN_UPDATE, new StandardFeeModel(TOKEN_UPDATE, "Update a specific token"));
119-
registry.put(TOKEN_MINT, new StandardFeeModel(TOKEN_MINT, "Mint tokens"));
120-
registry.put(TOKEN_BURN, new StandardFeeModel(TOKEN_BURN, "Burn tokens"));
121-
registry.put(
122-
TOKEN_ACCOUNT_WIPE, new StandardFeeModel(TOKEN_ACCOUNT_WIPE, "Wipe all amounts for a specific token"));
123-
registry.put(
124-
TOKEN_ASSOCIATE_TO_ACCOUNT,
125-
new StandardFeeModel(TOKEN_ASSOCIATE_TO_ACCOUNT, "Associate account to a specific token"));
126-
registry.put(
127-
TOKEN_DISSOCIATE_FROM_ACCOUNT,
128-
new StandardFeeModel(TOKEN_DISSOCIATE_FROM_ACCOUNT, "Dissociate account from a specific token"));
129-
registry.put(TOKEN_PAUSE, new StandardFeeModel(TOKEN_PAUSE, "Pause a specific token"));
130-
registry.put(TOKEN_UNPAUSE, new StandardFeeModel(TOKEN_UNPAUSE, "Unpause a specific token"));
131-
registry.put(TOKEN_UPDATE_NFTS, new StandardFeeModel(TOKEN_UPDATE_NFTS, "Update metadata of an NFT token"));
132-
registry.put(TOKEN_REJECT, new StandardFeeModel(TOKEN_REJECT, "Reject a token"));
133-
registry.put(TOKEN_AIRDROP, new StandardFeeModel(TOKEN_AIRDROP, "Airdrop one or more tokens"));
134-
registry.put(TOKEN_CANCEL_AIRDROP, new StandardFeeModel(TOKEN_CANCEL_AIRDROP, "Cancel pending airdrops"));
135-
registry.put(TOKEN_CLAIM_AIRDROP, new StandardFeeModel(TOKEN_CLAIM_AIRDROP, "Claim pending airdrops"));
96+
register(new StandardFeeModel(TOKEN_CREATE, "Create a token"));
97+
register(new StandardFeeModel(TOKEN_GET_INFO, "Get metadata for a token"));
98+
register(new StandardFeeModel(TOKEN_FREEZE_ACCOUNT, "Freeze a specific account with respect to a token"));
99+
register(new StandardFeeModel(TOKEN_UNFREEZE_ACCOUNT, "Unfreeze a specific account with respect to a token"));
100+
register(new StandardFeeModel(
101+
TOKEN_GRANT_KYC_TO_ACCOUNT, "Grant KYC status to an account for a specific token"));
102+
register(new StandardFeeModel(
103+
TOKEN_REVOKE_KYC_FROM_ACCOUNT, "Revoke KYC status from an account for a specific token"));
104+
register(new StandardFeeModel(TOKEN_DELETE, "Delete a specific token"));
105+
register(new StandardFeeModel(TOKEN_UPDATE, "Update a specific token"));
106+
register(new StandardFeeModel(TOKEN_MINT, "Mint tokens"));
107+
register(new StandardFeeModel(TOKEN_BURN, "Burn tokens"));
108+
register(new StandardFeeModel(TOKEN_ACCOUNT_WIPE, "Wipe all amounts for a specific token"));
109+
register(new StandardFeeModel(TOKEN_ASSOCIATE_TO_ACCOUNT, "Associate account to a specific token"));
110+
register(new StandardFeeModel(TOKEN_DISSOCIATE_FROM_ACCOUNT, "Dissociate account from a specific token"));
111+
register(new StandardFeeModel(TOKEN_PAUSE, "Pause a specific token"));
112+
register(new StandardFeeModel(TOKEN_UNPAUSE, "Unpause a specific token"));
113+
register(new StandardFeeModel(TOKEN_UPDATE_NFTS, "Update metadata of an NFT token"));
114+
register(new StandardFeeModel(TOKEN_REJECT, "Reject a token"));
115+
register(new StandardFeeModel(TOKEN_AIRDROP, "Airdrop one or more tokens"));
116+
register(new StandardFeeModel(TOKEN_CANCEL_AIRDROP, "Cancel pending airdrops"));
117+
register(new StandardFeeModel(TOKEN_CLAIM_AIRDROP, "Claim pending airdrops"));
136118

137-
registry.put(SCHEDULE_CREATE, new StandardFeeModel(SCHEDULE_CREATE, "Create a scheduled transaction"));
138-
registry.put(SCHEDULE_DELETE, new StandardFeeModel(SCHEDULE_DELETE, "Delete a scheduled transaction"));
139-
registry.put(SCHEDULE_SIGN, new StandardFeeModel(SCHEDULE_SIGN, "Sign a scheduled transaction"));
140-
registry.put(
141-
SCHEDULE_GET_INFO, new StandardFeeModel(SCHEDULE_GET_INFO, "Get metadata for a scheduled transaction"));
119+
register(new StandardFeeModel(SCHEDULE_CREATE, "Create a scheduled transaction"));
120+
register(new StandardFeeModel(SCHEDULE_DELETE, "Delete a scheduled transaction"));
121+
register(new StandardFeeModel(SCHEDULE_SIGN, "Sign a scheduled transaction"));
122+
register(new StandardFeeModel(SCHEDULE_GET_INFO, "Get metadata for a scheduled transaction"));
142123
}
143124

144125
public static FeeModel lookupModel(HederaFunctionality service) {
145126
if (!registry.containsKey(service)) {
146-
throw new IllegalArgumentException("No registered model found for service " + service);
127+
throw new IllegalArgumentException("No registered model found for service " + service.protoName());
147128
}
148129
return registry.get(service);
149130
}

hedera-node/hapi-fees/src/main/java/org/hiero/hapi/fees/FeeResult.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public String toString() {
7272

7373
@Override
7474
public String toString() {
75-
return "FeeResult{" + "fee=" + service + ", details=" + details + '}';
75+
return "FeeResult{" + "fee=" + this.total() + ", details=" + details + '}';
7676
}
7777

7878
private static long clampedAdd(final long a, final long b) {

hedera-node/hapi-fees/src/main/java/org/hiero/hapi/fees/FeeScheduleUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public static ServiceFeeDefinition lookupServiceFee(FeeSchedule feeSchedule, Hed
7979
* one service defined.
8080
* @param feeSchedule
8181
*/
82-
public static boolean validate(FeeSchedule feeSchedule) {
82+
public static boolean isValid(FeeSchedule feeSchedule) {
8383
requireNonNull(feeSchedule);
8484
for (ExtraFeeDefinition def : feeSchedule.extras()) {
8585
// no negative values or greater than MAX long

hedera-node/hapi-fees/src/main/java/org/hiero/hapi/fees/apis/common/AbstractBaseFeeModel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public String getDescription() {
3131
return this.description;
3232
}
3333

34-
protected FeeResult computeNodeAndNetworkFees(Map<Extra, Object> params, FeeSchedule feeSchedule) {
34+
protected FeeResult computeNodeAndNetworkFees(Map<Extra, Long> params, FeeSchedule feeSchedule) {
3535
var result = new FeeResult();
3636
final var nodeFee = feeSchedule.node();
3737
result.addNodeFee("Node base fee", 1, nodeFee.baseFee());

hedera-node/hapi-fees/src/main/java/org/hiero/hapi/fees/apis/common/StandardFeeModel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public StandardFeeModel(HederaFunctionality api, String description) {
2020
}
2121

2222
@Override
23-
public FeeResult computeFee(Map<Extra, Object> params, FeeSchedule feeSchedule) {
23+
public FeeResult computeFee(Map<Extra, Long> params, FeeSchedule feeSchedule) {
2424
var result = this.computeNodeAndNetworkFees(params, feeSchedule);
2525
result.addServiceFee(
2626
"Base Fee for " + this.getApi(),

hedera-node/hapi-fees/src/test/java/org/hiero/hapi/fees/FeeScheduleTest.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public class FeeScheduleTest {
2222
void testLoadingFeeScheduleFromJson() throws ParseException {
2323
final var fin = FeeScheduleTest.class.getClassLoader().getResourceAsStream("simple-fee-schedule.json");
2424
final FeeSchedule buf = FeeSchedule.JSON.parse(new ReadableStreamingData(Objects.requireNonNull(fin)));
25-
assertTrue(FeeScheduleUtils.validate(buf), "Fee schedule validation failed");
25+
assertTrue(FeeScheduleUtils.isValid(buf), "Fee schedule validation failed");
2626
}
2727

2828
// extra definitions must have positive values
@@ -32,7 +32,7 @@ void catchNegativeValue() {
3232
.copyBuilder()
3333
.extras(makeExtraDef(Extra.KEYS, -88))
3434
.build();
35-
assertFalse(FeeScheduleUtils.validate(badSchedule), "Fee schedule validation didn't catch negative value");
35+
assertFalse(FeeScheduleUtils.isValid(badSchedule), "Fee schedule validation didn't catch negative value");
3636
}
3737

3838
// all referenced extras must exist in the defined extras
@@ -50,7 +50,6 @@ void catchMissingExtraDef() {
5050
makeExtraIncluded(Extra.SIGNATURES, 1))))
5151
.build();
5252
assertFalse(
53-
FeeScheduleUtils.validate(badSchedule),
54-
"Fee schedule validation failed to find the missing extras def");
53+
FeeScheduleUtils.isValid(badSchedule), "Fee schedule validation failed to find the missing extras def");
5554
}
5655
}

hedera-node/hapi-fees/src/test/java/org/hiero/hapi/fees/apis/consensus/ConsensusFeeModelTests.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
import static com.hedera.hapi.node.base.HederaFunctionality.CONSENSUS_DELETE_TOPIC;
66
import static com.hedera.hapi.node.base.HederaFunctionality.CONSENSUS_SUBMIT_MESSAGE;
77
import static com.hedera.hapi.node.base.HederaFunctionality.CONSENSUS_UPDATE_TOPIC;
8+
import static org.hiero.hapi.fees.FeeScheduleUtils.isValid;
89
import static org.hiero.hapi.fees.FeeScheduleUtils.makeExtraDef;
910
import static org.hiero.hapi.fees.FeeScheduleUtils.makeExtraIncluded;
1011
import static org.hiero.hapi.fees.FeeScheduleUtils.makeService;
1112
import static org.hiero.hapi.fees.FeeScheduleUtils.makeServiceFee;
12-
import static org.hiero.hapi.fees.FeeScheduleUtils.validate;
1313
import static org.junit.jupiter.api.Assertions.assertEquals;
1414
import static org.junit.jupiter.api.Assertions.assertTrue;
1515

@@ -61,13 +61,13 @@ static void setup() {
6161
@Test
6262
void createTopicWithExtraKeys() {
6363
FeeModel model = FeeModelRegistry.lookupModel(CONSENSUS_CREATE_TOPIC);
64-
Map<Extra, Object> params = new HashMap<>();
64+
Map<Extra, Long> params = new HashMap<>();
6565
params.put(Extra.SIGNATURES, 1L);
6666
params.put(Extra.KEYS, 5L);
6767
params.put(Extra.BYTES, 20L);
6868
// params.put(Params.HasCustomFee, YesOrNo.NO);
6969

70-
assertTrue(validate(feeSchedule), "Fee schedule failed validation");
70+
assertTrue(isValid(feeSchedule), "Fee schedule failed validation");
7171
FeeResult fee = model.computeFee(params, feeSchedule);
7272
// service base fee= 15
7373
// 5 keys - 1 included * key cost of 2 = 4*2 = 8
@@ -86,7 +86,7 @@ void createTopicWithExtraKeys() {
8686
@Test
8787
void updateTopic() {
8888
FeeModel model = FeeModelRegistry.lookupModel(CONSENSUS_UPDATE_TOPIC);
89-
Map<Extra, Object> params = new HashMap<>();
89+
Map<Extra, Long> params = new HashMap<>();
9090
params.put(Extra.SIGNATURES, 1L);
9191
params.put(Extra.KEYS, 1L);
9292
params.put(Extra.BYTES, 10L);
@@ -97,7 +97,7 @@ void updateTopic() {
9797
@Test
9898
void submitMessage() {
9999
FeeModel model = FeeModelRegistry.lookupModel(CONSENSUS_SUBMIT_MESSAGE);
100-
Map<Extra, Object> params = new HashMap<>();
100+
Map<Extra, Long> params = new HashMap<>();
101101
params.put(Extra.SIGNATURES, 1L);
102102
params.put(Extra.KEYS, 1L);
103103
params.put(Extra.BYTES, 100L);
@@ -111,7 +111,7 @@ void submitMessage() {
111111
@Test
112112
void submitMessageWithExtraBytes() {
113113
FeeModel model = FeeModelRegistry.lookupModel(CONSENSUS_SUBMIT_MESSAGE);
114-
Map<Extra, Object> params = new HashMap<>();
114+
Map<Extra, Long> params = new HashMap<>();
115115
params.put(Extra.SIGNATURES, 1L);
116116
params.put(Extra.KEYS, 1L);
117117
params.put(Extra.BYTES, 500L);
@@ -126,7 +126,7 @@ void submitMessageWithExtraBytes() {
126126
@Test
127127
void submitMessageWithCustomFee() {
128128
FeeModel model = FeeModelRegistry.lookupModel(CONSENSUS_SUBMIT_MESSAGE);
129-
Map<Extra, Object> params = new HashMap<>();
129+
Map<Extra, Long> params = new HashMap<>();
130130
params.put(Extra.SIGNATURES, 1L);
131131
params.put(Extra.KEYS, 1L);
132132
params.put(Extra.BYTES, 10L);
@@ -141,7 +141,7 @@ void submitMessageWithCustomFee() {
141141
@Test
142142
void deleteTopic() {
143143
FeeModel model = FeeModelRegistry.lookupModel(CONSENSUS_DELETE_TOPIC);
144-
Map<Extra, Object> params = new HashMap<>();
144+
Map<Extra, Long> params = new HashMap<>();
145145
params.put(Extra.SIGNATURES, 1L);
146146
params.put(Extra.KEYS, 1L);
147147
params.put(Extra.BYTES, 1L);

0 commit comments

Comments
 (0)