Skip to content

Commit b382231

Browse files
Merge pull request #815 from lightninglabs/docs-lnd
Update lnd documentation
2 parents d8b57d2 + fc5f385 commit b382231

File tree

4 files changed

+724
-344
lines changed

4 files changed

+724
-344
lines changed

docs/lnd/code_contribution_guidelines.md

+15-341
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,8 @@
55
4. [Substantial contributions only](#substantial-contributions-only)
66
5. [Development Practices](#development-practices)
77
1. [Share Early, Share Often](#share-early-share-often)
8-
1. [Testing](#testing)
9-
1. [Code Documentation and Commenting](#code-documentation-and-commenting)
10-
1. [Model Git Commit Messages](#model-git-commit-messages)
11-
1. [Ideal Git Commit Structure](#ideal-git-commit-structure)
12-
1. [Sign Your Git Commits](#sign-your-git-commits)
13-
1. [Code Spacing and formatting](#code-spacing-and-formatting)
14-
1. [Pointing to Remote Dependent Branches in Go Modules](#pointing-to-remote-dependent-branches-in-go-modules)
15-
1. [Use of Log Levels](#use-of-log-levels)
16-
1. [Use of Golang submodules](#use-of-golang-submodules)
17-
6. [Code Approval Process](#code-approval-process)
8+
1. [Development Guidelines](#development-guidelines)
9+
5. [Code Approval Process](#code-approval-process)
1810
1. [Code Review](#code-review)
1911
1. [Rework Code (if needed)](#rework-code-if-needed)
2012
1. [Acceptance](#acceptance)
@@ -146,340 +138,22 @@ This approach has several benefits:
146138
- The quicker your changes are merged to master, the less time you will need to
147139
spend rebasing and otherwise trying to keep up with the main code base
148140

149-
## Testing
150-
151-
One of the major design goals of all of `lnd`'s packages and the daemon itself is
152-
to aim for a high degree of test coverage. This is financial software so bugs
153-
and regressions in the core logic can cost people real money. For this reason
154-
every effort must be taken to ensure the code is as accurate and bug-free as
155-
possible. Thorough testing is a good way to help achieve that goal.
156-
157-
Unless a new feature you submit is completely trivial, it will probably be
158-
rejected unless it is also accompanied by adequate test coverage for both
159-
positive and negative conditions. That is to say, the tests must ensure your
160-
code works correctly when it is fed correct data as well as incorrect data
161-
(error paths).
162-
163-
164-
Go provides an excellent test framework that makes writing test code and
165-
checking coverage statistics straightforward. For more information about the
166-
test coverage tools, see the [golang cover blog post](https://blog.golang.org/cover).
167-
168-
A quick summary of test practices follows:
169-
- All new code should be accompanied by tests that ensure the code behaves
170-
correctly when given expected values, and, perhaps even more importantly, that
171-
it handles errors gracefully
172-
- When you fix a bug, it should be accompanied by tests which exercise the bug
173-
to both prove it has been resolved and to prevent future regressions
174-
- Changes to publicly exported packages such as
175-
[brontide](https://github.com/lightningnetwork/lnd/tree/master/brontide) should
176-
be accompanied by unit tests exercising the new or changed behavior.
177-
- Changes to behavior within the daemon's interaction with the P2P protocol,
178-
or RPC's will need to be accompanied by integration tests which use the
179-
[`networkHarness`framework](https://github.com/lightningnetwork/lnd/blob/master/lntest/harness.go)
180-
contained within `lnd`. For example integration tests, see
181-
[`lnd_test.go`](https://github.com/lightningnetwork/lnd/blob/master/itest/lnd_test.go).
182-
- The itest log files are automatically scanned for `[ERR]` lines. There
183-
shouldn't be any of those in the logs, see [Use of Log Levels](#use-of-log-levels).
184-
185-
Throughout the process of contributing to `lnd`, you'll likely also be
186-
extensively using the commands within our `Makefile`. As a result, we recommend
187-
[perusing the make file documentation](https://github.com/lightningnetwork/lnd/blob/master/docs/MAKEFILE.md).
188-
189-
## Code Documentation and Commenting
190-
191-
- At a minimum every function must be commented with its intended purpose and
192-
any assumptions that it makes
193-
- Function comments must always begin with the name of the function per
194-
[Effective Go](https://golang.org/doc/effective_go.html)
195-
- Function comments should be complete sentences since they allow a wide
196-
variety of automated presentations such as [godoc.org](https://godoc.org)
197-
- The general rule of thumb is to look at it as if you were completely
198-
unfamiliar with the code and ask yourself, would this give me enough
199-
information to understand what this function does and how I'd probably want
200-
to use it?
201-
- Exported functions should also include detailed information the caller of the
202-
function will likely need to know and/or understand:<br /><br />
203-
204-
**WRONG**
205-
```go
206-
// generates a revocation key
207-
func DeriveRevocationPubkey(commitPubKey *btcec.PublicKey,
208-
revokePreimage []byte) *btcec.PublicKey {
209-
```
210-
**RIGHT**
211-
```go
212-
// DeriveRevocationPubkey derives the revocation public key given the
213-
// counterparty's commitment key, and revocation preimage derived via a
214-
// pseudo-random-function. In the event that we (for some reason) broadcast a
215-
// revoked commitment transaction, then if the other party knows the revocation
216-
// preimage, then they'll be able to derive the corresponding private key to
217-
// this private key by exploiting the homomorphism in the elliptic curve group:
218-
// * https://en.wikipedia.org/wiki/Group_homomorphism#Homomorphisms_of_abelian_groups
219-
//
220-
// The derivation is performed as follows:
221-
//
222-
// revokeKey := commitKey + revokePoint
223-
// := G*k + G*h
224-
// := G * (k+h)
225-
//
226-
// Therefore, once we divulge the revocation preimage, the remote peer is able to
227-
// compute the proper private key for the revokeKey by computing:
228-
// revokePriv := commitPriv + revokePreimge mod N
229-
//
230-
// Where N is the order of the sub-group.
231-
func DeriveRevocationPubkey(commitPubKey *btcec.PublicKey,
232-
revokePreimage []byte) *btcec.PublicKey {
233-
```
234-
- Comments in the body of the code are highly encouraged, but they should
235-
explain the intention of the code as opposed to just calling out the
236-
obvious<br /><br />
237-
238-
**WRONG**
239-
```go
240-
// return err if amt is less than 546
241-
if amt < 546 {
242-
return err
243-
}
244-
```
245-
**RIGHT**
246-
```go
247-
// Treat transactions with amounts less than the amount which is considered dust
248-
// as non-standard.
249-
if amt < 546 {
250-
return err
251-
}
252-
```
253-
**NOTE:** The above should really use a constant as opposed to a magic number,
254-
but it was left as a magic number to show how much of a difference a good
255-
comment can make.
256-
257-
## Code Spacing and formatting
258-
259-
Code in general (and Open Source code specifically) is _read_ by developers many
260-
more times during its lifecycle than it is modified. With this fact in mind, the
261-
Golang language was designed for readability (among other goals).
262-
While the enforced formatting of `go fmt` and some best practices already
263-
eliminate many discussions, the resulting code can still look and feel very
264-
differently among different developers.
265-
266-
We aim to enforce a few additional rules to unify the look and feel of all code
267-
in `lnd` to help improve the overall readability.
268-
269-
**Please refer to the [code formatting rules
270-
document](./code_formatting_rules.md)** to see the list of additional style
271-
rules we enforce.
272-
273-
## Model Git Commit Messages
274-
275-
This project prefers to keep a clean commit history with well-formed commit
276-
messages. This section illustrates a model commit message and provides a bit
277-
of background for it. This content was originally created by Tim Pope and made
278-
available on his website, however that website is no longer active, so it is
279-
being provided here.
280-
281-
Here’s a model Git commit message:
282-
283-
```text
284-
Short (50 chars or less) summary of changes
285-
286-
More detailed explanatory text, if necessary. Wrap it to about 72
287-
characters or so. In some contexts, the first line is treated as the
288-
subject of an email and the rest of the text as the body. The blank
289-
line separating the summary from the body is critical (unless you omit
290-
the body entirely); tools like rebase can get confused if you run the
291-
two together.
292-
293-
Write your commit message in the present tense: "Fix bug" and not "Fixed
294-
bug." This convention matches up with commit messages generated by
295-
commands like git merge and git revert.
296-
297-
Further paragraphs come after blank lines.
298-
299-
- Bullet points are okay, too
300-
- Typically a hyphen or asterisk is used for the bullet, preceded by a
301-
single space, with blank lines in between, but conventions vary here
302-
- Use a hanging indent
303-
```
304-
305-
Here are some of the reasons why wrapping your commit messages to 72 columns is
306-
a good thing.
307-
308-
- git log doesn't do any special wrapping of the commit messages. With
309-
the default pager of less -S, this means your paragraphs flow far off the edge
310-
of the screen, making them difficult to read. On an 80 column terminal, if we
311-
subtract 4 columns for the indent on the left and 4 more for symmetry on the
312-
right, we’re left with 72 columns.
313-
- git format-patch --stdout converts a series of commits to a series of emails,
314-
using the messages for the message body. Good email netiquette dictates we
315-
wrap our plain text emails such that there’s room for a few levels of nested
316-
reply indicators without overflow in an 80 column terminal.
317-
318-
In addition to the Git commit message structure adhered to within the daemon
319-
all short-[commit messages are to be prefixed according to the convention
320-
outlined in the Go project](https://golang.org/doc/contribute.html#change). All
321-
commits should begin with the subsystem or package primarily affected by the
322-
change. In the case of a widespread change, the packages are to be delimited by
323-
either a '+' or a ','. This prefix seems minor but can be extremely helpful in
324-
determining the scope of a commit at a glance, or when bug hunting to find a
325-
commit which introduced a bug or regression.
326-
327-
## Ideal Git Commit Structure
328-
329-
Within the project we prefer small, contained commits for a pull request over a
330-
single giant commit that touches several files/packages. Ideal commits build on
331-
their own, in order to facilitate easy usage of tools like `git bisect` to `git
332-
cherry-pick`. It's preferred that commits contain an isolated change in a
333-
single package. In this case, the commit header message should begin with the
334-
prefix of the modified package. For example, if a commit was made to modify the
335-
`lnwallet` package, it should start with `lnwallet: `.
336-
337-
In the case of changes that only build in tandem with changes made in other
338-
packages, it is permitted for a single commit to be made which contains several
339-
prefixes such as: `lnwallet+htlcswitch`. This prefix structure along with the
340-
requirement for atomic contained commits (when possible) make things like
341-
scanning the set of commits and debugging easier. In the case of changes that
342-
touch several packages, and can only compile with the change across several
343-
packages, a `multi: ` prefix should be used.
344-
345-
Examples of common patterns w.r.t commit structures within the project:
346-
347-
* It is common that during the work on a PR, existing bugs are found and
348-
fixed. If they can be fixed in isolation, they should have their own
349-
commit.
350-
* File restructuring like moving a function to another file or changing order
351-
of functions: with a separate commit because it is much easier to review
352-
the real changes that go on top of the restructuring.
353-
* Preparatory refactorings that are functionally equivalent: own commit.
354-
* Project or package wide file renamings should be in their own commit.
355-
* Ideally if a new package/struct/sub-system is added in a PR, there should
356-
be a single commit which adds the new functionality, with follow up
357-
individual commits that begin to integrate the functionality within the
358-
codebase.
359-
* If a PR only fixes a trivial issue, such as updating documentation on a
360-
small scale, fix typos, or any changes that do not modify the code, the
361-
commit message of the HEAD commit of the PR should end with `[skip ci]` to
362-
skip the CI checks. When pushing to such an existing PR, the latest commit
363-
being pushed should end with `[skip ci]` as to not inadvertently trigger the
364-
CI checks.
365-
366-
## Sign your git commits
367-
368-
When contributing to `lnd` it is recommended to sign your git commits. This is
369-
easy to do and will help in assuring the integrity of the tree. See [mailing
370-
list entry](https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2014-May/005877.html)
371-
for more information.
372-
373-
### How to sign your commits?
374-
375-
Provide the `-S` flag (or `--gpg-sign`) to git commit when you commit
376-
your changes, for example
377-
378-
```shell
379-
$ git commit -m "Commit message" -S
380-
```
381-
382-
Optionally you can provide a key id after the `-S` option to sign with a
383-
specific key.
384-
385-
To instruct `git` to auto-sign every commit, add the following lines to your
386-
`~/.gitconfig` file:
387-
388-
```text
389-
[commit]
390-
gpgsign = true
391-
```
392-
393-
### What if I forgot?
394-
395-
You can retroactively sign your previous commit using `--amend`, for example
396-
397-
```shell
398-
$ git commit -S --amend
399-
```
400-
401-
If you need to go further back, you can use the interactive rebase
402-
command with 'edit'. Replace `HEAD~3` with the base commit from which
403-
you want to start.
404-
405-
```shell
406-
$ git rebase -i HEAD~3
407-
```
408-
409-
Replace 'pick' by 'edit' for the commit that you want to sign and the
410-
rebasing will stop after that commit. Then you can amend the commit as
411-
above. Afterwards, do
412-
413-
```shell
414-
$ git rebase --continue
415-
```
416-
417-
As this will rewrite history, you cannot do this when your commit is
418-
already merged. In that case, too bad, better luck next time.
419-
420-
If you rewrite history for another reason - for example when squashing
421-
commits - make sure that you re-sign as the signatures will be lost.
422-
423-
Multiple commits can also be re-signed with `git rebase`. For example, signing
424-
the last three commits can be done with:
425-
426-
```shell
427-
$ git rebase --exec 'git commit --amend --no-edit -n -S' -i HEAD~3
428-
```
429-
430-
### How to check if commits are signed?
431-
432-
Use `git log` with `--show-signature`,
433-
434-
```shell
435-
$ git log --show-signature
436-
```
437-
438-
You can also pass the `--show-signature` option to `git show` to check a single
439-
commit.
440-
441-
## Pointing to Remote Dependent Branches in Go Modules
442-
443-
It's common that a developer may need to make a change in a dependent project
444-
of `lnd` such as `btcd`, `neutrino`, `btcwallet`, etc. In order to test changes
445-
without testing infrastructure, or simply make a PR into `lnd` that will build
446-
without any further work, the `go.mod` and `go.sum` files will need to be
447-
updated. Luckily, the `go mod` command has a handy tool to do this
448-
automatically so developers don't need to manually edit the `go.mod` file:
449-
```shell
450-
$ go mod edit -replace=IMPORT-PATH-IN-LND@LND-VERSION=DEV-FORK-IMPORT-PATH@DEV-FORK-VERSION
451-
```
141+
## Development Guidelines
452142

453-
Here's an example replacing the `lightning-onion` version checked into `lnd` with a version in roasbeef's fork:
454-
```shell
455-
$ go mod edit -replace=github.com/lightningnetwork/lightning-onion@v0.0.0-20180605012408-ac4d9da8f1d6=github.com/roasbeef/lightning-onion@2e5ae87696046298365ab43bcd1cf3a7a1d69695
456-
```
143+
The `lnd` project emphasizes code readability and maintainability through
144+
specific development guidelines. Key aspects include: thorough code
145+
documentation with clear function comments and meaningful inline comments;
146+
consistent code spacing to separate logical blocks; adherence to an 80-character
147+
line limit with specific rules for wrapping function calls, definitions, and log
148+
messages (including structured logging); comprehensive unit and integration
149+
testing for all changes; well-structured Git commit messages with package
150+
prefixes and atomic commits; signing Git commits; proper handling of Go module
151+
dependencies and submodules; and appropriate use of log levels. Developers are
152+
encouraged to configure their editors to align with these standards.
457153

458-
## Use of Log Levels
154+
For the complete set of rules and examples, please refer to the detailed
155+
[Development Guidelines](development_guidelines.md).
459156

460-
There are six log levels available: `trace`, `debug`, `info`, `warn`, `error` and `critical`.
461-
462-
Only use `error` for internal errors that are never expected to happen during
463-
normal operation. No event triggered by external sources (rpc, chain backend,
464-
etc) should lead to an `error` log.
465-
466-
## Use of Golang submodules
467-
468-
Changes to packages that are their own submodules (e.g. they contain a `go.mod`
469-
and `go.sum` file, for example `tor/go.mod`) require a specific process.
470-
We want to avoid the use of local replace directives in the root `go.mod`,
471-
therefore changes to a submodule are a bit involved.
472-
473-
The main process for updating and then using code in a submodule is as follows:
474-
- Create a PR for the changes to the submodule itself (e.g. edit something in
475-
the `tor` package)
476-
- Wait for the PR to be merged and a new tag (for example `tor/v1.0.x`) to be
477-
pushed.
478-
- Create a second PR that bumps the updated submodule in the root `go.mod` and
479-
uses the new functionality in the main module.
480-
481-
Of course the two PRs can be opened at the same time and be built on top of each
482-
other. But the merge and tag push order should always be maintained.
483157

484158
# Code Approval Process
485159

0 commit comments

Comments
 (0)