Skip to content

Commit 3efe26b

Browse files
authored
feat: implement resource reclamation (#2065)
Signed-off-by: Artur Troian <troian@users.noreply.github.com> Co-authored-by: Artur Troian <troian@users.noreply.github.com>
1 parent 711b4e1 commit 3efe26b

27 files changed

Lines changed: 1433 additions & 95 deletions

File tree

.agents/skills/guidelines/SKILL.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
---
2+
name: guidelines
3+
description: Behavioral guidelines to reduce common LLM coding mistakes. Use when writing, reviewing, or refactoring code to avoid overcomplication, make surgical changes, surface assumptions, and define verifiable success criteria.
4+
license: MIT
5+
---
6+
7+
# Guidelines
8+
9+
**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.
10+
11+
## 1. Think Before Coding
12+
13+
**Don't assume. Don't hide confusion. Surface tradeoffs.**
14+
15+
Before implementing:
16+
- State your assumptions explicitly. If uncertain, ask.
17+
- If multiple interpretations exist, present them - don't pick silently.
18+
- If a simpler approach exists, say so. Push back when warranted.
19+
- If something is unclear, stop. Name what's confusing. Ask.
20+
21+
## 2. Simplicity First
22+
23+
**Minimum code that solves the problem. Nothing speculative.**
24+
25+
- No features beyond what was asked.
26+
- No abstractions for single-use code.
27+
- No "flexibility" or "configurability" that wasn't requested.
28+
- No error handling for impossible scenarios.
29+
- If you write 200 lines and it could be 50, rewrite it.
30+
31+
Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.
32+
33+
## 3. Surgical Changes
34+
35+
**Touch only what you must. Clean up only your own mess.**
36+
37+
When editing existing code:
38+
- Don't "improve" adjacent code, comments, or formatting.
39+
- Don't refactor things that aren't broken.
40+
- Match existing style, even if you'd do it differently.
41+
- If you notice unrelated dead code, mention it - don't delete it.
42+
43+
When your changes create orphans:
44+
- Remove imports/variables/functions that YOUR changes made unused.
45+
- Don't remove pre-existing dead code unless asked.
46+
47+
The test: Every changed line should trace directly to the user's request.
48+
49+
## 4. Goal-Driven Execution
50+
51+
**Define success criteria. Loop until verified.**
52+
53+
Transform tasks into verifiable goals:
54+
- "Add validation" → "Write tests for invalid inputs, then make them pass"
55+
- "Fix the bug" → "Write a test that reproduces it, then make it pass"
56+
- "Refactor X" → "Ensure tests pass before and after"
57+
58+
For multi-step tasks, state a brief plan:
59+
```
60+
1. [Step] → verify: [check]
61+
2. [Step] → verify: [check]
62+
3. [Step] → verify: [check]
63+
```
64+
65+
Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
name: upgrade-changelog
3+
description: "Generates CHANGELOG.md entries for upgrade versions found in upgrades/software/ by parsing init.go and upgrade.go"
4+
---
5+
# Instructions
6+
7+
Generate changelog entries in `upgrades/CHANGELOG.md` for any upgrade version under `upgrades/software/` that doesn't already have an entry.
8+
9+
## Steps
10+
11+
1. **Find semver directories** — list all directories under `upgrades/software/` whose names match `v<major>.<minor>.<patch>` (e.g., `v2.0.0`, `v1.0.0`).
12+
13+
2. **Read `upgrades/CHANGELOG.md`** — identify which versions already have entries by scanning for `##### vX.Y.Z` headings. If a version already has a heading, skip it entirely.
14+
15+
3. **For each new version** (no existing heading), gather data from two files:
16+
17+
### 3a. Parse `upgrades/software/<version>/init.go`
18+
19+
Find all `utypes.RegisterMigration(...)` calls. Each call has the form:
20+
```go
21+
utypes.RegisterMigration(moduleName, version, handlerFn)
22+
```
23+
- `moduleName` is a Go constant (e.g., `dv1.ModuleName`). Resolve it:
24+
1. Find the import alias (e.g., `dv1 "pkg.akt.dev/go/node/deployment/v1"`)
25+
2. Search the imported package for `ModuleName` constant definition to get the actual string value
26+
- `version` is a `uint64` — this is the **from** version. The **to** version is `version + 1`.
27+
- Record each migration as: `moduleName version -> version+1`
28+
29+
### 3b. Parse `upgrades/software/<version>/upgrade.go`
30+
31+
Find the `StoreLoader()` method. It returns a `*storetypes.StoreUpgrades` struct with optional fields:
32+
- `Added: []string{...}` — new stores
33+
- `Renamed: []storetypes.StoreRename{...}` — renamed stores
34+
- `Deleted: []string{...}` — removed stores
35+
36+
If `StoreLoader()` returns `nil`, there are no store changes.
37+
38+
For each store key constant (e.g., `epochstypes.StoreKey`, `ttypes.ModuleName`):
39+
1. Find the import alias in the file
40+
2. Search the imported package for the constant definition to get the actual string value
41+
42+
4. **Insert the new entry** in `upgrades/CHANGELOG.md` immediately after the line:
43+
```
44+
Add new upgrades after this line based on the template above
45+
```
46+
followed by `-----`.
47+
48+
Use this format (newest entries go first, right after the delimiter):
49+
50+
```markdown
51+
52+
##### vX.Y.Z
53+
54+
###### Description
55+
56+
- Stores
57+
- added
58+
- `storeName`: brief description if available
59+
- renamed
60+
- `oldName` -> `newName`
61+
- deleted
62+
- `storeName`: brief description if available
63+
64+
- Migrations
65+
- moduleName `from -> to`
66+
```
67+
68+
**Omission rules** (match existing CHANGELOG style):
69+
- Omit the entire `Stores` section if there are no added, renamed, or deleted stores
70+
- Omit `added`/`renamed`/`deleted` subsections individually if empty
71+
- Omit the entire `Migrations` section if there are no migrations
72+
- Always include the `###### Description` heading (leave it for the user to fill in)
73+
74+
5. **Report results** — list each version processed and what was added. For skipped versions (already in CHANGELOG), mention they were skipped.
75+
76+
## Important notes
77+
78+
- Store key constants may be named `StoreKey` or `ModuleName` — both are used as store identifiers. Resolve whichever constant appears in the code.
79+
- When resolving Go constants from external packages, search under the Go module cache or use `go doc` if needed. The packages typically follow the pattern `pkg.akt.dev/go/node/<module>/<version>`.
80+
- If a constant cannot be resolved, use the raw Go expression as a placeholder (e.g., `` `epochstypes.StoreKey` ``) and warn the user.
81+
- Multiple versions may need entries — process them all in one run, inserting newest first after the delimiter.

app/app.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ import (
5353
transfertypes "github.com/cosmos/ibc-go/v10/modules/apps/transfer/types"
5454
ibchost "github.com/cosmos/ibc-go/v10/modules/core/exported"
5555

56+
gogogrpc "github.com/cosmos/gogoproto/grpc"
57+
5658
cflags "pkg.akt.dev/go/cli/flags"
59+
aclient "pkg.akt.dev/go/node/client"
5760
epochstypes "pkg.akt.dev/go/node/epochs/v1beta1"
5861
"pkg.akt.dev/go/sdkutil"
5962

@@ -532,6 +535,11 @@ func (app *AkashApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIC
532535
// Register node gRPC service for grpc-gateway.
533536
nodeservice.RegisterGRPCGatewayRoutes(cctx, apiSvr.GRPCGatewayRouter)
534537

538+
// Register Akash Discovery gRPC-Gateway route for REST access at GET /akash/discovery/v1/info.
539+
if err := aclient.RegisterDiscoveryHandlerServer(cctx.CmdContext, apiSvr.GRPCGatewayRouter, aclient.NewDiscoveryServer(aclient.GetRegistry())); err != nil {
540+
panic(fmt.Errorf("failed to register discovery gRPC-Gateway routes: %w", err))
541+
}
542+
535543
// register swagger API from root so that other applications can override easily
536544
if apiConfig.Swagger {
537545
RegisterSwaggerAPI(cctx, apiSvr.Router)
@@ -557,6 +565,18 @@ func (app *AkashApp) RegisterNodeService(cctx client.Context, cfg config.Config)
557565
nodeservice.RegisterNodeService(cctx, app.GRPCQueryRouter(), cfg)
558566
}
559567

568+
// RegisterGRPCServerWithSkipCheckHeader registers all gRPC services including
569+
// the Akash Discovery service for version negotiation.
570+
func (app *AkashApp) RegisterGRPCServerWithSkipCheckHeader(server gogogrpc.Server, skipCheckHeader bool) {
571+
// Register all standard Cosmos SDK module query services.
572+
app.BaseApp.RegisterGRPCServerWithSkipCheckHeader(server, skipCheckHeader)
573+
574+
// Register Akash Discovery service directly on the gRPC server.
575+
// This enables version discovery for clients via gRPC at akash.discovery.v1.Discovery/GetInfo
576+
// and via REST through gRPC-Gateway at GET /akash/discovery/v1/info.
577+
aclient.RegisterDiscoveryService(server, aclient.GetRegistry())
578+
}
579+
560580
// RegisterSwaggerAPI registers swagger route with API Server
561581
func RegisterSwaggerAPI(_ client.Context, rtr *mux.Router) {
562582
statikFS, err := fs.New()

cmd/akash/cmd/app_creator.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ import (
1919
sdkserver "github.com/cosmos/cosmos-sdk/server"
2020
servertypes "github.com/cosmos/cosmos-sdk/server/types"
2121

22+
"github.com/cosmos/cosmos-sdk/version"
23+
2224
cflags "pkg.akt.dev/go/cli/flags"
25+
aclient "pkg.akt.dev/go/node/client"
2326
"pkg.akt.dev/go/sdkutil"
2427

2528
akash "pkg.akt.dev/node/v2/app"
@@ -81,6 +84,14 @@ func (a appCreator) newApp(
8184
cast.ToUint32(appOpts.Get(cflags.FlagStateSyncSnapshotKeepRecent)),
8285
)
8386

87+
// Configure version discovery registry with chain metadata.
88+
// This is used by the CometBFT JSON-RPC "akash" route (automatic via init())
89+
// and the gRPC Discovery service (registered in AkashApp.RegisterGRPCServerWithSkipCheckHeader).
90+
aclient.SetRegistry(aclient.DefaultRegistry(
91+
aclient.WithChainID(chainID),
92+
aclient.WithNodeVersion(version.Version),
93+
))
94+
8495
baseAppOptions := []func(*baseapp.BaseApp){
8596
baseapp.SetChainID(chainID),
8697
baseapp.SetPruning(pruningOpts),

go.mod

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module pkg.akt.dev/node/v2
22

3-
go 1.25.9
3+
go 1.26.2
44

55
require (
66
cosmossdk.io/api v0.9.2
@@ -35,7 +35,7 @@ require (
3535
github.com/prometheus/client_golang v1.23.2
3636
github.com/rakyll/statik v0.1.7
3737
github.com/regen-network/cosmos-proto v0.3.1
38-
github.com/rs/zerolog v1.34.0
38+
github.com/rs/zerolog v1.35.0
3939
github.com/spf13/cast v1.10.0
4040
github.com/spf13/cobra v1.10.2
4141
github.com/spf13/pflag v1.0.10
@@ -48,7 +48,7 @@ require (
4848
google.golang.org/grpc v1.76.0
4949
gopkg.in/yaml.v3 v3.0.1
5050
gotest.tools/v3 v3.5.2
51-
pkg.akt.dev/go v0.2.9
51+
pkg.akt.dev/go v0.2.10
5252
pkg.akt.dev/go/cli v0.2.2
5353
pkg.akt.dev/go/sdl v0.2.0
5454
)
@@ -59,12 +59,12 @@ replace (
5959
// use cosmos fork of keyring
6060
github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0
6161

62-
github.com/bytedance/sonic => github.com/bytedance/sonic v1.14.2
62+
github.com/bytedance/sonic => github.com/bytedance/sonic v1.15.0
6363

6464
// use akash fork of cometbft
6565
github.com/cometbft/cometbft => github.com/akash-network/cometbft v0.38.21-akash.1
6666
// use akash fork of cosmos sdk
67-
github.com/cosmos/cosmos-sdk => github.com/akash-network/cosmos-sdk v0.53.6-akash.1
67+
github.com/cosmos/cosmos-sdk => github.com/akash-network/cosmos-sdk v0.53.7-akash.1
6868

6969
github.com/cosmos/gogoproto => github.com/akash-network/gogoproto v1.7.0-akash.2
7070

@@ -118,8 +118,8 @@ require (
118118
github.com/bits-and-blooms/bitset v1.24.3 // indirect
119119
github.com/blang/semver/v4 v4.0.0 // indirect
120120
github.com/bytedance/gopkg v0.1.3 // indirect
121-
github.com/bytedance/sonic v1.14.2 // indirect
122-
github.com/bytedance/sonic/loader v0.4.0 // indirect
121+
github.com/bytedance/sonic v1.15.0 // indirect
122+
github.com/bytedance/sonic/loader v0.5.0 // indirect
123123
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
124124
github.com/cespare/xxhash/v2 v2.3.0 // indirect
125125
github.com/chzyer/readline v1.5.1 // indirect
@@ -210,7 +210,7 @@ require (
210210
github.com/jmhodges/levigo v1.0.1-0.20191019112844-b572e7f4cdac // indirect
211211
github.com/json-iterator/go v1.1.12 // indirect
212212
github.com/klauspost/compress v1.18.0 // indirect
213-
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
213+
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
214214
github.com/kr/pretty v0.3.1 // indirect
215215
github.com/kr/text v0.2.0 // indirect
216216
github.com/lib/pq v1.10.9 // indirect
@@ -262,25 +262,25 @@ require (
262262
github.com/zondax/hid v0.9.2 // indirect
263263
github.com/zondax/ledger-go v1.0.1 // indirect
264264
go.etcd.io/bbolt v1.4.0 // indirect
265-
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
265+
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
266266
go.opentelemetry.io/contrib/detectors/gcp v1.36.0 // indirect
267267
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
268268
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect
269-
go.opentelemetry.io/otel v1.37.0 // indirect
270-
go.opentelemetry.io/otel/metric v1.37.0 // indirect
269+
go.opentelemetry.io/otel v1.41.0 // indirect
270+
go.opentelemetry.io/otel/metric v1.41.0 // indirect
271271
go.opentelemetry.io/otel/sdk v1.37.0 // indirect
272272
go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect
273-
go.opentelemetry.io/otel/trace v1.37.0 // indirect
273+
go.opentelemetry.io/otel/trace v1.41.0 // indirect
274274
go.uber.org/mock v0.6.0 // indirect
275275
go.uber.org/multierr v1.11.0 // indirect
276276
go.uber.org/zap v1.27.0 // indirect
277277
go.yaml.in/yaml/v2 v2.4.2 // indirect
278278
go.yaml.in/yaml/v3 v3.0.4 // indirect
279-
golang.org/x/arch v0.17.0 // indirect
279+
golang.org/x/arch v0.24.0 // indirect
280280
golang.org/x/crypto v0.45.0 // indirect
281281
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
282282
golang.org/x/net v0.47.0 // indirect
283-
golang.org/x/sys v0.38.0 // indirect
283+
golang.org/x/sys v0.41.0 // indirect
284284
golang.org/x/term v0.37.0 // indirect
285285
golang.org/x/text v0.31.0 // indirect
286286
golang.org/x/time v0.12.0 // indirect

0 commit comments

Comments
 (0)