6.5 KiB
XRPLD Documentation Standards
This document defines the canonical format for inline code documentation in the xrpld codebase. All new and updated code must follow these standards.
Comment Style
Use Javadoc-style Doxygen comments (/** ... */). This matches the dominant
convention in the codebase: ~5,200 existing instances across 569 files.
/** Brief description of the entity. */
For multi-line documentation, each line is prefixed with * (space, asterisk,
space):
/** Brief description of the entity.
*
* Extended description with behavioral details, invariants,
* and constraints that are not obvious from the signature.
*/
JAVADOC_AUTOBRIEF = YES is enabled in the Doxyfile, so the first sentence
of any /** */ block is automatically treated as the brief. An explicit
@brief tag is accepted but not required.
The /// triple-slash style appears in ~37 files (340 instances). It is
valid Doxygen and will not be removed where it exists, but new code should
use /** */ for consistency with the majority style.
What to Document
File-Level (Optional)
The @file tag is not currently used anywhere in the codebase. Adding
file-level documentation is encouraged for complex modules where a
high-level overview helps, but it is not required:
/** @file
* Defines the Payment transactor for the XRP Ledger.
*
* The Payment transactor handles direct XRP transfers, cross-currency
* payments via the pathfinding engine, and partial payments.
*/
Module-level READMEs (e.g., src/xrpld/peerfinder/README.md) remain the
primary place for architectural documentation.
Class / Struct Level
Every class and struct gets a doc block describing:
- What it does (1-2 sentences)
- Key invariants or constraints, if any
- Thread-safety guarantees, if relevant
- Lifecycle notes, if relevant
/** Executes a Payment transaction on the XRP Ledger.
*
* Supports direct XRP payments, cross-currency payments via RippleCalc,
* and partial payments (tfPartialPayment). Path count is limited to 6
* with max path length of 8.
*/
class Payment : public Transactor { ... };
Target: 2-5 lines for most classes. Complex classes may need more.
Public Methods and Free Functions
Every public method and free function in headers gets:
- Brief description of behavior (not a restatement of the signature)
@paramfor each parameter@returndescribing what is returned@throwif it can throw (either@throwor@throwsis acceptable — the codebase uses both)@notefor non-obvious constraints or edge cases
When a @param description wraps, continuation lines are indented with
4 spaces from the *:
/** Round a Number value to the precision of a given asset.
*
* For IOUs, rounds to the IOU's scale. For XRP and MPT, no rounding
* is performed.
*
* @param asset The relevant asset
* @param value The value to be rounded
* @param scale An exponent value to establish the precision limit of
* `value`. Should be larger than `value.exponent()`.
* @return The rounded Number.
*/
[[nodiscard]] Number
roundToAsset(Asset const& asset, Number const& value, int scale);
Target: 1-3 lines of description plus @param/@return.
Private Methods
Document private methods only when the logic is non-obvious. A brief one-line comment is sufficient.
Enums and Constants
All enums get a brief class-level description. Individual enum values get inline documentation when the meaning is not self-evident:
/** Result codes for transaction processing. */
enum TERCode
{
tesSUCCESS = 0, /**< Transaction succeeded. */
tecCLAIM = 100, /**< Fee claimed; transaction failed. */
tecPATH_PARTIAL = 101, /**< Path could not deliver full amount. */
};
What NOT to Document
- Do not paraphrase the function signature.
/** Returns the account ID. */onAccountID getAccountID()adds zero information. - Do not document what is obvious from well-named identifiers.
- Do not reference specific issues, PRs, or task numbers. These belong in commit messages and rot as the codebase evolves.
- Do not add multi-paragraph docstrings. If it takes that long to explain, the code may need restructuring.
- Do not document
.cppimplementation files exhaustively. Focus docs on headers where the public interface is defined.
Quality Over Quantity
Wrong documentation is worse than no documentation. Every doc comment must accurately describe the current behavior. When in doubt:
- Read the implementation before writing the doc
- Cross-reference against test files for edge cases
- Use
@noteto flag subtle behavior that has caught contributors before
Doxygen Tags Reference
Tags in regular use across the codebase:
| Tag | Codebase Usage | Purpose |
|---|---|---|
@brief |
~2,500 instances | Brief description (optional — autobrief is enabled) |
@param |
~2,400 instances | Function parameter description |
@return |
~2,200 instances | Return value description |
@note |
~270 instances | Important behavioral note or caveat |
@throw / @throws |
~450 instances combined | Exception specification |
@see |
~64 instances | Cross-reference to related entities |
@tparam |
~43 instances | Template parameter description |
Tags used rarely but accepted:
| Tag | Codebase Usage | Purpose |
|---|---|---|
@invariant |
~13 instances | Property that must always hold |
@pre |
~3 instances | Precondition |
@file |
0 instances | File-level description (new convention, optional) |
Enforcement
Documentation coverage is measured by coverxygen and enforced in CI:
- PRs cannot decrease documentation coverage (
no_decreaseratchet mode) - New files added in a PR require >= 80% doc coverage
- Module-specific thresholds increase quarterly
- The doc-review GitHub Action checks whether code changes invalidate existing documentation
Coverage is measured against public API surface: classes, structs, functions, enums, typedefs, and variables. Private implementation details are not counted.
Style Notes
- Doc comments go immediately before the entity they describe (no blank line between the comment and the declaration)
- Keep
@paramdescriptions on a single line when possible - For wrapped
@paramdescriptions, indent continuation lines 4 spaces from the* - Use
@seesparingly — only when the relationship is non-obvious - Code style (braces, line width, formatting) is governed by
.clang-formatand is independent of these documentation standards