Skip to content

Conversation

@aderevets
Copy link
Contributor

@aderevets aderevets commented Oct 28, 2025

Description:
Update CryptoCreate/CryptoDelete handler to use new simple fees model based on this HIP


Update simpleFeesSchedules.json with correct values

Related issue(s):

Fixes #20443

Notes for reviewer:

Checklist

  • Documented (Code comments, README, etc.)
  • Tested (unit, integration, etc.)

@aderevets aderevets requested a review from a team as a code owner October 28, 2025 19:04
@lfdt-bot
Copy link

lfdt-bot commented Oct 28, 2025

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@aderevets aderevets self-assigned this Oct 28, 2025
@codecov
Copy link

codecov bot commented Oct 28, 2025

Codecov Report

❌ Patch coverage is 0% with 122 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...node/app/spi/fees/AbstractSimpleFeeCalculator.java 0.00% 69 Missing ⚠️
...rvice/token/impl/handlers/SimpleTxContextImpl.java 0.00% 29 Missing ⚠️
...token/impl/handlers/CryptoCreateFeeCalculator.java 0.00% 13 Missing ⚠️
...token/impl/handlers/CryptoDeleteFeeCalculator.java 0.00% 8 Missing ⚠️
...pp/workflows/dispatcher/TransactionDispatcher.java 0.00% 1 Missing ⚠️
...rvice/token/impl/handlers/CryptoCreateHandler.java 0.00% 1 Missing ⚠️
...rvice/token/impl/handlers/CryptoDeleteHandler.java 0.00% 1 Missing ⚠️

Impacted file tree graph

@@             Coverage Diff              @@
##               main   #21901      +/-   ##
============================================
- Coverage     70.89%   70.82%   -0.08%     
+ Complexity    24429    24428       -1     
============================================
  Files          2668     2672       +4     
  Lines        104410   104531     +121     
  Branches      10966    10973       +7     
============================================
+ Hits          74022    74031       +9     
- Misses        26343    26450     +107     
- Partials       4045     4050       +5     
Files with missing lines Coverage Δ Complexity Δ
...pp/workflows/dispatcher/TransactionDispatcher.java 49.58% <0.00%> (ø) 39.00 <0.00> (ø)
...rvice/token/impl/handlers/CryptoCreateHandler.java 80.40% <0.00%> (-0.41%) 51.00 <0.00> (ø)
...rvice/token/impl/handlers/CryptoDeleteHandler.java 97.29% <0.00%> (-2.71%) 9.00 <0.00> (ø)
...token/impl/handlers/CryptoDeleteFeeCalculator.java 0.00% <0.00%> (ø) 0.00 <0.00> (?)
...token/impl/handlers/CryptoCreateFeeCalculator.java 0.00% <0.00%> (ø) 0.00 <0.00> (?)
...rvice/token/impl/handlers/SimpleTxContextImpl.java 0.00% <0.00%> (ø) 0.00 <0.00> (?)
...node/app/spi/fees/AbstractSimpleFeeCalculator.java 0.00% <0.00%> (ø) 0.00 <0.00> (?)

... and 14 files with indirect coverage changes

Impacted file tree graph

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Signed-off-by: artemderevets <[email protected]>
@aderevets aderevets requested a review from ibankov October 29, 2025 13:10
Copy link
Contributor

@joshmarinacci joshmarinacci left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall the PR is good and contains what I expect. The part I'm confused on is in CryptoTransferHandler. Why does it need a cache? This seems overly complex.

Also, there should be full HAPI tests for each of the transaction types.

Signed-off-by: artemderevets <[email protected]>
@aderevets aderevets requested a review from a team as a code owner October 29, 2025 16:34
Signed-off-by: artemderevets <[email protected]>
@aderevets
Copy link
Contributor Author

aderevets commented Oct 29, 2025

Overall the PR is good and contains what I expect. The part I'm confused on is in CryptoTransferHandler. Why does it need a cache? This seems overly complex.

Also, there should be full HAPI tests for each of the transaction types.

I created a cache to reduce store interaction and overall complexity. This will allow to implement crypto transfrer estimation in the single pass

Signed-off-by: artemderevets <[email protected]>
Signed-off-by: artemderevets <[email protected]>
@aderevets aderevets requested a review from a team as a code owner October 29, 2025 22:40
@aderevets aderevets changed the title feat: Update CryptoTransfer to use new simple fees feat: Update CryptoCreate/CryptoDelete to use new simple fees Nov 5, 2025
Comment on lines +29 to +32
final var usageMapper = usageBuilder()
.withSignatures(context.numTxnSignatures())
.withKeys(keyCount)
.build();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great!

Comment on lines 36 to 52
final var feeSchedule = feeCalculator.getSimpleFeesSchedule();
final var serviceDef = lookupServiceFee(feeSchedule, HederaFunctionality.CRYPTO_CREATE);

// Calculate fees
long nodeFee = feeSchedule.node().baseFee()
+ calculateExtraFees(feeSchedule.node().extras(), feeSchedule, usageMapper);

long serviceFee = serviceDef.baseFee() + calculateExtraFees(serviceDef.extras(), feeSchedule, usageMapper);

long networkFee = calculateNetworkFee(nodeFee, feeSchedule.network().multiplier());

// Return result
final var result = new FeeResult();
result.node = nodeFee;
result.network = networkFee;
result.service = serviceFee;
return result;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can all this code be moved to AbstractSimpleFeeCalculator ? Since it will be the same for every handler

private long countKeys(Key key) {
return switch (key.key().kind()) {
case ED25519, ECDSA_SECP256K1, ECDSA_384 -> 1L;
case THRESHOLD_KEY ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We support other key types also right ?

Copy link
Contributor Author

@aderevets aderevets Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we support other key types (like CONTRACT_ID, DELEGATABLE_CONTRACT_ID, RSA_3072) at the API level, but they're intentionally not counted for fee calculation. The current implementation only counts cryptographic keys (ED25519, ECDSA_SECP256K1, ECDSA_384) and recursively processes THRESHOLD_KEY and KEY_LIST. Contract ID keys return 0 because they don't contain actual key material—they're authorization references. Old fee model charges based on cryptographic complexity, not authorization complexity (as I understand). ECDSA_384 and RSA_3072 are deprecated but still handled for backward compatibility.

Comment on lines 63 to 75
public boolean existsAccountWith(@NonNull final Bytes alias) {
requireNonNull(alias, "alias");
final var hederaConfig =
feeContext.configuration().getConfigData(com.hedera.node.config.data.HederaConfig.class);
final var accountId = accountStore.getAccountIDByAlias(hederaConfig.shard(), hederaConfig.realm(), alias);
return accountId != null;
}

@Override
public boolean existsAccount(@NonNull final AccountID accountId) {
requireNonNull(accountId, "accountId");
return accountStore.getAliasedAccountById(accountId) != null;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need these two when we have getAccount?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refactored. Just forget to do this


@Override
public int cryptoVerificationsRequired() {
return feeContext.numTxnSignatures();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be txInfo.signatureMap().sigPair().size() ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it shouldn't be txInfo.signatureMap().sigPair().size() directly. In IngestChecker.java:325: numSigs = txInfo.signatureMap().sigPair().size(). This is passed to FeeContextImpl constructor. feeContext.numTxnSignatures() returns this value

Copy link
Contributor

@Neeharika-Sompalli Neeharika-Sompalli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks like a great step. Thanks @aderevets . Have a few comments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Crypto Service support

4 participants