Skip to content

fix(grpc): return actual earliest_store_height in node.Status endpoint#25647

Merged
technicallyty merged 11 commits intocosmos:mainfrom
Cordtus:fix/earliest-store-height-upstream
Feb 6, 2026
Merged

fix(grpc): return actual earliest_store_height in node.Status endpoint#25647
technicallyty merged 11 commits intocosmos:mainfrom
Cordtus:fix/earliest-store-height-upstream

Conversation

@Cordtus
Copy link
Copy Markdown
Contributor

@Cordtus Cordtus commented Dec 5, 2025

Description

Closes: #15463

Add EarliestVersion() to the CommitMultiStore interface to enable querying the earliest available state height.
This addresses the longstanding TODO in the Status gRPC endpoint that was returning 0 for EarliestStoreHeight.

Problem

Indexers and tooling need to know which heights a pruned node can serve queries for. Currently:

  • earliest_block_height in CometBFT's STATUS RPC returns the earliest block, not the earliest state
  • The EarliestStoreHeight field in cosmos.base.node.v1beta1.Status was hardcoded to 0

Solution

  • Add EarliestVersion() int64 to the CommitMultiStore interface (not MultiStore, since CacheMultiStore lacks root DB access)
  • Implement persistent tracking in rootmulti.Store:
    • Stores earliest version at s/earliest key
    • Defaults to 1 for unpruned chains
    • Updates after successful pruning in PruneStores()
  • Add EarliestStoreHeight() and WithEarliestStoreHeight() to sdk.Context
  • Populate earliestStoreHeight in query context creation (CreateQueryContextWithCheckHeader)
  • Node gRPC service reads from context rather than storing a reference to the multistore

Changes

File Change
store/types/store.go Add EarliestVersion() to CommitMultiStore interface
store/rootmulti/store.go Implement EarliestVersion(), GetEarliestVersion(), flushEarliestVersion(), update PruneStores()
store/rootmulti/store_test.go Add 3 unit tests
types/context.go Add earliestStoreHeight field with getter/setter
baseapp/abci.go Populate earliestStoreHeight when creating query context
client/grpc/node/service.go Read EarliestStoreHeight from context
runtime/app.go Simplified service registration (no store param)
simapp/app.go Simplified service registration (no store param)

Testing

  • TestEarliestVersion - basic functionality, default value
  • TestEarliestVersionWithPruning - tracks updates after pruning
  • TestEarliestVersionPersistence - persists across restarts
  • System test: TestNodeStatus - gRPC endpoint returns valid heights

API Changes

Breaking change for any code implementing CommitMultiStore — must now implement EarliestVersion() int64.
No impact on MultiStore or CacheMultiStore implementations.

@fmorency
Copy link
Copy Markdown
Contributor

fmorency commented Dec 5, 2025

Would love to get this backported to 0.50.x. It would enable fixing manifest-network/yaci#28

@aljo242
Copy link
Copy Markdown
Contributor

aljo242 commented Dec 8, 2025

This seems like a nice feature but will need more extensive testing such as using systemtest if we are going to include

@Cordtus Cordtus force-pushed the fix/earliest-store-height-upstream branch from e7384c5 to eaa696a Compare December 10, 2025 20:22
@Cordtus
Copy link
Copy Markdown
Contributor Author

Cordtus commented Dec 10, 2025

Added systemtest for the node.Status gRPC endpoint:

  • Basic test confirms valid heights are returned
  • Pruning test configures aggressive state pruning and confirms earliest_store_height increases afterward

Also updated the service to use CommitMultiStore directly since query context provides a CacheMultiStore which doesn't support version queries.

Run locally:

make build && cp build/simd tests/systemtests/binaries/
cd tests/systemtests && go test -tags system_test -v -run TestNodeStatus

@Cordtus Cordtus changed the title feat(store): implement EarliestVersion for MultiStore fix(grpc): return actual earliest_store_height in node.Status endpoint Dec 10, 2025
@fmorency
Copy link
Copy Markdown
Contributor

@aljo242 is there anything blocking this PR?

@Cordtus
Copy link
Copy Markdown
Contributor Author

Cordtus commented Jan 7, 2026

Bump. Would like to be sure there is nothing else needed from my end here.

@Cordtus
Copy link
Copy Markdown
Contributor Author

Cordtus commented Jan 11, 2026

@aljo242 is there anything I can do to help this one along?

@Cordtus Cordtus force-pushed the fix/earliest-store-height-upstream branch from 995a18e to 1172c68 Compare January 22, 2026 06:00
@aljo242 aljo242 requested a review from technicallyty January 23, 2026 17:56
@aljo242
Copy link
Copy Markdown
Contributor

aljo242 commented Jan 23, 2026

@technicallyty to review this

@codecov
Copy link
Copy Markdown

codecov Bot commented Jan 23, 2026

Codecov Report

❌ Patch coverage is 17.50000% with 33 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.19%. Comparing base (f66e5e2) to head (95b8e59).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
store/rootmulti/store.go 0.00% 26 Missing ⚠️
client/grpc/node/service.go 54.54% 5 Missing ⚠️
runtime/app.go 33.33% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main   #25647      +/-   ##
==========================================
- Coverage   68.23%   68.19%   -0.04%     
==========================================
  Files         910      910              
  Lines       59147    59177      +30     
