-
Notifications
You must be signed in to change notification settings - Fork 18
Development
Before setting up the development environment, ensure you have:
- Git - Version control system
- Go 1.25+ - Latest Go runtime (download from https://go.dev/dl/)
- Docker & Docker Compose - For containerized services
- Timescale+ - Database (or use Docker version)
- Make - Build automation tool (pre-installed on macOS/Linux)
git clone https://github.com/celenium-io/celestia-indexer.git
cd celestia-indexerCreate a .env file in the project root with required variables:
cp .env.example .envEdit .env and set the following required variables:
# Celestia Node Configuration
CELESTIA_NODE_URL=http://localhost:26657 # Consensus node RPC
CELESTIA_NODE_API_URL=http://localhost:1317 # LCD API endpoint
CELESTIA_DAL_API_URL=http://localhost:7654 # Data availability API
CELESTIA_NODE_AUTH_TOKEN=<token-from-node> # Node auth token
# Database Configuration
POSTGRES_HOST=db # or localhost
POSTGRES_PORT=5432
POSTGRES_USER=postgres
POSTGRES_PASSWORD=<secure-password>
POSTGRES_DB=celestia
# Cache Configuration (optional)
VALKEY_HOST=cache
VALKEY_PORT=6379
# API Configuration
API_PORT=9876
PRIVATE_API_PORT=9877
# Logging
LOG_LEVEL=info # debug, info, warn, error
# Indexing Parameters
INDEXER_BLOCK_PERIOD=15 # Seconds between blocks
INDEXER_REQUEST_BULK_SIZE=10 # Blocks per request
# Optional: Monitoring
SENTRY_DSN=<sentry-dsn>
PYROSCOPE_ENABLED=false
PYROSCOPE_URL=http://localhost:4040go mod download
go mod tidyRun the initialization script:
make initThis will set up the development environment and prepare the database.
Start all services:
make composeThis starts:
- PostgreSQL database (localhost:5432)
- Valkey cache (localhost:6379)
- Indexer service
- API service (localhost:9876)
- Private API service (localhost:9877)
View logs:
docker-compose logs -f [service-name]Stop services:
docker-compose downmake indexerOr manually:
cd cmd/indexer && go run . -c ../../configs/dipdup.ymlmake apiOr manually:
cd cmd/api && go run . -c ../../configs/dipdup.ymlmake private_apimake celestialsCreate optimized binaries:
make buildThis generates executables in the bin/ directory:
-
bin/indexer- Main indexing service -
bin/api- REST API service -
bin/private_api- Internal API service -
bin/celestials- Celestials service
Build individual binaries:
cd cmd/indexer && go build -a -o ../../bin/indexer .Build all Docker images:
docker-compose buildBuild a specific image:
docker-compose build indexer
docker-compose build apimake testWith coverage:
go test -cover -coverprofile=coverage.out ./...
go tool cover -html=coverage.out# Test a single package
go test ./internal/storage/...
# Test a specific test
go test ./internal/storage/... -run TestBlockRepository
# Verbose output
go test -v ./...
# Parallel execution
go test -p 8 ./...The codebase uses testfixtures for test data. Fixtures are located in test data directories and loaded before tests run.
Run the linter:
make lintOr manually:
golangci-lint runFormat code:
go fmt ./...Generate code for mocks, interfaces, and SQL:
make generateThis regenerates:
- Mock implementations
- Storage interfaces
- ORM generated code
- Node type definitions
The database is automatically initialized on first run with:
- Table schemas
- Indexes
- Partitions
- Materialized views
- Functions
Migrations are applied automatically by the indexer on startup.
To manually apply scripts:
# Using psql
psql -h localhost -U postgres -d celestia < database/views/00_block_stats_by_minute.sqlAccess the database:
docker exec -it celestia-indexer-db-1 psql -U postgres -d celestiaOr locally if PostgreSQL is installed:
psql -h localhost -U postgres -d celestiaGenerate API documentation:
make api-docsAccess API docs at: http://localhost:9876/v1/docs
- Create handler in
cmd/api/handler/ - Add request/response models
- Add enpoint in routes
cmd/api/init.go - Document with Swagger comments
- Add tests to route tests
Example handler structure:
// GetBlock returns block information
// @Summary Get block by height
// @Tags Block
// @Produce json
// @Param height path integer true "Block Height"
// @Success 200 {object} BlockResponse
// @Router /v1/blocks/{height} [get]
func (h *Handler) GetBlock(c echo.Context) error {
// handler implementation
}Set LOG_LEVEL=debug in .env:
LOG_LEVEL=debug# Install delve
go install github.com/go-delve/delve/cmd/dlv@latest
# Debug indexer
dlv debug ./cmd/indexer
# At dlv prompt
(dlv) break main.main
(dlv) continueThe application integrates Pyroscope for performance profiling:
- Enable in
.env:
PYROSCOPE_ENABLED=true
PYROSCOPE_URL=http://localhost:4040- View profiles at the Pyroscope URL
# Connect to database
psql -h localhost -U postgres -d celestia
# Check active connections
SELECT count(*) FROM pg_stat_activity;
# View slow queries
SELECT query, calls, mean_exec_time
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;-
Enable Query Stats (Docker Compose default):
-
-cpg_stat_statements.track=allflag enables query tracking
-
-
Review Slow Queries:
SELECT * FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 20;
-
Analyze Table Plans:
EXPLAIN ANALYZE SELECT * FROM blocks;
Adjust bulk size in .env:
INDEXER_REQUEST_BULK_SIZE=20 # Increase for faster processingAdjust block period:
INDEXER_BLOCK_PERIOD=15 # Lower for more frequent checks- Always use transactions for multi-step operations
- Handle context cancellation gracefully
- Use dependency injection for testability
- Write unit tests for new functions
- Document public APIs with godoc comments
- Use structured logging with zerolog
- Validate input in API handlers
-
Use error wrapping with
pkg/errors - Follow Go conventions (gofmt, naming)
When contributing to the project:
- Create a feature branch:
git checkout -b feature/your-feature - Make changes and write tests
- Run tests and linting
- Push and create a pull request
- Address review comments
- Merge when approved