Skip to content

Conversation

@derektriley
Copy link
Contributor

@derektriley derektriley commented Oct 24, 2025

Description:
This PR introduces a new singleton state to track the highest node ID ever used. The change includes:

  • Adding a singleton state definition for the highest node ID.
  • Initializing the highest node ID during migration based on the current number of nodes.
  • Removing nodes that are marked as deleted after network upgrade.

Related issue(s):
Fixes #18855

Notes for reviewer:
Since the new singleton state is part of EntityIdStore, a big part of the changes are just mocking or initializing the new singleton for many unit tests.

Checklist

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

Signed-off-by: Derek Riley <[email protected]>
@derektriley derektriley added this to the v0.68 milestone Oct 24, 2025
@derektriley derektriley self-assigned this Oct 24, 2025
@derektriley derektriley linked an issue Oct 24, 2025 that may be closed by this pull request
@lfdt-bot
Copy link

lfdt-bot commented Oct 24, 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.

Signed-off-by: Derek Riley <[email protected]>
Signed-off-by: Derek Riley <[email protected]>
@codecov
Copy link

codecov bot commented Oct 24, 2025

Codecov Report

❌ Patch coverage is 77.45098% with 23 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...dera/node/app/workflows/handle/HandleWorkflow.java 0.00% 11 Missing ⚠️
...e/addressbook/impl/handlers/NodeCreateHandler.java 62.50% 3 Missing and 3 partials ⚠️
...a/node/app/hapi/utils/blocks/BlockStreamUtils.java 0.00% 2 Missing ⚠️
...pp/service/addressbook/impl/WritableNodeStore.java 66.66% 2 Missing ⚠️
...e/app/blocks/impl/BoundaryStateChangeListener.java 0.00% 2 Missing ⚠️

Impacted file tree graph

@@             Coverage Diff              @@
##               main   #21861      +/-   ##
============================================
- Coverage     74.18%   74.17%   -0.02%     
- Complexity    23572    23584      +12     
============================================
  Files          2551     2553       +2     
  Lines         96367    96412      +45     
  Branches      10209    10212       +3     
============================================
+ Hits          71488    71510      +22     
- Misses        21084    21107      +23     
  Partials       3795     3795              
Files with missing lines Coverage Δ Complexity Δ
...ervice/addressbook/impl/ReadableNodeStoreImpl.java 97.14% <100.00%> (ø) 11.00 <2.00> (ø)
...m/hedera/node/app/spi/workflows/HandleContext.java 92.30% <100.00%> (+0.20%) 1.00 <0.00> (ø)
...ra/node/app/hints/impl/ReadableHintsStoreImpl.java 84.74% <100.00%> (ø) 21.00 <4.00> (ø)
...ra/node/app/hints/impl/WritableHintsStoreImpl.java 88.72% <100.00%> (ø) 33.00 <1.00> (ø)
...om/hedera/node/app/store/ReadableStoreFactory.java 87.27% <100.00%> (+1.55%) 11.00 <0.00> (ø)
...om/hedera/node/app/store/WritableStoreFactory.java 82.60% <100.00%> (ø) 8.00 <1.00> (ø)
...de/app/workflows/handle/DispatchHandleContext.java 94.77% <100.00%> (+0.06%) 61.00 <1.00> (+1.00)
...orkflows/handle/dispatch/ChildDispatchFactory.java 90.64% <100.00%> (+0.06%) 19.00 <0.00> (ø)
...pp/workflows/handle/record/SystemTransactions.java 61.05% <100.00%> (-1.25%) 51.00 <0.00> (-2.00)
.../app/workflows/handle/record/TokenContextImpl.java 100.00% <100.00%> (ø) 12.00 <1.00> (ø)
... and 14 more

... and 11 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.

@codacy-production
Copy link