==========================================
- Hits        40358    40357       -1     
- Misses      18789    18820      +31     
Files with missing lines Coverage Δ
store/types/store.go 30.00% <ø> (ø)
runtime/app.go 64.07% <33.33%> (-1.27%) ⬇️
client/grpc/node/service.go 62.96% <54.54%> (-1.04%) ⬇️
store/rootmulti/store.go 46.88% <0.00%> (-1.89%) ⬇️

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

@technicallyty
Copy link
Copy Markdown
Member

This seems like a nice feature but will need more extensive testing such as using systemtest if we are going to include

i'm fine with merging this with systemtests, but i would like to use systemtest more sparingly in the future. systest runs a local 4 node network, which is not necessary for queries like this. an e2e integration test is more than enough for these types of PRs

Comment thread store/rootmulti/store.go
Comment thread client/grpc/node/service.go
@Cordtus Cordtus force-pushed the fix/earliest-store-height-upstream branch 3 times, most recently from 4f40612 to 5c4a042 Compare January 26, 2026 22:25
Add EarliestVersion() to the CommitMultiStore interface to enable
querying the earliest available state height. Placed on CommitMultiStore
rather than MultiStore since it requires root DB access that
CacheMultiStore does not have.

- Implement in rootmulti.Store with persistent DB storage
- Track earliest version after pruning in PruneStores
- Add unit tests for EarliestVersion functionality

Ref: cosmos#15463
Pass CommitMultiStore to the node query service to populate
EarliestStoreHeight in the Status response.
@Cordtus
Copy link
Copy Markdown
Contributor Author

Cordtus commented Jan 26, 2026

I edited the original description and cleaned it up a bit. This makes more sense for sure. Sorry for the mess.

Instead of passing CommitMultiStore directly to the node gRPC service,
add earliestStoreHeight field to sdk.Context and populate it when
creating query contexts. This is more idiomatic for the SDK and avoids
coupling the service to the store implementation.

- Add EarliestStoreHeight() and WithEarliestStoreHeight() to Context
- Populate context in CreateQueryContextWithCheckHeader
- Remove CommitMultiStore parameter from RegisterNodeService
@Cordtus Cordtus force-pushed the fix/earliest-store-height-upstream branch from 09b146d to 88416e6 Compare February 3, 2026 06:44
…tore-height

refactor: change how store height is retreived
@technicallyty
Copy link
Copy Markdown
Member

just need changelog and test fixes

Add missing earliestStoreHeightFn argument to NewQueryServer call
in test, matching the updated function signature.
@Cordtus
Copy link
Copy Markdown
Contributor Author

Cordtus commented Feb 5, 2026

The golangci-lint and tests (00) failures are fixed by the latest push (missing arg in service_test.go).

The dependency-review failure is due to a new Go stdlib vulnerability GO-2026-4337 in crypto/tls@go1.25.6, fixed in Go 1.25.7. Opened #25875 for the version bump — will rebase once that merges or is fixed elsewhere.

@technicallyty technicallyty added this pull request to the merge queue Feb 6, 2026
Merged via the queue into cosmos:main with commit ae80efb Feb 6, 2026
44 of 45 checks passed
@Cordtus
Copy link
Copy Markdown
Contributor Author

Cordtus commented Feb 11, 2026

@aljo242 @technicallyty -- same request here, could the backport/v0.53.x label be added? This fix complements #25648 and would be good to have in the next v0.53.x patch. Thanks!

@technicallyty
Copy link
Copy Markdown
Member

@mergify backport release/v0.53.x

@mergify
Copy link
Copy Markdown
Contributor

mergify Bot commented Feb 11, 2026

backport release/v0.53.x

✅ Backports have been created

Details

Cherry-pick of ae80efb has failed:

On branch mergify/bp/release/v0.53.x/pr-25647
Your branch is up to date with 'origin/release/v0.53.x'.

You are currently cherry-picking commit ae80efbfd.
  (fix conflicts and run "git cherry-pick --continue")
  (use "git cherry-pick --skip" to skip this patch)
  (use "git cherry-pick --abort" to cancel the cherry-pick operation)

Changes to be committed:
	modified:   client/grpc/node/service.go
	modified:   client/grpc/node/service_test.go
	modified:   runtime/app.go
	modified:   server/mock/store.go
	modified:   simapp/app.go
	modified:   store/rootmulti/store_test.go
	modified:   store/types/store.go
	new file:   tests/systemtests/node_service_test.go

Unmerged paths:
  (use "git add/rm <file>..." as appropriate to mark resolution)
	both modified:   CHANGELOG.md
	deleted by us:   enterprise/poa/simapp/app.go
	both modified:   store/rootmulti/store.go

To fix up this pull request, you can check it out locally. See documentation: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally

mergify Bot pushed a commit that referenced this pull request Feb 11, 2026
#25647)

Co-authored-by: Tyler <48813565+technicallyty@users.noreply.github.com>
Co-authored-by: Alex | Cosmos Labs <alex@cosmoslabs.io>
(cherry picked from commit ae80efb)

# Conflicts:
#	CHANGELOG.md
#	enterprise/poa/simapp/app.go
#	store/rootmulti/store.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make query to find what states a given node exposes

4 participants