bitcoin-s/docs/0.2.0/contributing/index.html
Docusaurus bot 03c8735955 Deploy website
Deploy website version based on 34e9be1299
2020-07-01 22:18:52 +00:00

287 lines
No EOL
36 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Contributing · bitcoin-s</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta name="description" content="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."/><meta name="docsearch:version" content="0.2.0"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Contributing · bitcoin-s"/><meta property="og:type" content="website"/><meta property="og:url" content="https://bitcoin-s.org/"/><meta property="og:description" content="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."/><meta property="og:image" content="https://bitcoin-s.org/img/undraw_online.svg"/><meta name="twitter:card" content="summary"/><meta name="twitter:image" content="https://bitcoin-s.org/img/undraw_tweetstorm.svg"/><link rel="shortcut icon" href="/img/favicon.ico"/><link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css"/><script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-61958686-2', 'auto');
ga('send', 'pageview');
</script><link rel="stylesheet" href="/css/code-block-buttons.css"/><script type="text/javascript" src="https://buttons.github.io/buttons.js"></script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.0/clipboard.min.js"></script><script type="text/javascript" src="https://fonts.googleapis.com/css?family=Montserrat:500"></script><script type="text/javascript" src="https://www.googletagmanager.com/gtag/js?id=UA-61958686-2"></script><script type="text/javascript" src="/js/code-block-buttons.js"></script><script src="/js/scrollSpy.js"></script><link rel="stylesheet" href="/css/main.css"/><script src="/js/codetabs.js"></script></head><body class="sideNavVisible separateOnPageNav"><div class="fixedHeaderContainer"><div class="headerWrapper wrapper"><header><a href="/"><img class="logo" src="/img/favicon.ico" alt="bitcoin-s"/><h2 class="headerTitleWithLogo">bitcoin-s</h2></a><a href="/versions"><h3>0.2.0</h3></a><div class="navigationWrapper navigationSlider"><nav class="slidingNav"><ul class="nav-site nav-site-internal"><li class="siteNavGroupActive"><a href="/docs/0.2.0/core/core-intro" target="_self">Docs</a></li><li class=""><a href="/api/org/bitcoins" target="_self">API</a></li><li class=""><a href="/help" target="_self">Help</a></li><li class="navSearchWrapper reactNavSearchWrapper"><input type="text" id="search_input_react" placeholder="Search" title="Search"/></li></ul></nav></div></header></div></div><div class="navPusher"><div class="docMainWrapper wrapper"><div class="docsNavContainer" id="docsNav"><nav class="toc"><div class="toggleNav"><section class="navWrapper wrapper"><div class="navBreadcrumb wrapper"><div class="navToggle" id="navToggler"><div class="hamburger-menu"><div class="line1"></div><div class="line2"></div><div class="line3"></div></div></div><h2><i></i><span>Contributing</span></h2><div class="tocToggler" id="tocToggler"><i class="icon-toc"></i></div></div><div class="navGroups"><div class="navGroup"><h3 class="navGroupCategoryTitle">Getting started</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/0.2.0/getting-started">Add Bitcoin-S to your project</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Core module</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/0.2.0/core/core-intro">Core module</a></li><li class="navListItem"><a class="navItem" href="/docs/0.2.0/core/addresses">Generating addresses</a></li><li class="navListItem"><a class="navItem" href="/docs/0.2.0/core/hd-keys">HD key generation</a></li><li class="navListItem"><a class="navItem" href="/docs/0.2.0/core/txbuilder">TxBuilder example</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">RPC clients</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/0.2.0/rpc/rpc-clients-intro">Introduction</a></li><li class="navListItem"><a class="navItem" href="/docs/0.2.0/rpc/rpc-eclair">Eclair</a></li><li class="navListItem"><a class="navItem" href="/docs/0.2.0/rpc/rpc-bitcoind">bitcoind/Bitcoin Core</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Applications</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/0.2.0/applications/chain">Blockchain Verification</a></li><li class="navListItem"><a class="navItem" href="/docs/0.2.0/applications/cli">bitcoin-s cli</a></li><li class="navListItem"><a class="navItem" href="/docs/0.2.0/applications/configuration">Application configuration</a></li><li class="navListItem"><a class="navItem" href="/docs/0.2.0/applications/key-manager">Key Manager</a></li><li class="navListItem"><a class="navItem" href="/docs/0.2.0/applications/node">Light client</a></li><li class="navListItem"><a class="navItem" href="/docs/0.2.0/applications/wallet">Wallet</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Contributing</h3><ul class=""><li class="navListItem navListItemActive"><a class="navItem" href="/docs/0.2.0/contributing">Contributing</a></li><li class="navListItem"><a class="navItem" href="/docs/0.2.0/contributing-website">Contributing to the website</a></li></ul></div><div class="navGroup"><h3 class="navGroupCategoryTitle">Security</h3><ul class=""><li class="navListItem"><a class="navItem" href="/docs/0.2.0/security">Security</a></li></ul></div></div></section></div><script>
var coll = document.getElementsByClassName('collapsible');
var checkActiveCategory = true;
for (var i = 0; i < coll.length; i++) {
var links = coll[i].nextElementSibling.getElementsByTagName('*');
if (checkActiveCategory){
for (var j = 0; j < links.length; j++) {
if (links[j].classList.contains('navListItemActive')){
coll[i].nextElementSibling.classList.toggle('hide');
coll[i].childNodes[1].classList.toggle('rotate');
checkActiveCategory = false;
break;
}
}
}
coll[i].addEventListener('click', function() {
var arrow = this.childNodes[1];
arrow.classList.toggle('rotate');
var content = this.nextElementSibling;
content.classList.toggle('hide');
});
}
document.addEventListener('DOMContentLoaded', function() {
createToggler('#navToggler', '#docsNav', 'docsSliderActive');
createToggler('#tocToggler', 'body', 'tocActive');
var headings = document.querySelector('.toc-headings');
headings && headings.addEventListener('click', function(event) {
var el = event.target;
while(el !== headings){
if (el.tagName === 'A') {
document.body.classList.remove('tocActive');
break;
} else{
el = el.parentNode;
}
}
}, false);
function createToggler(togglerSelector, targetSelector, className) {
var toggler = document.querySelector(togglerSelector);
var target = document.querySelector(targetSelector);
if (!toggler) {
return;
}
toggler.onclick = function(event) {
event.preventDefault();
target.classList.toggle(className);
};
}
});
</script></nav></div><div class="container mainContainer docsContainer"><div class="wrapper"><div class="post"><header class="postHeader"><a class="edit-page-link button" href="https://github.com/bitcoin-s/bitcoin-s/blob/master/docs/contributing.md" target="_blank" rel="noreferrer noopener">Edit</a><h1 id="__docusaurus" class="postHeaderTitle">Contributing</h1></header><article><div><span><p>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.</p>
<h2><a class="anchor" aria-hidden="true" id="communication-channels"></a><a href="#communication-channels" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Communication Channels</h2>
<p>It's possible to communicate with other developers through a variety of communication channels:</p>
<ul>
<li><a href="https://join.slack.com/t/suredbits/shared_invite/enQtNDEyMjY3MTg1MTg3LTYyYjkwOGUzMDQ4NDAwZjE1M2I3MmQyNWNlZjNlYjg4OGRjYTRjNWUwNjRjNjg4Y2NjZjAxYjU1N2JjMTU1YWM">Suredbits Slack</a> - 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.</li>
<li><a href="https://gitter.im/bitcoin-s-core/">Bitcoin-S Gitter</a></li>
<li><a href="https://webchat.freenode.net/?channels=bitcoin-scala">#bitcoin-scala</a> on IRC Freenode</li>
</ul>
<h2><a class="anchor" aria-hidden="true" id="working-on-bitcoin-s-applications"></a><a href="#working-on-bitcoin-s-applications" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Working on Bitcoin-S applications</h2>
<p>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
<a href="../testkit/src/main/resources/reference.conf"><code>reference.conf</code></a>
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.</p>
<p>One example of things you can tune is logging levels. Lets say you wanted general logging
to happen at the <code>WARN</code> level, but the P2P message handling to be logged at <code>DEBUG</code>. Your
configuration file would then look like:</p>
<pre><code class="hljs css language-conf">bitcoins-s {
<span class="hljs-built_in"> logging </span>{
level = warn
p2p = <span class="hljs-builtin-name">debug</span>
}
}
</code></pre>
<h3><a class="anchor" aria-hidden="true" id="running-the-applications"></a><a href="#running-the-applications" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Running the applications</h3>
<p>When running the applications configuration placed in <code>bitcoin-s.conf</code> in the current
data directory gets picked up. For linux this is by default <code>$HOME/.bitcoin-s/</code>, so the
file you should edit would be <code>$HOME/.bitcoin-s/bitcoin-s.conf</code>.</p>
<h3><a class="anchor" aria-hidden="true" id="running-tests-for-the-applications"></a><a href="#running-tests-for-the-applications" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Running tests for the applications</h3>
<p>You can place a <code>logback-test.xml</code> file in the <code>src/test/resources/</code> directory in the same project that tests are being run in.</p>
<p>If the test suite depends on <code>testkit</code>, you can modify <a href="../testkit/src/main/resources/reference.conf"><code>reference.conf</code></a>
that is built into the testkit to control logging.</p>
<h2><a class="anchor" aria-hidden="true" id="logging-when-working-on-bitcoin-s-tests"></a><a href="#logging-when-working-on-bitcoin-s-tests" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Logging when working on Bitcoin-S tests</h2>
<p>When working on various parts of Bitcoin-S the need to log what's going on arises
pretty quickly. There's two way of doing this:</p>
<ol>
<li>Using the way described in the section above, &quot;Working on Bitcoin-S applications&quot;.
You could either use traits (like <code>HTTPLogger</code> or <code>P2PLogger</code>) that exposes a
field <code>logger</code>, or acquire the logger directly through the traits companion
object.</li>
<li>Use the standard <code>BitcoinSLogger</code>, which is also available as both a trait and
a companion object with a field you can access (<code>BitcoinSLogger.logger</code>). 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
<code>core-test/src/test/resources/logback-test.xml</code>.</li>
</ol>
<h3><a class="anchor" aria-hidden="true" id="akka-logging"></a><a href="#akka-logging" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Akka logging</h3>
<p>The test logging for akka is controlled by the <a href="../testkit/src/main/resources/reference.conf"><code>reference.conf</code></a> file inside of testkit.</p>
<p>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 <a href="https://doc.akka.io/docs/akka/current/logging.html#auxiliary-logging-options">logging documentation</a></p>
<p>The easiest thing to do to enable akka logging is to adjust the <code>loglevel</code> and <code>stdout-loglevel</code> from <code>OFF</code> to <code>DEBUG</code>.</p>
<p>If you want to enable this when you are running a bitcoin-s application, you will need to modify the <a href="../app/server/src/main/resources/reference.conf"><code>reference.conf</code></a> file</p>
<h2><a class="anchor" aria-hidden="true" id="developer-productivity"></a><a href="#developer-productivity" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Developer productivity</h2>
<h3><a class="anchor" aria-hidden="true" id="sbt"></a><a href="#sbt" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>sbt</h3>
<p>The default scala build tool is <a href="https://www.scala-sbt.org/">sbt</a>.</p>
<p>For the basics of how sbt works see the <a href="https://www.scala-sbt.org/1.x/docs/Getting-Started.html">sbt guide</a></p>
<p>One helpful configuration is the env variable <code>SBT_OPTS</code> which allows you to pass jvm arguments for sbt.</p>
<h3><a class="anchor" aria-hidden="true" id="bloop"></a><a href="#bloop" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Bloop</h3>
<p>If you're tired of waiting around for sbt all day, there's a new,
cool kid on the block. It is called <a href="https://scalacenter.github.io/bloop/">Bloop</a>,
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 &quot;hot&quot; 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 <a href="https://en.wikipedia.org/wiki/Just-in-time_compilation">JIT compiled</a>
for you.</p>
<p>The documentation on Bloops <a href="https://scalacenter.github.io/bloop/">site</a> is good, but here is the highlights:</p>
<ol>
<li>Install Bloop by doing step 1 &amp; 2 in the <a href="https://scalacenter.github.io/bloop/setup#universal">official guide</a></li>
<li>Enable the Bloop background daemon
<ol>
<li>macOS:</li>
</ol>
<pre><code class="hljs css language-bash">$ brew services start bloop
</code></pre>
<ol start="2">
<li>Ubuntu:</li>
</ol>
<pre><code class="hljs css language-bash">$ systemctl --user <span class="hljs-built_in">enable</span> <span class="hljs-variable">$HOME</span>/.bloop/systemd/bloop.service
$ systemctl --user daemon-reload
$ systemctl --user start bloop
</code></pre></li>
<li>Enable shell completion for the Bloop CLI
<ol>
<li>Bash:</li>
</ol>
<pre><code class="hljs css language-bash">$ <span class="hljs-built_in">echo</span> <span class="hljs-string">'. $HOME/.bloop/bash/bloop'</span> &gt;&gt; <span class="hljs-variable">$HOME</span>/.bash_profile
</code></pre>
<ol start="2">
<li>Zsh:</li>
</ol>
<pre><code class="hljs css language-bash">$ <span class="hljs-built_in">echo</span> <span class="hljs-string">'autoload -U compinit'</span> &gt;&gt; <span class="hljs-variable">$HOME</span>/.zshrc
$ <span class="hljs-built_in">echo</span> <span class="hljs-string">'fpath=($HOME/.bloop/zsh $fpath)'</span> &gt;&gt; <span class="hljs-variable">$HOME</span>/.bashrc
$ <span class="hljs-built_in">echo</span> <span class="hljs-string">'compinit'</span> &gt;&gt; <span class="hljs-variable">$HOME</span>/.bashrc
</code></pre>
<ol start="3">
<li>Fish:</li>
</ol>
<pre><code class="hljs css language-bash">$ ln -s <span class="hljs-variable">$HOME</span>/.bloop/fish/bloop.fish ~/.config/fish/completions/bloop.fish
</code></pre></li>
<li>Generate configuration files
<pre><code class="hljs css language-bash">$ sbt bloopInstall
</code></pre></li>
<li>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 <a href="https://scalacenter.github.io/bloop/docs/ides/intellij">official docs</a> for details.</li>
<li><em>(Bonus step):</em> Lightning fast recompilations on file save:
<pre><code class="hljs css language-bash">$ bloop compile --project &lt;name of module your<span class="hljs-string">'re working on&gt; --watch
</span></code></pre></li>
</ol>
<p>Your editor should now be much faster and require less resources :tada:</p>
<h2><a class="anchor" aria-hidden="true" id="testing"></a><a href="#testing" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Testing</h2>
<h3><a class="anchor" aria-hidden="true" id="property-based-testing"></a><a href="#property-based-testing" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Property based testing</h3>
<p>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.
<a href="https://github.com/bitcoin-s/bitcoin-s-core/blob/89fbf35d78046b7ed21fd93fec05bb57cba023bb/src/test/scala/org/bitcoins/core/protocol/transaction/TransactionSpec.scala#L13-L17">Here</a>
is an example of a property in the bitcoin-s-core test suite</p>
<pre><code class="hljs css language-scala"> property(<span class="hljs-string">"Serialization symmetry"</span>) =
<span class="hljs-type">Prop</span>.forAll(<span class="hljs-type">TransactionGenerators</span>.transactions) { tx =&gt;
<span class="hljs-type">Transaction</span>(tx.hex) == tx
}
</code></pre>
<p>What this property says is that for every transaction we can generate with
<a href="/api/org/bitcoins/core/gen/TransactionGenerators"><code>TransactionGenerators.transactions</code></a>
we <em>must</em> be able to serialize it to hex format, then deserialize it back
to a transaction and get the original <code>tx</code> back.</p>
<p>A more complex example of property based testing is checking that a
multisignature transaction was signed correctly (see
<a href="core-test/src/test/scala/org/bitcoins/core/crypto/TransactionSignatureCreatorSpec.scala"><code>TransactionSignatureCreatorSpec</code></a>
line 29-34). First we generate a <em>supposedly</em> validly signed multisig
transaction with <a href="/api/org/bitcoins/testkit/core/gen/TransactionGenerators"><code>TransactionGenerators.signedMultiSigTransaction</code></a>
(line 102-108). These transactions have varying <code>m</code> of <code>n</code> requirements.
An interesting corner case if when you have 0 of <code>n</code> 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 <a href="/api/org/bitcoins/core/script/interpreter/ScriptInterpreter"><code>ScriptInterpreter</code></a>.
If we have built our functionality correctly the <code>ScriptInterpreter</code> should
always return <a href="/api/org/bitcoins/core/script/result/ScriptResult"><code>ScriptOk</code></a>
indicating the script was valid.</p>
<pre><code class="hljs css language-scala"> property(<span class="hljs-string">"generate valid signatures for a multisignature transaction"</span>) =
<span class="hljs-type">Prop</span>.forAllNoShrink(<span class="hljs-type">TransactionGenerators</span>.signedMultiSigTransaction) {
<span class="hljs-keyword">case</span> (txSignatureComponent: <span class="hljs-type">TxSigComponent</span>, _) =&gt;
<span class="hljs-comment">//run it through the interpreter</span>
<span class="hljs-keyword">val</span> program = <span class="hljs-type">ScriptProgram</span>(txSignatureComponent)
<span class="hljs-keyword">val</span> result = <span class="hljs-type">ScriptInterpreter</span>.run(program)
result == <span class="hljs-type">ScriptOk</span>
}
</code></pre>
<h3><a class="anchor" aria-hidden="true" id="running-tests"></a><a href="#running-tests" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Running tests</h3>
<p>To run the entire test suite all you need to do is run the following command:</p>
<blockquote>
<p>This takes a long time, and runs a lot of tests that require IO. It may hog your computer at times.</p>
</blockquote>
<pre><code class="hljs css language-scala">$ sbt test
[info] <span class="hljs-type">Elapsed</span> time: <span class="hljs-number">4</span> min <span class="hljs-number">36.760</span> sec
[info] <span class="hljs-type">ScalaCheck</span>
[info] <span class="hljs-type">Passed</span>: <span class="hljs-type">Total</span> <span class="hljs-number">149</span>, <span class="hljs-type">Failed</span> <span class="hljs-number">0</span>, <span class="hljs-type">Errors</span> <span class="hljs-number">0</span>, <span class="hljs-type">Passed</span> <span class="hljs-number">149</span>
[info] <span class="hljs-type">ScalaTest</span>
[info] <span class="hljs-type">Run</span> completed in <span class="hljs-number">4</span> minutes, <span class="hljs-number">55</span> seconds.
[info] <span class="hljs-type">Total</span> number of tests run: <span class="hljs-number">744</span>
[info] <span class="hljs-type">Suites</span>: completed <span class="hljs-number">97</span>, aborted <span class="hljs-number">0</span>
[info] <span class="hljs-type">Tests</span>: succeeded <span class="hljs-number">744</span>, failed <span class="hljs-number">0</span>, canceled <span class="hljs-number">0</span>, ignored <span class="hljs-number">0</span>, pending <span class="hljs-number">0</span>
[info] <span class="hljs-type">All</span> tests passed.
[info] <span class="hljs-type">Passed</span>: <span class="hljs-type">Total</span> <span class="hljs-number">909</span>, <span class="hljs-type">Failed</span> <span class="hljs-number">0</span>, <span class="hljs-type">Errors</span> <span class="hljs-number">0</span>, <span class="hljs-type">Passed</span> <span class="hljs-number">909</span>
[success] <span class="hljs-type">Total</span> time: <span class="hljs-number">297</span> s, completed <span class="hljs-type">Jul</span> <span class="hljs-number">20</span>, <span class="hljs-number">2017</span> <span class="hljs-number">10</span>:<span class="hljs-number">34</span>:<span class="hljs-number">16</span> <span class="hljs-type">AM</span>
</code></pre>
<p>To run a specific suite of tests you can specify the suite name in the following way</p>
<pre><code class="hljs css language-scala">$ sbt testOnly *<span class="hljs-type">ScriptInterpreterTest</span>*
[info] <span class="hljs-type">ScriptInterpreterTest</span>:
[info] <span class="hljs-type">ScriptInterpreter</span>
[info] - must evaluate all the scripts from the bitcoin core script_tests.json
[info] <span class="hljs-type">Run</span> completed in <span class="hljs-number">8</span> seconds, <span class="hljs-number">208</span> milliseconds.
[info] <span class="hljs-type">Total</span> number of tests run: <span class="hljs-number">1</span>
[info] <span class="hljs-type">Suites</span>: completed <span class="hljs-number">1</span>, aborted <span class="hljs-number">0</span>
[info] <span class="hljs-type">Tests</span>: succeeded <span class="hljs-number">1</span>, failed <span class="hljs-number">0</span>, canceled <span class="hljs-number">0</span>, ignored <span class="hljs-number">0</span>, pending <span class="hljs-number">0</span>
[info] <span class="hljs-type">All</span> tests passed.
</code></pre>
<p>The command <code>sbt testQuick</code> can also be handy. It runs tests that either:</p>
<ol>
<li>Failed previously</li>
<li>Has not been run previously</li>
<li>Either the test or one of its dependencies has been recompiled</li>
</ol>
<p>For more information on <code>testQuick</code>, see the offical
<a href="https://www.scala-sbt.org/1.x/docs/Testing.html#testQuick">sbt docs</a>.</p>
<h3><a class="anchor" aria-hidden="true" id="coverage"></a><a href="#coverage" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Coverage</h3>
<p>To produce a report that quantifies how much of our code is covered by tests:</p>
<pre><code class="hljs css language-bash">sbt
&gt; coverage
&gt; coreTest/<span class="hljs-built_in">test</span>
&gt; core/coverageReport
</code></pre>
<p>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 <code>core</code> project.</p>
<h3><a class="anchor" aria-hidden="true" id="ci"></a><a href="#ci" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>CI</h3>
<p>Bitcoin-S uses Travis 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 start your PR title with <code>Docs:</code>. This skips running tests on CI.</p>
</span></div></article></div><div class="docLastUpdate"><em>Last updated on 2020-6-15 by Nadav Kohen</em></div><div class="docs-prevnext"><a class="docs-prev button" href="/docs/0.2.0/applications/wallet"><span class="arrow-prev"></span><span>Previous</span></a><a class="docs-next button" href="/docs/0.2.0/contributing-website"><span>Contributing to the website</span><span class="arrow-next"></span></a></div></div></div><nav class="onPageNav"><ul class="toc-headings"><li><a href="#communication-channels">Communication Channels</a></li><li><a href="#working-on-bitcoin-s-applications">Working on Bitcoin-S applications</a><ul class="toc-headings"><li><a href="#running-the-applications">Running the applications</a></li><li><a href="#running-tests-for-the-applications">Running tests for the applications</a></li></ul></li><li><a href="#logging-when-working-on-bitcoin-s-tests">Logging when working on Bitcoin-S tests</a><ul class="toc-headings"><li><a href="#akka-logging">Akka logging</a></li></ul></li><li><a href="#developer-productivity">Developer productivity</a><ul class="toc-headings"><li><a href="#sbt">sbt</a></li><li><a href="#bloop">Bloop</a></li></ul></li><li><a href="#testing">Testing</a><ul class="toc-headings"><li><a href="#property-based-testing">Property based testing</a></li><li><a href="#running-tests">Running tests</a></li><li><a href="#coverage">Coverage</a></li><li><a href="#ci">CI</a></li></ul></li></ul></nav></div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/" class="nav-home"><img src="/img/favicon.ico" alt="bitcoin-s" width="66" height="58"/></a><div><h5>Docs</h5><a href="/docs/en/getting-started">Getting Started</a><a href="/docs/en/core/core-intro">Guides</a><a href="/api/org/bitcoins">API Reference</a></div><div><h5>Community</h5><a href="/en/users.html">User Showcase</a><a href="https://join.slack.com/t/suredbits/shared_invite/enQtNDEyMjY3MTg1MTg3LTYyYjkwOGUzMDQ4NDAwZjE1M2I3MmQyNWNlZjNlYjg4OGRjYTRjNWUwNjRjNjg4Y2NjZjAxYjU1N2JjMTU1YWM" target="_blank" rel="noreferrer noopener">Slack</a><a href="https://gitter.im/bitcoin-s-core/">Gitter chat</a></div><div><h5>More</h5><a href="https://github.com/bitcoin-s/bitcoin-s">GitHub</a><a class="github-button" href="https://github.com/bitcoin-s/bitcoin-s" data-icon="octicon-star" data-count-href="/bitcoin-s/bitcoin-s-core/stargazers" data-show-count="true" data-count-aria-label="# stargazers on GitHub" aria-label="Star this project on GitHub">Star</a></div></section><section class="copyright">Copyright © 2020 Suredbits &amp; the bitcoin-s developers</section></footer></div><script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script><script>
document.addEventListener('keyup', function(e) {
if (e.target !== document.body) {
return;
}
// keyCode for '/' (slash)
if (e.keyCode === 191) {
const search = document.getElementById('search_input_react');
search && search.focus();
}
});
</script><script>
var search = docsearch({
apiKey: '0a510688bf8448e19aeb380377d328d3',
indexName: 'bitcoin-s',
inputSelector: '#search_input_react'
});
</script></body></html>