|
5 | 5 | 4. [Substantial contributions only](#substantial-contributions-only)
|
6 | 6 | 5. [Development Practices](#development-practices)
|
7 | 7 | 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) |
18 | 10 | 1. [Code Review](#code-review)
|
19 | 11 | 1. [Rework Code (if needed)](#rework-code-if-needed)
|
20 | 12 | 1. [Acceptance](#acceptance)
|
@@ -146,340 +138,22 @@ This approach has several benefits:
|
146 | 138 | - The quicker your changes are merged to master, the less time you will need to
|
147 | 139 | spend rebasing and otherwise trying to keep up with the main code base
|
148 | 140 |
|
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 |
452 | 142 |
|
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. |
457 | 153 |
|
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). |
459 | 156 |
|
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. |
483 | 157 |
|
484 | 158 | # Code Approval Process
|
485 | 159 |
|
|
0 commit comments