hiero-ledger / hiero-ledger/hiero-consensus-node
StandaloneFeeCalculator API Performance Improvements
- Dominant language
- Java
- Stars
- 406
- Forks
- 226
- Avg merge
- 3d 4h
- Merged PRs (30d)
- 210
Description
* Change calls from SimpleFeeContext.feeContext().body() to SimpleFeeContext.body() so we can make SimpleFeeContext.feeContext() object static and stateless
* Consider reworking fee calculator to pull fee schedule from KV state
* improve perf of the high volume throttle
Notes from Martin:
And one more thing from the fee estimation work — UtilizationScaledThrottleMultiplier.currentMultiplier() reads directly from state stores (via feeContext.readableStore()) to calculate congestion utilisation, regardless of what SimpleFeeContext.getHighVolumeThrottleUtilization() returns. In our estimation context that method already returns 0 (no congestion), but the multiplier still tries to load the stores — and if any of them are absent it NPEs.
Would it be possible to either: (a) have the multiplier check getHighVolumeThrottleUtilization() first and skip the store reads when it's 0, or (b) null-check the stores before dereferencing them in roundedAccountPercentUtil, roundedContractPercentUtil, etc.?
For now we're working around it with a proxy that returns zero for all methods on unknown stores, but a fix on the CN side would let us drop the workaround entirely.
And another one I've just discovered FeeManager.updateSimpleFees() constructs SimpleFeeCalculatorImpl with the injected congestionMultipliers (non-null in the standalone executor). This causes the congestion multiplier to run during mirror node fee estimation, which calls stores we don't have. SimpleFeeCalculatorImpl already has a @VisibleForTestingconstructor that passes null for congestion — can FeeManager use that for standalone use so congestion is skipped because now it throws?
Contributor guide
Research direction
Start by tracing FeeManager.updateSimpleFees() and SimpleFeeCalculatorImpl, then inspect SimpleFeeContext.body(), UtilizationScaledThrottleMultiplier.currentMultiplier(), and the rounded account and contract utilization methods. Verify the standalone fee path avoids unavailable state-store reads and unnecessary congestion calculation, while using the direct context body access and preserving the requested high-volume throttle behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend, performance
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100