codacy-production bot commented Oct 24, 2025

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
-0.01% (target: -1.00%) 80.39%
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (91953bd) 96270 75235 78.15%
Head commit (21cb8f6) 96315 (+45) 75257 (+22) 78.14% (-0.01%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#21861) 102 82 80.39%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

Signed-off-by: Derek Riley <[email protected]>
Signed-off-by: Derek Riley <[email protected]>
Signed-off-by: Derek Riley <[email protected]>
# Conflicts:
#	hedera-node/hedera-addressbook-service-impl/src/test/java/com/hedera/node/app/service/addressbook/impl/test/handlers/AddressBookTestBase.java
#	hedera-node/hedera-addressbook-service-impl/src/test/java/com/hedera/node/app/service/addressbook/impl/test/handlers/NodeCreateHandlerTest.java
#	hedera-node/hedera-addressbook-service-impl/src/test/java/com/hedera/node/app/service/addressbook/impl/test/handlers/NodeDeleteHandlerTest.java
@JivkoKelchev JivkoKelchev reopened this Nov 4, 2025
@JivkoKelchev JivkoKelchev self-assigned this Nov 4, 2025
@JivkoKelchev JivkoKelchev marked this pull request as ready for review November 14, 2025 14:43
@JivkoKelchev JivkoKelchev requested review from a team as code owners November 14, 2025 14:43
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 great! Thanks @JivkoKelchev @derektriley . Had a few minor comments

final var size = sizeOfState();
final var keys = new ArrayList<EntityNumber>();
for (int i = 0; i < size; i++) {
final long highestExclusive = entityIdStore.peekAtNextNodeId();
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Is there a reason to not have a method, getHighestNodeId, instead of looking at next node id?

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess to be consistent with peekAtNextNumber(). But we can introduce getHighestNodeId() too.

Comment on lines 151 to 152
if (storeInterface == WritableEntityIdStore.class) {
return storeInterface.cast(writableEntityIdStore);
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm I don't understand why we need this

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know. I guess since this store is already a private field of the class, we can return it directly and skip the checks below.
@derektriley ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't recall why I added this originally, go ahead and remove it

Copy link
Contributor

Choose a reason for hiding this comment

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

Removed

Comment on lines -848 to -860
if (dispatch.txnInfo().functionality() == NODE_CREATE) {
WritableSingletonState<EntityCounts> countsBefore =
dispatch.stack().getWritableStates(EntityIdService.NAME).getSingleton(ENTITY_COUNTS_STATE_ID);
countsBefore.put(requireNonNull(countsBefore.get())
.copyBuilder()
.numNodes(isSuccess ? Math.max(nextEntityNum + 1, prevEntityNum) : prevEntityNum)
.build());
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 not need this case anymore? Don't we need to look at the new state now instead of entity counts?

Copy link
Contributor

Choose a reason for hiding this comment

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

Here we were restoring the EntityCounts state, because before the dispatch we were updating it.
See here,
This code was preparing/updating the state so that when a NODE_CREATE transaction is dispatched, the new node will receive a specific, desired ID (nextEntityNum).
The both updating and restoring the EntityCounts are not needed anymore, because now we are passing the nextEntityNum to the handler by dispatch metadata.

Signed-off-by: Zhivko Kelchev <[email protected]>
Signed-off-by: Zhivko Kelchev <[email protected]>
# Conflicts:
#	hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/handle/HandleWorkflow.java
#	hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/hip869/NodeUpdateTest.java
#	hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/hip869/batch/AtomicNodeUpdateTest.java
Signed-off-by: Zhivko Kelchev <[email protected]>
# Conflicts:
#	hapi/hedera-protobuf-java-api/src/main/proto/block/stream/output/state_changes.proto
#	hapi/hedera-protobuf-java-api/src/main/proto/platform/state/virtual_map_state.proto
Signed-off-by: Zhivko Kelchev <[email protected]>
Signed-off-by: Zhivko Kelchev <[email protected]>
# Conflicts:
#	hedera-node/test-clients/src/main/java/com/hedera/services/bdd/suites/regression/system/DabEnabledUpgradeTest.java
Signed-off-by: Zhivko Kelchev <[email protected]>
Signed-off-by: Zhivko Kelchev <[email protected]>
# Conflicts:
#	hedera-node/hedera-app/src/main/java/com/hedera/node/app/workflows/handle/record/SystemTransactions.java
Signed-off-by: Zhivko Kelchev <[email protected]>
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.

Store the highest nodeID used in state

5 participants