This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
ev-node is a sovereign rollup framework built in Go that allows developers to build rollups on any DA layer. It provides a modular architecture where components like the data availability layer, executor, and sequencer can be plugged in.
make build- Builds the Testapp CLI to./build/testappmake install- Installs Testapp CLI to your Go bin directorymake build-all- Builds all ev-node binariesmake docker-build- Builds Docker image tagged asevstack:local-dev
make test- Runs unit tests for all go.mod filesmake test-integration- Runs integration tests (15m timeout)make test-e2e- Runs end-to-end tests (requires building binaries first)make test-cover- Generates code coverage reportmake test-all- Runs all tests including Docker E2E tests
make lint- Runs all linters (golangci-lint, markdownlint, hadolint, yamllint, goreleaser check, actionlint)make lint-fix- Auto-fixes linting issues where possiblemake vet- Runs go vet
make deps- Downloads dependencies and runs go mod tidy for all modulesmake proto-gen- Generates protobuf files (requires Docker)make mock-gen- Generates mocks using mockerymake run-n NODES=3- Run multiple nodes locally (default: 1)
The project uses a zero-dependency core package pattern:
- core/ - Contains only interfaces and types, no external dependencies
- block/ - Block management, creation, validation, and synchronization
- p2p/ - Networking layer built on libp2p
- sequencing/ - Modular sequencer implementations
- testapp/ - Reference implementation for testing
- Executor (core/executor.go) - Handles state transitions
- Sequencer (core/sequencer.go) - Orders transactions
- Blob API (block/internal/da/client.go) - Data availability client abstraction used by the node
- Each component has an interface in the core package
- Implementations are in separate packages
- Components are wired together via dependency injection
- Multiple go.mod files enable modular builds
- Built on libp2p with GossipSub and Kademlia DHT
- Nodes advertise capabilities (full/light, DA layers)
- Automatic peer discovery with rendezvous points
- Unit tests:
*_test.gofiles alongside code - Integration tests:
test/integration/ - E2E tests:
test/e2e/
# Run a single test
go test -run TestSpecificFunction ./package/...
# Run with verbose output
go test -v ./package/...
# Run with race detection
go test -race ./package/...- Mocks are defined in
.mockery.yaml - Generate with
make mock-gen - Mocks are placed in
mocks/directories
- Follow standard Go formatting (enforced by golangci-lint)
- Use meaningful variable names
- Keep functions small and focused
- Document exported types and functions
- Use context.Context for cancellation
- Wrap errors with context using
fmt.Errorf - Return errors early
- Use custom error types for domain-specific errors
- Use structured logging (look for existing patterns)
- Include relevant context in log messages
- Use appropriate log levels
- Implement the
BlobAPIinterface fromblock/internal/da/client.go(or extend the shared helpers inpkg/blob) - Add configuration in the appropriate config package
- Wire it up in the initialization code
- Add tests following existing patterns
- Edit
.protofiles intypes/pb/ - Run
make proto-gento regenerate Go code - Update any affected code
- Run tests to ensure compatibility
- Place unit tests next to the code being tested
- Use table-driven tests where appropriate
- Mock external dependencies using mockery
- Ensure tests are deterministic
- Never expose private keys in logs or errors
- Validate all inputs from external sources
- Use secure random number generation
- Follow the principle of least privilege
- Be careful with concurrent access to shared state
- The project uses concurrent processing extensively
- Be mindful of goroutine leaks
- Use buffered channels appropriately
- Profile before optimizing
- Consider memory allocation in hot paths
- Use
make run-n NODES=2to test multi-node scenarios locally - Check logs for error messages and stack traces
- Use Go's built-in profiling tools for performance issues
- The testapp provides a simple way to test changes
- All code must pass linting (
make lint) - All tests must pass (
make test-all) - Follow the existing code patterns
- Update tests when changing functionality
- Keep commits focused and atomic