Lotus is a universally open project and welcomes contributions of all kinds: code, docs, and more. We appreciate your interest in contributing!
- Before Contributing
- Implementing Changes
- Working with builtin-actors
- PR Title Conventions
- CHANGELOG Management
- Dependency Management
- Go Version Management
- Markdown Conventions
- Getting Help
- Familiarize yourself with our release flow to understand how changes are incorporated into releases. This includes our branch strategy and where to target PRs.
- If the proposal entails a protocol change, please first submit a Filecoin Improvement Proposal.
- If the change is complex and requires prior discussion, open an issue or a discussion to request feedback before you start working on a pull request. This is to avoid disappointment and sunk costs, in case the change is not actually needed or accepted.
- Please refrain from submitting PRs to adapt existing code to subjective preferences. The changeset should contain functional or technical improvements/enhancements, bug fixes, new features, or some other clear material contribution. Simple stylistic changes are likely to be rejected in order to reduce code churn.
When implementing a change:
- Adhere to the standard Go formatting guidelines, e.g. Effective Go. Run
go fmt. - Stick to the idioms and patterns used in the codebase. Familiar-looking code has a higher chance of being accepted than eerie code. Pay attention to commonly used variable and parameter names, avoidance of naked returns, error handling patterns, etc.
- Comments: follow the advice on the Commentary section of Effective Go.
- Minimize code churn. Modify only what is strictly necessary. Well-encapsulated changesets will get a quicker response from maintainers.
- Lint your code with
golangci-lint(CI will reject your PR if unlinted). - Add tests.
- Write clean, thoughtful, and detailed commit messages. This is even more important than the PR description, because commit messages are stored inside the Git history. One good rule is: if you are happy posting the commit message as the PR description, then it's a good commit message.
For doing FIP development that involves a change in builtin-actors which needs to also be exposed in Lotus, see the builtin-actor Development Guide.
PR titles should follow Conventional Commits standard.
This means the PR title should be in the form of <type>(<scope>): <description>
- example:
fix(mempool): introduce a cache for valid signatures type: MUST be one of build, chore, ci, docs, feat, fix, perf, refactor, revert, style, testscope: OPTIONAL arbitrary string that is usually one of api, chain, deps, mempool, multisig, networking, paych, proving, sealing, state, wallet- Breaking changes must add a
!
Alternatively, titles can match a GitHub revert title: Revert "<original title>"
- example:
Revert "feat: add new feature"
Note that this is enforced with https://github.com/filecoin-project/lotus/blob/master/.github/workflows/pr-title-check.yml
If it is unclear why one's title is getting flagged, it the regex defined in pr-title-check.yml can be plugged into a debugger like regex101.com.
To expedite the release process, the CHANGELOG is built-up incrementally. We enforce that each PR updates CHANGELOG.md or signals that the change doesn't need it. If the PR affects users (e.g., new feature, bug fix, system requirements change), update the CHANGELOG.md and add details to the UNRELEASED section. If the change does not require a CHANGELOG.md entry, do one of the following:
- Add
[skip changelog]to the PR description - Add the label
skip/changelogto the PR
Note that this is enforced with https://github.com/filecoin-project/lotus/blob/master/.github/workflows/changelog.yml
We strive to use release dependencies because:
- Security / reliability - While there's no guarantee that a released version doesn't have bugs or issues, it seems fair to assume that non-released versions have even more. For example, filecoin-project#12467 was triggered because of a bug in non-released library that lotus was depending on when the latest released version didn't have the bug.
- Faster builds
- Makes Lotus a better citizen when it's imported by other projects.
We enforce that each dependency on an unreleased version of a package is explicitly documented in the go.mod file via an inline comment of the form dependency-check-ignore: <reason>.
- If you are adding such a dependency, please add a suitable comment to the
go.modfile as well. - This requirement applies both to direct and indirect dependencies.
- This requirement applies to packages that have released versions (i.e., is not a
v0.0.0). - This is enforced with https://github.com/filecoin-project/lotus/blob/master/.github/workflows/dependency-check.yml
- This enforcement was initially done per #7131.
Lotus follows a conservative Go version strategy to balance stability with access to new features:
- Stay One Minor Version Behind: We typically use the Go version that is one minor version behind the latest stable release
- Gradual Adoption: When a new Go minor version is released, we continue using the previous version for approximately one month before upgrading
This approach provides:
- Stability: Allows time for the Go community to identify and fix issues in new releases
- Ecosystem Compatibility: Ensures our dependencies have time to test and adapt to new Go versions
- Predictable Upgrades: Contributors and downstream users can anticipate Go version requirements
Here's how our Go version policy works in practice:
Time t: Latest Go minor version is 1.24.x. We use 1.23.x.
Time t': Go 1.25.x is released. We continue using 1.23.x
(transition period of ~1 month).
Time t'+1 month: Latest Go minor version is 1.25.x. We upgrade to 1.24.x.
Between minor version upgrades, we periodically update to newer patch releases (e.g., 1.23.7 → 1.23.10) to incorporate:
- Security fixes
- Bug fixes
- Performance improvements
These patch updates happen more frequently and are generally lower risk.
When updating the Go version (either patch or minor), the following files must be updated consistently:
go.mod- The Go language version directive. This specifies the Go language version for module compilation.GO_VERSION_MIN- Minimum version enforced by the Makefile.README.md- Documentation and badge (2 locations). This documents requirements for contributors and users.Dockerfile- Docker base image version. This ensures container builds use the correct Go version.
OLD_GO_VERSION="1.24.7"
NEW_GO_VERSION="1.25.0"
# Update go.mod
sed -i "s/go $OLD_GO_VERSION/go $NEW_GO_VERSION/" go.mod
# Update GO_VERSION_MIN
echo "$NEW_GO_VERSION" > GO_VERSION_MIN
# Update README.md badge and documentation
sed -i "s/$OLD_GO_VERSION/$NEW_GO_VERSION/g" README.md
# Update Dockerfile
sed -i "s/FROM golang:$OLD_GO_VERSION-bookworm/FROM golang:$NEW_GO_VERSION-bookworm/" Dockerfile
# Add a changelog entry
# Validate
go mod tidy
make build
make unittests
make lintFor an example of a Go patch version update, see PR #13190, which updated from Go 1.23.7 to 1.23.10. For an example of a Go minor version update, see PR #13354, which updated from Go 1.23.10 to 1.24.7.
.go-versionfiles are gitignored and developer-specific- Developers can create local
.go-versionfiles for their preferred Go version managers - The formal Go version requirements are documented in the tracked files listed above
- Go version updates should be coordinated changes affecting all relevant files
We optimize our markdown files for viewing on GitHub. That isn't to say other syntaxes can't be used, but that is the flavor we focus on and at the minimum don't want to break.
For longer documents, we tend to inline a table of contents (TOC). This is slightly annoying with Markdown on GitHub because the actual table of contents needs to be checked-in rather than just giving a directive to the renderer like [][[_TOC_]] on GitLab](https://docs.gitlab.com/ee/user/markdown.html#table-of-contents). (Yes GitHub UI does enable someone to see an auto-generated outline if they click the "outline" button on the top right-hand corner when viewing a Markdown file, but that isn't necessarily obvious to users, requires an extra click, and doesn't enable any customization.)
There is tooling that can help with auto-generating and updating a TOC and allow customization. Maintainers aren't wedded to a particular format/standard/tool but have gone with VS Code Markdown All in One because it has what we needed and is the most popular VS Code plugin for this functionality (at least as of 202408).
If you need help with your contribution, please don't hesitate to ask questions in our discussions or reach out to the maintainers.
Thank you for contributing to Lotus!