First Time Contributors
Consequential changes are determined case-by-case. As a guideline:- Spelling and grammar fixes are typically not consequential unless they materially correct the message
- Bug fixes, feature additions, and performance improvements are consequential
- Refactoring and code quality improvements are consequential
Pull Request Process
PR Size Guidelines
Small, frequent PRs are strongly preferred over large, infrequent ones. Large PRs:- Are difficult to review
- Block others from making progress
- Lead to “rebase hell”
Breaking Down Large Changes
When one change requires another, use cherry-picking to create separate PRs:Pre-Submission Checks
Before pushing code, always run:Code Requirements
Testing Requirements
- 90% coverage minimum: All changes should have unit and integration tests covering at least 90% of added code paths
- Fast and reliable: Tests should run quickly and not be flaky
- Comprehensive: Include stress tests for performance-critical code
Performance Requirements
- Benchmark results: All performance-related changes must include benchmark evidence
- Profile data: Include validator timings or profiles for mainnet/testnet
- Justification: Added complexity must be justified by commensurate performance improvement
Code Quality Requirements
- Consensus changes: Must be behind a feature gate with a merged SIMD
- Subject matter review: Changes should be reviewed by domain experts
- Master-first: All changes merge to master first; only critical changes backport to release branches
- No duplication: Avoid duplicate code where possible
- No abbreviations: Spell out variable names unless used as closure arguments
- Changelog entries: Add entries for features that should be in release notes
- Separate concerns: Don’t mix refactoring and logical changes
Draft Pull Requests
PR Description Structure
The PR Title
Write titles from the user’s perspective: Good examples:- Add rent to accounts
- Fix out-of-memory error in validator
- Clean up
process_message()in runtime
- First word capitalized and in imperative mood (“add”, not “added”)
- No trailing period
- State what was done, to what, and in what context
Problem Statement
Describe how the product is missing a feature, how a feature is incomplete, or how an implementation is undesirable.Reviewer time is scarce. Don’t make reviewers click through links - copy relevant problem descriptions directly into your PR.
Proposed Changes
List the steps taken to solve the problem, typically as bullet points:- Each major change or addition
- High-level approach
- Key decisions made
Code Changes
The actual diff should implement what was proposed. Reviewers look for:- Implementation matches the proposal
- Code is maintainable
- Tests cover all new code paths
Getting PRs Merged
Timeline Expectations
PRs are typically reviewed and merged within 7 days. If your PR has been open longer, reviewers may lack confidence in the change quality. Consider:- Closing and returning with smaller PRs
- Adding more detailed problem/solution descriptions
- Ensuring tests cover all new code
Finding Reviewers
There’s no single person watching the PR queue. To find reviewers:- Use
git blameto find component authors - Ask on Discord
- Include a detailed problem description to engage interested parties
- Remember: changing code is your priority, not necessarily theirs
Managing Review Feedback
When reviewers provide feedback:Making PRs Easy to Approve
Things that make review harder:- Orthogonal changes unrelated to the problem
- Unnecessary renaming
- Not following established conventions
- Whitespace changes
- Force-pushing unnecessarily
- Not responding to review comments
- Tests for all new/changed behavior
- Documentation of manual testing performed
- Performance results for optimization PRs
- Focused changes addressing one problem
Rust Coding Conventions
Formatting
All Rust code usesrustfmt:
Clippy
Don’t change Clippy config without good reason. To ignore Clippy advice explicitly:Naming Conventions
Variables:- Spell out names (don’t abbreviate unless in closures)
- Lowercase type names with underscores:
let hash_map = HashMap::new(); - Add prefixes for multiple instances:
alice_keypair,bob_keypair - Or use numeric suffixes:
tx0,tx1 - Keep names consistent across functions
- Use
<verb>_<subject>pattern - Unit tests:
test_<description> - Benchmarks:
bench_<description> - Don’t abbreviate words
- Don’t namespace unnecessarily
Error Handling
- Only use
unwrap()where you can prove it never panics - Prefer
.expect("reason")when panic is desirable - Document why unwrap is safe in complex cases
Test-Only Code
Mark test utilities appropriately:Design Proposals
For architectural changes, submit a design proposal following the proposal process. View existing proposals:Labels
Common PR/issue labels:- automerge: Automatically merge when CI passes (small hot-fixes only, less than 100 lines)
- good first issue: Non-urgent, self-contained issues suitable for newcomers
Next Steps
- Review testing guidelines for test requirements
- Understand the release process
- Build from source following the build guide