--- id: contributing title: Contributing --- Bitcoin-S is an open source project where anyone is welcome to contribute. All contributions are encouraged and appreciated, whether that is code, testing, documentation or something else entirely. ## Communication Channels It's possible to communicate with other developers through a variety of communication channels: - [Suredbits Slack](https://join.slack.com/t/suredbits/shared_invite/zt-eavycu0x-WQL7XOakzQo8tAy7jHHZUw) - Suredbits is a company monetizing APIs through the Lightning Network. Suredbits doesn't own Bitcoin-S, but the Suredbits CEO Chris Stewart is the maintainer of this library. There's a separate Bitcoin-S channel on their Slack, this is probably the easiest way of getting in touch with someone working on this project. - [Bitcoin-S Gitter](https://gitter.im/bitcoin-s-core/) - [#bitcoin-scala](https://webchat.freenode.net/?channels=bitcoin-scala) on IRC Freenode ## Working on Bitcoin-S applications Bitcoin-S includes a couple of applications that can be run as standalone executables. This includes the node, wallet and (partial) blockchain verification modules, as well as the server that bundles these three together and the CLI used to communicate with the server. These applications are configured with HOCON files. The file [`reference.conf`](https://github.com/bitcoin-s/bitcoin-s/blob/master/testkit/src/main/resources/reference.conf) is the basis configuration file, and every option read by Bitcoin-S should be present in this file. This means that you can copy sections from this file and edit them, to tune how the application runs on your machine. One example of things you can tune is logging levels. Let's say you wanted the logback config ignored, general logging to happen at the `WARN` level, and the P2P message handling to be logged at `DEBUG`. Your configuration file would then look like: ```conf bitcoins-s { logging { logback = false level = warn p2p = debug } } ``` ### Running the applications When running the application's configuration placed in `bitcoin-s.conf` in the current data directory gets picked up. For linux this is by default `$HOME/.bitcoin-s/`, so the file you should edit would be `$HOME/.bitcoin-s/bitcoin-s.conf`. ### Running tests for the applications You can place a `logback-test.xml` file in the `src/test/resources/` directory in the same project that tests are being run in. If the test suite depends on `testkit`, you can modify [`reference.conf`](https://github.com/bitcoin-s/bitcoin-s/blob/master/testkit/src/main/resources/reference.conf) that is built into the testkit to control logging. ## Logging when working on Bitcoin-S tests When working on various parts of Bitcoin-S the need to log what's going on arises pretty quickly. There are two ways of doing this: 1. Using the way described in the section above, "Working on Bitcoin-S applications". You could either use traits (like `HTTPLogger` or `P2PLogger`) that exposes a field `logger`, or acquire the logger directly through the trait's companion object. 2. Use the standard `BitcoinSLogger`, which is also available as both a trait and a companion object with a field you can access (`BitcoinSLogger.logger`). Note that by default all logging from this logger is turned off in tests, to make output less noisy. You can tune this by changing the level found in `core-test/src/test/resources/logback-test.xml`. ### Akka logging The test logging for akka is controlled by the [`reference.conf`](https://github.com/bitcoin-s/bitcoin-s/blob/master/testkit/src/main/resources/reference.conf) file inside of testkit. This allows you to debug what is happening in our actors inside of bitcoin-s easier. For examples of what you can enable for akka to log, please look at their [logging documentation](https://doc.akka.io/docs/akka/current/logging.html#auxiliary-logging-options) The easiest thing to do to enable akka logging is to adjust the `loglevel` and `stdout-loglevel` from `OFF` to `DEBUG`. If you want to enable this when you are running a bitcoin-s application, you will need to modify the [`reference.conf`](../app/server/src/main/resources/reference.conf) file ## Developer productivity ### sbt The default scala build tool is [sbt](https://www.scala-sbt.org/). For the basics of how sbt works see the [sbt guide](https://www.scala-sbt.org/1.x/docs/Getting-Started.html) One helpful configuration is the env variable `SBT_OPTS` which allows you to pass jvm arguments for sbt. ### Bloop If you're tired of waiting around for sbt all day, there's a new, cool kid on the block. It is called [Bloop](https://scalacenter.github.io/bloop/), and it makes compilations in general faster, and in particular incremental, small compilation units (which greatly help editor performance). Bloop is a server that runs in the background of your computer, and keeps several "hot" JVMs running at all times. These JVMs serve compilation requests. Because the JVMs are running in the background you avoid the startup lag, and you also get code that's already [JIT compiled](https://en.wikipedia.org/wiki/Just-in-time_compilation) for you. The documentation on Bloops [site](https://scalacenter.github.io/bloop/) is good, but here is the highlights: 1. Install Bloop by doing step 1 & 2 in the [official guide](https://scalacenter.github.io/bloop/setup#universal) 2. Enable the Bloop background daemon 1. macOS: ```bash $ brew services start bloop ``` 2. Ubuntu: ```bash $ systemctl --user enable $HOME/.bloop/systemd/bloop.service $ systemctl --user daemon-reload $ systemctl --user start bloop ``` 3. Enable shell completion for the Bloop CLI 1. Bash: ```bash $ echo '. $HOME/.bloop/bash/bloop' >> $HOME/.bash_profile ``` 2. Zsh: ```bash $ echo 'autoload -U compinit' >> $HOME/.zshrc $ echo 'fpath=($HOME/.bloop/zsh $fpath)' >> $HOME/.bashrc $ echo 'compinit' >> $HOME/.bashrc ``` 3. Fish: ```bash $ ln -s $HOME/.bloop/fish/bloop.fish ~/.config/fish/completions/bloop.fish ``` 4. Generate configuration files ```bash $ sbt bloopInstall ``` 5. Import Bitcoin-S into IntelliJ again, as a bsp (Build Server Protocol) project (instead of a sbt project). Make sure you're running on the most recent IntelliJ and Scala plugin. See [official docs](https://scalacenter.github.io/bloop/docs/ides/intellij) for details. 6. _(Bonus step):_ Lightning fast recompilations on file save: ```bash $ bloop compile --project --watch ``` Your editor should now be much faster and require less resources :tada: ## Testing ### Property based testing This library aims to achieve high level of correctness via property based testing. At the simplest level, you can think of property based testing as specifying a invariant that must always hold true. [Here](https://github.com/bitcoin-s/bitcoin-s-core/blob/89fbf35d78046b7ed21fd93fec05bb57cba023bb/src/test/scala/org/bitcoins/core/protocol/transaction/TransactionSpec.scala#L13-L17) is an example of a property in the bitcoin-s-core test suite ```scala property("Serialization symmetry") = Prop.forAll(TransactionGenerators.transactions) { tx => Transaction(tx.hex) == tx } ``` What this property says is that for every transaction we can generate with [`TransactionGenerators.transactions`](/api/org/bitcoins/testkit/core/gen/TransactionGenerators$) we _must_ be able to serialize it to hex format, then deserialize it back to a transaction and get the original `tx` back. A more complex example of property based testing is checking that a multisignature transaction was signed correctly (see [`TransactionSignatureCreatorSpec`](https://github.com/bitcoin-s/bitcoin-s/blob/master/core-test/src/test/scala/org/bitcoins/core/crypto/TransactionSignatureCreatorSpec.scala) line 29-34). First we generate a _supposedly_ validly signed multisig transaction with [`TransactionGenerators.signedMultiSigTransaction`](/api/org/bitcoins/testkit/core/gen/TransactionGenerators$) (line 102-108). These transactions have varying `m` of `n` requirements. An interesting corner case if when you have 0 of `n` signatures, which means no signature is required. Property based testing is really good at fleshing out these corner cases. We check to see if this transaction is valid by running it through our [`ScriptInterpreter`](/api/org/bitcoins/core/script/interpreter/ScriptInterpreter). If we have built our functionality correctly the `ScriptInterpreter` should always return [`ScriptOk`](/api/org/bitcoins/core/script/result/ScriptResult) indicating the script was valid. ```scala property("generate valid signatures for a multisignature transaction") = Prop.forAllNoShrink(TransactionGenerators.signedMultiSigTransaction) { case (txSignatureComponent: TxSigComponent, _) => //run it through the interpreter val program = ScriptProgram(txSignatureComponent) val result = ScriptInterpreter.run(program) result == ScriptOk } ``` ### Running tests To run the entire test suite all you need to do is run the following command: > This takes a long time, and runs a lot of tests that require IO. It may hog your computer at times. ```scala $ sbt test [info] Elapsed time: 4 min 36.760 sec [info] ScalaCheck [info] Passed: Total 149, Failed 0, Errors 0, Passed 149 [info] ScalaTest [info] Run completed in 4 minutes, 55 seconds. [info] Total number of tests run: 744 [info] Suites: completed 97, aborted 0 [info] Tests: succeeded 744, failed 0, canceled 0, ignored 0, pending 0 [info] All tests passed. [info] Passed: Total 909, Failed 0, Errors 0, Passed 909 [success] Total time: 297 s, completed Jul 20, 2017 10:34:16 AM ``` To run a specific suite of tests you can specify the suite name in the following way ```scala $ sbt testOnly *ScriptInterpreterTest* [info] ScriptInterpreterTest: [info] ScriptInterpreter [info] - must evaluate all the scripts from the bitcoin core script_tests.json [info] Run completed in 8 seconds, 208 milliseconds. [info] Total number of tests run: 1 [info] Suites: completed 1, aborted 0 [info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0 [info] All tests passed. ``` The command `sbt testQuick` can also be handy. It runs tests that either: 1. Failed previously 2. Has not been run previously 3. Either the test or one of its dependencies has been recompiled For more information on `testQuick`, see the offical [sbt docs](https://www.scala-sbt.org/1.x/docs/Testing.html#testQuick). ### Coverage To produce a report that quantifies how much of our code is covered by tests: ```bash sbt > coverage > coreTest/test > core/coverageReport ``` This generates three different reports: Cobertura, XML and HTML formats. See the output of your sbt shell to find the location of them. Open up the HTML file in your browser. You'll now see code coverage of all files in `core` project. ### CI Bitcoin-S uses Github Actions to run tests and deploy library and website builds. Generally speaking CI has to pass for a PR to get merged. If you make documentation/website only changes, you can add the `documentation` label to your PR. This skips running tests on CI.