Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1def3c3d5f |
416
CLAUDE.md
Normal file
416
CLAUDE.md
Normal file
@ -0,0 +1,416 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Overview
|
||||
|
||||
This is the **Cosmos SDK** - a framework for building application-specific blockchains in Go. The SDK uses CometBFT for consensus and is organized as a multi-module monorepo with 23+ separate Go modules.
|
||||
|
||||
## Build & Development Commands
|
||||
|
||||
### Building
|
||||
|
||||
```bash
|
||||
# Build the simapp binary (reference application)
|
||||
make build # Outputs to ./build/simd
|
||||
|
||||
# Build for specific platforms
|
||||
make build-linux-amd64
|
||||
make build-linux-arm64
|
||||
|
||||
# Install to $GOPATH/bin
|
||||
make install
|
||||
```
|
||||
|
||||
Build tags can be controlled via `COSMOS_BUILD_OPTIONS`:
|
||||
- `ledger` - Enable Ledger hardware wallet support (default on)
|
||||
- `secp` - Use libsecp256k1
|
||||
- `legacy` - Build with app_v1 (legacy manual wiring)
|
||||
- `rocksdb`, `badgerdb`, `boltdb`, `cleveldb` - Database backends
|
||||
|
||||
### Testing
|
||||
|
||||
```bash
|
||||
# Run all unit tests (recommended)
|
||||
make test-unit # Fast unit tests across all modules
|
||||
|
||||
# Run tests by category
|
||||
make test-integration # Integration tests in /tests
|
||||
make test-e2e # End-to-end tests
|
||||
make test-all # Everything including race detector
|
||||
|
||||
# Run tests for a single module
|
||||
cd x/bank && go test ./...
|
||||
|
||||
# Run a specific test
|
||||
cd x/bank && go test -run TestKeeper_SendCoins ./keeper
|
||||
|
||||
# Run with race detector
|
||||
make test-race
|
||||
|
||||
# System tests (requires building v0.50 branch first)
|
||||
make test-system
|
||||
```
|
||||
|
||||
**Note:** The test suite iterates through all modules (based on go.mod files). Install `tparse` for prettier output: `go install github.com/mfridman/tparse@latest`
|
||||
|
||||
### Linting
|
||||
|
||||
```bash
|
||||
# Run linter across all modules
|
||||
make lint
|
||||
|
||||
# Auto-fix linting issues
|
||||
make lint-fix
|
||||
|
||||
# Lint only changed files
|
||||
LINT_DIFF=1 make lint
|
||||
```
|
||||
|
||||
Linting uses golangci-lint v2.1.5 with tags: `e2e,ledger,test_ledger_mock,system_test,sims`
|
||||
|
||||
### Protobuf
|
||||
|
||||
```bash
|
||||
# Generate all protobuf code (requires Docker)
|
||||
make proto-gen
|
||||
|
||||
# Format proto files
|
||||
make proto-format
|
||||
|
||||
# Lint proto files
|
||||
make proto-lint
|
||||
|
||||
# Check for breaking changes against main
|
||||
make proto-check-breaking
|
||||
|
||||
# Update CometBFT proto dependencies
|
||||
make proto-update-deps
|
||||
```
|
||||
|
||||
Protobuf generation uses `ghcr.io/cosmos/proto-builder:0.16.0` Docker image.
|
||||
|
||||
### Local Testing Network
|
||||
|
||||
```bash
|
||||
# Initialize a single-node network for testing
|
||||
make init-simapp # Sets up ~/.simapp
|
||||
simd start # Run the node
|
||||
|
||||
# Start a 4-node local testnet with Docker
|
||||
make localnet-start # Builds images and starts nodes
|
||||
|
||||
# Stop the testnet
|
||||
make localnet-stop
|
||||
```
|
||||
|
||||
### Simulations
|
||||
|
||||
```bash
|
||||
# Run simulation tests
|
||||
make test-sim-nondeterminism # Determinism check
|
||||
make test-sim-multi-seed-short # Quick multi-seed test
|
||||
make test-sim-multi-seed-long # Long-running test
|
||||
|
||||
# Benchmarking
|
||||
make test-sim-benchmark SIM_NUM_BLOCKS=500 SIM_BLOCK_SIZE=200
|
||||
```
|
||||
|
||||
### Other Useful Commands
|
||||
|
||||
```bash
|
||||
# Generate mocks for testing
|
||||
make mocks
|
||||
|
||||
# Check for vulnerabilities
|
||||
make vulncheck
|
||||
|
||||
# View Go docs locally
|
||||
make godocs # Visit http://localhost:6060
|
||||
|
||||
# Clean build artifacts
|
||||
make clean
|
||||
make distclean # Also cleans tools
|
||||
```
|
||||
|
||||
## Architecture & Structure
|
||||
|
||||
### Multi-Module Organization
|
||||
|
||||
This repository contains 23 separate Go modules with independent versioning:
|
||||
|
||||
**Core Packages (cosmossdk.io/*):**
|
||||
- `core/` - Core interfaces defining the SDK's module architecture
|
||||
- `api/` - Pulsar-generated protobuf code
|
||||
- `collections/` - Type-safe state management (recommended over raw KVStore)
|
||||
- `depinject/` - Dependency injection framework for app wiring
|
||||
- `store/` - State storage layer (IAVL, KVStore)
|
||||
- `errors/`, `math/`, `log/` - Utility packages
|
||||
|
||||
**Main SDK (github.com/cosmos/cosmos-sdk):**
|
||||
- `baseapp/` - ABCI application base implementation
|
||||
- `runtime/` - Modern app wiring system (App v2)
|
||||
- `x/*/` - Core blockchain modules (auth, bank, staking, gov, etc.)
|
||||
- `types/` - Common SDK types
|
||||
- `client/`, `server/` - Client and node infrastructure
|
||||
|
||||
**Reference Application:**
|
||||
- `simapp/` - Example blockchain application showing best practices
|
||||
|
||||
**Extracted Modules (cosmossdk.io/x/*):**
|
||||
- `x/tx/`, `x/upgrade/`, `x/feegrant/`, `x/evidence/`, `x/circuit/`, `x/nft/`, `x/epochs/`
|
||||
|
||||
**Tools:**
|
||||
- `tools/cosmovisor/` - Automated upgrade tool
|
||||
- `tools/confix/` - Config file migration tool
|
||||
- `tools/hubl/` - gRPC client
|
||||
|
||||
### App Architecture: V1 vs V2
|
||||
|
||||
The SDK supports two app wiring approaches:
|
||||
|
||||
**App v2 (Default - Recommended):**
|
||||
- File: `simapp/app_di.go` (385 lines)
|
||||
- Build: `go build ./simapp` or `go build -tags !app_v1`
|
||||
- Uses dependency injection (`depinject`) for automatic wiring
|
||||
- Configuration in `simapp/app_config.go` (declarative)
|
||||
- ~57% less boilerplate code
|
||||
- Easier to maintain and extend
|
||||
|
||||
**App v1 (Legacy):**
|
||||
- File: `simapp/app.go` (906 lines)
|
||||
- Build: `go build -tags app_v1 ./simapp`
|
||||
- Manual keeper instantiation and ordering
|
||||
- More control but more error-prone
|
||||
- Maintained for backward compatibility
|
||||
|
||||
For new applications, **always use App v2** (depinject-based) approach.
|
||||
|
||||
### Module Structure
|
||||
|
||||
Standard module layout in `x/[module]/`:
|
||||
|
||||
```
|
||||
x/bank/
|
||||
├── keeper/ # Business logic and state management
|
||||
│ ├── keeper.go # Keeper interface
|
||||
│ ├── send.go # Core operations
|
||||
│ ├── grpc_query.go # Query handlers
|
||||
│ └── msg_server.go # Transaction handlers
|
||||
├── types/ # Protobuf types, keys, errors
|
||||
│ ├── keys.go # Store key definitions
|
||||
│ ├── msgs.go # Message types
|
||||
│ └── *.pb.go # Generated proto code
|
||||
├── client/cli/ # CLI commands
|
||||
├── migrations/ # State migration code (v1/, v2/, etc.)
|
||||
├── simulation/ # Randomized simulation tests
|
||||
├── testutil/ # Test utilities
|
||||
├── module.go # Module definition & depinject wiring
|
||||
├── autocli.go # AutoCLI configuration
|
||||
└── README.md # Module documentation
|
||||
```
|
||||
|
||||
### Key Architectural Patterns
|
||||
|
||||
**1. Keeper Pattern:**
|
||||
- Encapsulates all module state access
|
||||
- Depends on interfaces, not concrete types
|
||||
- Uses `collections` for type-safe state management
|
||||
- Injected via depinject
|
||||
|
||||
**2. Collections Framework (Recommended):**
|
||||
Use instead of raw KVStore byte manipulation:
|
||||
```go
|
||||
// Define typed state in keeper
|
||||
type Keeper struct {
|
||||
Balances collections.Map[sdk.AccAddress, sdk.Coins]
|
||||
Supply collections.Map[string, math.Int]
|
||||
}
|
||||
|
||||
// Access is type-safe
|
||||
balance, err := k.Balances.Get(ctx, addr)
|
||||
k.Balances.Set(ctx, addr, newBalance)
|
||||
```
|
||||
|
||||
**3. Module Service Pattern:**
|
||||
Modules expose gRPC services for state transitions (Msg) and queries (Query)
|
||||
|
||||
**4. Dependency Injection:**
|
||||
Modules use `depinject.Provide()` in `module.go` to register dependencies automatically
|
||||
|
||||
## Module Categories
|
||||
|
||||
**Essential Modules** (required for most chains):
|
||||
- `x/auth` - Account authentication
|
||||
- `x/bank` - Token transfers
|
||||
- `x/staking` - Proof-of-Stake consensus
|
||||
- `x/distribution` - Fee and reward distribution
|
||||
- `x/gov` - On-chain governance
|
||||
- `x/mint` - Token inflation
|
||||
- `x/slashing` - Validator punishment
|
||||
- `x/consensus` - Consensus parameter management
|
||||
- `x/upgrade` - Coordinated upgrades
|
||||
|
||||
**Supplementary Modules** (optional):
|
||||
- `x/authz` - Generic authorization
|
||||
- `x/feegrant` - Fee allowances
|
||||
- `x/epochs` - Timed execution hooks
|
||||
- `x/protocolpool` - Community fund management
|
||||
|
||||
**Deprecated Modules** (moving to cosmos-sdk-legacy):
|
||||
- `x/params` - Use collections instead
|
||||
- `x/crisis` - Use x/circuit instead
|
||||
- `x/nft`, `x/group`
|
||||
|
||||
## Development Workflows
|
||||
|
||||
### Adding a New Module to an App
|
||||
|
||||
1. Add module configuration to `app_config.go`:
|
||||
```go
|
||||
{
|
||||
Name: mymoduletypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&mymodulev1.Module{
|
||||
// module config
|
||||
}),
|
||||
}
|
||||
```
|
||||
|
||||
2. Add to appropriate lifecycle arrays (PreBlockers, BeginBlockers, EndBlockers, InitGenesis)
|
||||
|
||||
3. Inject keeper in `app_di.go`:
|
||||
```go
|
||||
depinject.Inject(appConfig,
|
||||
// ... other keepers
|
||||
&app.MyModuleKeeper,
|
||||
)
|
||||
```
|
||||
|
||||
### Creating a New Module
|
||||
|
||||
1. Define protobuf messages in `proto/cosmos/mymodule/v1/`
|
||||
2. Create keeper with collections-based state
|
||||
3. Implement `module.go` with depinject providers
|
||||
4. Implement MsgServer and QueryServer
|
||||
5. Add genesis init/export logic
|
||||
6. Write tests and simulation code
|
||||
7. Document in README.md
|
||||
|
||||
### State Migrations
|
||||
|
||||
When upgrading module state schema:
|
||||
|
||||
1. Create `migrations/vX/migrate.go`
|
||||
2. Implement migration logic
|
||||
3. Register in keeper: `m.RegisterMigration("mymodule", fromVersion, migrationFunc)`
|
||||
4. Submit governance proposal with upgrade plan
|
||||
|
||||
### Running a Single Module's Tests
|
||||
|
||||
```bash
|
||||
# Navigate to module
|
||||
cd x/bank
|
||||
|
||||
# Run all tests in module
|
||||
go test ./...
|
||||
|
||||
# Run specific package
|
||||
go test ./keeper
|
||||
|
||||
# Run specific test
|
||||
go test -run TestSendCoins ./keeper
|
||||
|
||||
# With verbose output
|
||||
go test -v ./...
|
||||
|
||||
# With coverage
|
||||
go test -cover ./...
|
||||
```
|
||||
|
||||
## Code Conventions
|
||||
|
||||
### State Management
|
||||
- **Always use `collections`** for new state (not raw KVStore bytes)
|
||||
- Use appropriate collection type: Map, KeySet, Item, Sequence, IndexedMap
|
||||
- Define state in keeper struct with clear naming
|
||||
|
||||
### Errors
|
||||
- Import `cosmossdk.io/errors`
|
||||
- Define module-specific errors in `types/errors.go`
|
||||
- Use `errors.Wrap()` for context
|
||||
|
||||
### Keeper Dependencies
|
||||
- Depend on interfaces, not concrete keepers
|
||||
- Define expected keepers in `types/expected_keepers.go`
|
||||
- Use depinject for automatic wiring
|
||||
|
||||
### Protobuf
|
||||
- Define messages in `proto/cosmos/[module]/[version]/`
|
||||
- Use buf for linting and generation
|
||||
- Follow naming conventions in ADR-023
|
||||
|
||||
### Testing
|
||||
- Unit tests in `*_test.go` files alongside source
|
||||
- Integration tests in `/tests`
|
||||
- Use testutil helpers from `testutil/` and module-specific `testutil/`
|
||||
- Write simulation tests in `simulation/`
|
||||
|
||||
## Important Notes
|
||||
|
||||
### Git Workflow
|
||||
- Main branch: `main`
|
||||
- This is a clean working tree
|
||||
- Recent work focuses on repo cleanup and deprecation warnings
|
||||
|
||||
### Protobuf Changes
|
||||
Always regenerate after modifying `.proto` files:
|
||||
```bash
|
||||
make proto-gen
|
||||
```
|
||||
|
||||
### Multi-Module Testing
|
||||
Tests run across all Go modules. A failure in any module fails the overall test run.
|
||||
|
||||
### Version Information
|
||||
- CometBFT version: Extracted from `go.mod` via `go list -m github.com/cometbft/cometbft`
|
||||
- SDK version: Git tag-based (v0.0.0-{hash} if not on a tagged release)
|
||||
|
||||
### Database Backends
|
||||
Default is LevelDB. Alternative backends (RocksDB, BadgerDB, etc.) require:
|
||||
1. Installing system dependencies
|
||||
2. Setting `COSMOS_BUILD_OPTIONS` environment variable
|
||||
3. Rebuilding binary
|
||||
|
||||
## Documentation
|
||||
|
||||
- Official docs: https://docs.cosmos.network
|
||||
- Tutorials: https://tutorials.cosmos.network
|
||||
- ADRs (Architecture Decision Records): `docs/architecture/`
|
||||
- Module docs: Each `x/[module]/README.md`
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
1. **Don't manually manipulate bytes** - Use collections framework
|
||||
2. **Don't skip protobuf generation** - Always run `make proto-gen` after proto changes
|
||||
3. **Don't forget build tags** - Tests use specific tags (see Makefile)
|
||||
4. **Don't import from `/api`** - Use module-specific generated code for gogoproto types
|
||||
5. **Module order matters** - BeginBlocker/EndBlocker execution order is significant
|
||||
6. **Use App v2** - Don't start new apps with the legacy manual wiring approach
|
||||
|
||||
## Quick Reference
|
||||
|
||||
**Find things:**
|
||||
- Modules: `x/*/`
|
||||
- Core interfaces: `core/`
|
||||
- Example app: `simapp/`
|
||||
- Proto definitions: `proto/cosmos/`
|
||||
- Tests: `tests/`, or `*/testutil/`, or `*/*_test.go`
|
||||
|
||||
**Common file names:**
|
||||
- `module.go` - Module registration and depinject setup
|
||||
- `keeper.go` - State management
|
||||
- `keys.go` - Store prefixes and keys
|
||||
- `msgs.go` - Transaction message types
|
||||
- `codec.go` - Encoding registration
|
||||
- `autocli.go` - CLI configuration
|
||||
- `app_config.go` - App module configuration (App v2)
|
||||
Loading…
Reference in New Issue
Block a user