diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4a14c2a18..b0832ea0e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,208 +1,208 @@ Contributing to Bitcoin ABC =========================== The Bitcoin ABC project welcomes contributors! This guide is intended to help developers contribute effectively to Bitcoin ABC. Communicating with Developers ----------------------------- To get in contact with ABC developers, we monitor a telegram supergroup. The intent of this group is specifically to facilitate development of Bitcoin-ABC, and to welcome people who wish to participate. https://t.me/joinchat/HCYr50mxRWjA2uLqii-psw Acceptable use of this supergroup includes the following: * Introducing yourself to other ABC developers. * Getting help with your development environment. * Discussing how to complete a patch. It is not for: * Market discussion * Non-constructive criticism Bitcoin ABC Development Philosophy ---------------------------------- Bitcoin ABC aims for fast iteration and continuous integration. This means that there should be quick turnaround for patches to be proposed, reviewed, and committed. Changes should not sit in a queue for long. Here are some tips to help keep the development working as intended. These are guidelines for the normal and expected development process. Developers can use their judgement to deviate from these guidelines when they have a good reason to do so. - Keep each change small and self-contained. - Reach out for a 1-on-1 review so things move quickly. - Land the Diff quickly after it is accepted. - Don't amend changes after the Diff accepted, new Diff for another fix. - Review Diffs from other developers as quickly as possible. - Large changes should be broken into logical chunks that are easy to review, and keep the code in a functional state. - Do not mix moving stuff around with changing stuff. Do changes with renames on their own. - Sometimes you want to replace one subsystem by another implementation, in which case it is not possible to do things incrementally. In such cases, you keep both implementations in the codebase for a while, as described [here](https://www.gamasutra.com/view/news/128325/Opinion_Parallel_Implementations.php) - There are no "development" branches, all Diffs apply to the master branch, and should always improve it (no regressions). - Don't break the build, it is important to keep master green as much as possible. If a Diff is landed, and breaks the build, fix it quickly. If it cannot be fixed quickly, it should be reverted, and re-applied later when it no longer breaks the build. - As soon as you see a bug, you fix it. Do not continue on. Fixing the bug becomes the top priority, more important than completing other tasks. - Automate as much as possible, and spend time on things only humans can do. Here are some handy links for development practices aligned with Bitcoin ABC: - [Developer Notes](doc/developer-notes.md) - [Statement of Bitcoin ABC Values and Visions](https://www.yours.org/content/bitcoin-abc---our-values-and-vision-a282afaade7c) - [How to Do Code Reviews Like a Human - Part 1](https://mtlynch.io/human-code-reviews-1/) - [How to Do Code Reviews Like a Human - Part 2](https://mtlynch.io/human-code-reviews-2/) - [Large Diffs Are Hurting Your Ability To Ship](https://medium.com/@kurtisnusbaum/large-diffs-are-hurting-your-ability-to-ship-e0b2b41e8acf) - [Stacked Diffs: Keeping Phabricator Diffs Small](https://medium.com/@kurtisnusbaum/stacked-diffs-keeping-phabricator-diffs-small-d9964f4dcfa6) - [Parallel Implementations](https://www.gamasutra.com/view/news/128325/Opinion_Parallel_Implementations.php) - [The Pragmatic Programmer: From Journeyman to Master](https://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X) - [Advantages of monolithic version control](https://danluu.com/monorepo/) - [The importance of fixing bugs immediately](https://youtu.be/E2MIpi8pIvY?t=16m0s) - [Slow Deployment Causes Meetings](https://www.facebook.com/notes/kent-beck/slow-deployment-causes-meetings/1055427371156793/) - [Good Work, Great Work, and Right Work](https://forum.dlang.org/post/q7u6g1$94p$1@digitalmars.com) Getting set up with the Bitcoin ABC Repository ---------------------------------------------- 1. Create an account at https://reviews.bitcoinabc.org/ 2. Install Git and Arcanist on your machine Git documentation can be found at: https://git-scm.com/ Arcanist documentation can be found at: https://secure.phabricator.com/book/phabricator/article/arcanist_quick_start/ And: https://secure.phabricator.com/book/phabricator/article/arcanist/ To install these packages on Debian or Ubuntu, type: `sudo apt-get install git arcanist` 3. If you do not already have an SSH key set up, follow these steps: Type: `ssh-keygen -t rsa -b 4096 -C "your_email@example.com"` Enter a file in which to save the key (/home/*username*/.ssh/id_rsa): [Press enter] 4. Upload your SSH public key to reviews.bitcoinabc.org - - go to: `https://reviews.bitcoinabc.org/settings/user/*username*/page/ssh/` + - Go to: `https://reviews.bitcoinabc.org/settings/user/*username*/page/ssh/` - Under "SSH Key Actions", Select "Upload Public Key" Paste contents from: `/home/*username*/.ssh/id_rsa.pub` 5. Clone the repository and install Arcanist certificate: ``` git clone ssh://vcs@reviews.bitcoinabc.org:2221/source/bitcoin-abc.git cd bitcoin-abc arc install-certificate ``` Note: Arcanist tooling will tend to fail if your remote origin is set to something other than the above. A common mistake is to clone from Github and then forget to update your remotes. Follow instructions provided by `arc install-certificate` to provide your API token. 6. Code formatting tools If code formatting tools do not install automatically on your system, you may have to install clang-format-7, autopep8 and flake8. clang-format-7 can be installed from https://releases.llvm.org/download.html or https://apt.llvm.org To install autopep8 and flake8 on Ubuntu: ``` sudo apt-get install python-autopep8 flake8 ``` Working with The Bitcoin ABC Repository --------------------------------------- A typical workflow would be: - Create a topic branch in Git for your changes git checkout -b 'my-topic-branch' - Make your changes, and commit them git commit -a -m 'my-commit' - Create a differential with Arcanist arc diff You should add suggested reviewers and a test plan to the commit message. Note that Arcanist is set up to look only at the most-recent commit message, So all you changes for this Diff should be in one Git commit. - For large changes, break them into several Diffs, as described in this [guide](https://medium.com/@kurtisnusbaum/stacked-diffs-keeping-phabricator-diffs-small-d9964f4dcfa6). You can also include "Depends on Dxxx" in the Arcanist message to indicate dependence on other Diffs. - Log into Phabricator to see review and feedback. - Make changes as suggested by the reviewers. You can simply edit the files with my-topic-branch checked out, and then type `arc diff`. Arcanist will give you the option to add uncommited changes. Or, alternatively, you can commit the changes using `git commit -a --am` to add them to the last commit, or squash multiple commits by typing `git rebase -i master`. If you squash, make sure the commit message has the information needed for arcanist (such as the Diff number, reviewers, etc.). - Update your Diff by typing `arc diff` again. - When reviewers approve your Diff, it should be listed as "ready to Land" in Phabricator. When you want to commit your diff to the repository, check out type my-topic-branch in git, then type `arc land`. You have now successfully committed a change to the Bitcoin ABC repository. - When reviewing a Diff, apply the changeset on your local by using `arc patch D{NNNN}` - You will likely be re-writing git histories multiple times, which causes timestamp changes that require re-building a significant number of files. It's highly recommended to install `ccache` (re-run ./configure if you install it later), as this will help cut your re-build times from several minutes to under a minute, in many cases. What to work on --------------- If you are looking for a useful task to contribute to the project, a good place to start is the list of tasks at https://reviews.bitcoinabc.org/maniphest/ You could also try [backporting](doc/backporting.md) some code from Bitcoin Core. Copyright --------- By contributing to this repository, you agree to license your work under the MIT license unless specified otherwise in `contrib/debian/copyright` or at the top of the file itself. Any work contributed where you are not the original author must contain its license header with the original author(s) and source. Disclosure Policy ----------------- See [DISCLOSURE_POLICY](DISCLOSURE_POLICY). diff --git a/contrib/devtools/README.md b/contrib/devtools/README.md index bef9f41ce..6c6951541 100644 --- a/contrib/devtools/README.md +++ b/contrib/devtools/README.md @@ -1,142 +1,142 @@ Contents ======== This directory contains tools for developers working on this repository. check-doc.py ============ Check if all command line args are documented. The return value indicates the number of undocumented args. copyright\_header.py ==================== Provides utilities for managing copyright headers of `The Bitcoin developers` in repository source files. It has three subcommands: ``` $ ./copyright_header.py report [verbose] $ ./copyright_header.py update $ ./copyright_header.py insert ``` Running these subcommands without arguments displays a usage string. copyright\_header.py report \ [verbose] --------------------------------------------------------- Produces a report of all copyright header notices found inside the source files of a repository. Useful to quickly visualize the state of the headers. Specifying `verbose` will list the full filenames of files of each category. copyright\_header.py update \ [verbose] --------------------------------------------------------- Updates all the copyright headers of `The Bitcoin developers` which were changed in a year more recent than is listed. For example: ``` // Copyright (c) - The Bitcoin developers ``` will be updated to: ``` // Copyright (c) - The Bitcoin developers ``` where `` is obtained from the `git log` history. This subcommand also handles copyright headers that have only a single year. In those cases: ``` // Copyright (c) The Bitcoin developers ``` will be updated to: ``` // Copyright (c) - The Bitcoin developers ``` where the update is appropriate. copyright\_header.py insert \ ------------------------------------ Inserts a copyright header for `The Bitcoin developers` at the top of the file in either Python or C++ style as determined by the file extension. If the file is a Python file and it has `#!` starting the first line, the header is inserted in the line below it. The copyright dates will be set to be `-` where `` is according to the `git log` history. If `` is equal to ``, it will be set as a single year rather than two hyphenated years. If the file already has a copyright for `The Bitcoin developers`, the script will exit. gen-manpages.sh =============== A small script to automatically create manpages in ../../doc/man by running the release binaries with the -help option. This requires help2man which can be found at: https://www.gnu.org/software/help2man/ With in-tree builds this tool can be run from any directory within the repostitory. To use this tool with out-of-tree builds set `BUILDDIR`. For example: ```bash BUILDDIR=$PWD/build contrib/devtools/gen-manpages.sh ``` git-subtree-check.sh ==================== Run this script from the root of the repository to verify that a subtree matches the contents of the commit it claims to have been updated to. To use, make sure that you have fetched the upstream repository branch in which the subtree is maintained: * for `src/secp256k1`: https://github.com/bitcoin-core/secp256k1.git (branch master) * for `src/leveldb`: https://github.com/bitcoin-core/leveldb.git (branch bitcoin-fork) * for `src/univalue`: https://github.com/bitcoin-core/univalue.git (branch master) * for `src/crypto/ctaes`: https://github.com/bitcoin-core/ctaes.git (branch master) Usage: `git-subtree-check.sh DIR (COMMIT)` `COMMIT` may be omitted, in which case `HEAD` is used. optimize-pngs.py ================ A script to optimize png files in the bitcoin repository (requires pngcrush). security-check.py and test-security-check.py ============================================ Perform basic ELF security checks on a series of executables. symbol-check.py =============== A script to check that the (Linux) executables produced by gitian only contain allowed gcc, glibc and libstdc++ version symbols. This makes sure they are still compatible with the minimum supported Linux distribution versions. Example usage after a gitian build: find ../gitian-builder/build -type f -executable | xargs python contrib/devtools/symbol-check.py If only supported symbols are used the return value will be 0 and the output will be empty. If there are 'unsupported' symbols, the return value will be 1 a list like this will be printed: .../64/test_bitcoin: symbol memcpy from unsupported version GLIBC_2.14 .../64/test_bitcoin: symbol __fdelt_chk from unsupported version GLIBC_2.15 .../64/test_bitcoin: symbol std::out_of_range::~out_of_range() from unsupported version GLIBCXX_3.4.15 .../64/test_bitcoin: symbol _ZNSt8__detail15_List_nod from unsupported version GLIBCXX_3.4.15 update-translations.py ====================== Run this script from the root of the repository to update all translations from transifex. It will do the following automatically: -- fetch all translations -- post-process them into valid and committable format -- add missing translations to the build system (TODO) +- Fetch all translations +- Post-process them into valid and committable format +- Add missing translations to the build system (TODO) See doc/translation-process.md for more information. diff --git a/doc/abc/uahf-technical-spec.md b/doc/abc/uahf-technical-spec.md index 79db307ca..01d3fed65 100644 --- a/doc/abc/uahf-technical-spec.md +++ b/doc/abc/uahf-technical-spec.md @@ -1,281 +1,281 @@ # UAHF Technical Specification Version 1.6, 2017-07-24 ## Introduction This document describes proposed requirements for a block size Hard Fork (HF). BUIP 55 specified a block height fork. This UAHF specification is inspired by the idea of a flag day, but changed to a time-based fork due to miner requests. It should be possible to change easily to a height-based fork - the sense of the requirements would largely stay the same. ## Definitions MTP: the "median time past" value of a block, calculated from the nTime values of its past up to 11 ancestors, as obtained by the GetMedianTimePast(block.parent) call. "activation time": once the MTP of the chain tip is equal to or greater than this time, the next block must be a valid fork block. The fork block and subsequent blocks built on it must satisfy the new consensus rules. "fork block": the first block built on top of a chain tip whose MTP is greater than or equal to the activation time. "fork EB": the user-specified value that EB shall be set to at activation time. EB can be adjusted post-activation by the user. "fork MG": the user-specified value that MG shall be set to at activation time. It must be > 1MB. The user can adjust MG to any value once the fork has occurred (not limited to > 1MB after the fork). "Large block" means a block satisfying 1,000,000 bytes < block size <= EB, where EB is as adjusted by REQ-4-1 and a regular block is a block up to 1,000,000 bytes in size. "Core rules" means all blocks <= 1,000,000 bytes (Base block size). "Extended BU tx/sigops rules" means the existing additional consensus rules (1) and (2) below, as formalized by BUIP040 [1] and used by the Bitcoin Unlimited client's excessive checks for blocks larger than 1MB, extended with rule (3) below: 1. maximum sigops per block is calculated based on the actual size of a block using max_block_sigops = 20000 * ceil((max(blocksize, 1000000) / 1000000)) 2. maximum allowed size of a single transaction is 1,000,000 bytes (1MB) 3. maximum allowed number of sigops for a single transaction is 20k . NOTE 1: In plain English, the maximum allowed sigops per block is 20K sigops per the size of the block, rounded up to nearest integer in MB. i.e. 20K if <= 1MB, 40K for the blocks > 1MB and up to 2MB, etc. ## Requirements ### REQ-1 (fork by default) The client (with UAHF implementation) shall default to activating a hard fork with new consensus rules as specified by the remaining requirements. RATIONALE: It is better to make the HF active by default in a special HF release version. Users have to download a version capable of HF anyway, it is more convenient for them if the default does not require them to make additional configuration. NOTE 1: It will be possible to disable the fork behavior (see REQ-DISABLE) ### REQ-2 (configurable activation time) The client shall allow a "activation time" to be configured by the user, with a default value of 1501590000 (epoch time corresponding to Tue 1 Aug 2017 12:20:00 UTC) RATIONALE: Make it configurable to adapt easily to UASF activation time changes. NOTE 1: Configuring a "activation time" value of zero (0) shall disable any UAHF hard fork special rules (see REQ-DISABLE) ### REQ-3 (fork block must be > 1MB) The client shall enforce a block size larger than 1,000,000 bytes for the fork block. RATIONALE: This enforces the hard fork from the original 1MB chain and prevents a re-organization of the forked chain to the original chain. ### REQ-4-1 (require "fork EB" configured to at least 8MB at startup) If UAHF is not disabled (see REQ-DISABLE), the client shall enforce that the "fork EB" is configured to at least 8,000,000 (bytes) by raising an error during startup requesting the user to ensure adequate configuration. RATIONALE: Users need to be able to run with their usual EB prior to the fork (e.g. some are running EB1 currently). The fork code needs to adjust this EB automatically to a > 1MB value. 8MB is chosen as a minimum since miners have indicated in the past that they would be willing to support such a size, and the current network is capable of handling it. ### REQ-4-2 (require user to specify suitable *new* MG at startup) If UAHF is not disabled (see REQ-DISABLE), the client shall require the user to specify a "fork MG" (mining generation size) greater than 1,000,000 bytes. RATIONALE: This ensures a suitable MG is set at the activation time so that a mining node would produce a fork block compatible with REQ-3. It also forces the user (miner) to decide on what size blocks they want to produce immediately after the fork. NOTE 1: The DEFAULT_MAX_GENERATED_BLOCK_SIZE in the released client needs to remain 1,000,000 bytes so that the client will not generate invalid blocks before the fork activates. At activation time, however, the "fork MG" specified by the user (default: 2MB) will take effect. ### REQ-5 (max tx / max block sigops rules for blocks > 1 MB) Blocks larger than 1,000,000 shall be subject to "Extended BU tx/sigops rules" as follows: 1. maximum sigops per block shall be calculated based on the actual size of a block using `max_block_sigops = 20000 * ceil((max(blocksize_bytes, 1000000) / 1000000))` 2. maximum allowed size of a single transaction shall be 1,000,000 bytes NOTE 1: Blocks up to and including 1,000,000 bytes in size shall be subject to existing pre-fork Bitcoin consensus rules. NOTE 2: Transactions exceeding 100,000 bytes (100KB) shall remain non-standard after the activation time, meaning they will not be relayed. NOTE 3: BU treats both rules (1) and (2) as falling under the Emergent Consensus rules (AD). Other clients may choose to implement them as firm rules at their own risk. ### REQ-6-1 (disallow special OP_RETURN-marked transactions with sunset clause) Once the fork has activated, transactions consisting exclusively of a single OP_RETURN output, followed by a single minimally-coded data push with the specific magic data value of Bitcoin: A Peer-to-Peer Electronic Cash System (46 characters, including the single spaces separating the words, and without any terminating null character) shall be considered invalid until block 530,000 inclusive. RATIONALE: (DEPRECATED - see NOTE 2) To give users on the legacy chain (or other fork chains) an opt-in way to exclude their transactions from processing on the UAHF fork chain. The sunset clause block height is calculated as approximately 1 year after currently planned UASF activation time (Aug 1 2017 00:00:00 GMT), rounded down to a human friendly number. NOTE 1: Transactions with such OP_RETURNs shall be considered valid again for block 530,001 and onwards. NOTE 2: With the changes in v1.6 of this specification, mandatory use of SIGHASH_FORKID replay protection on UAHF chain makes the use of this opt-out protection unnecessary. Clients should nevertheless implement this requirement, as removing it would constitute a hard fork vis-a-vis the existing network. The sunset clause in this requirement will take care of its expiry by itself. ### REQ-6-2 (mandatory signature shift via hash type) Once the fork has activated, a transaction shall be deemed valid only if the following are true in combination: -- its nHashType has bit 6 set (SIGHASH_FORKID, mask 0x40) -- a magic 'fork id' value is added to the nHashType before the hash is +- Its nHashType has bit 6 set (SIGHASH_FORKID, mask 0x40) +- A magic 'fork id' value is added to the nHashType before the hash is calculated (see note 4) -- it is digested using the new algorithm described in REQ-6-3 +- It is digested using the new algorithm described in REQ-6-3 RATIONALE: To provide strong protection against replay of existing transactions on the UAHF chain, only transactions signed with the new hash algorithm and having SIGHASH_FORKID set will be accepted, by consensus. NOTE 1: It is possible for other hard forks to allow SIGHASH_FORKID-protected transactions on their chain by implementing a compatible signature. However, this does require a counter hard fork by legacy chains. NOTE 2: (DEPRECATED) ~~The client shall still accept transactions whose signatures~~ ~~verify according to pre-fork rules, subject to the additional OP_RETURN~~ ~~constraint introduced by REQ-6-1.~~ NOTE 3: (DEPRECATED) ~~If bit 6 is not set, only the unmodified nHashType will be used~~ ~~to compute the hash and verify the signature.~~ NOTE 4: The magic 'fork id' value used by UAHF-compatible clients is zero. This means that the change in hash when bit 6 is set is effected only by the adapted signing algorithm (see REQ-6-3). NOTE 5: See also REQ-6-4 which introduces a requirement for use of SCRIPT_VERIFY_STRICTENC. ### REQ-6-3 (use adapted BIP143 hash algorithm for protected transactions) Once the fork has activated, any transaction that has bit 6 set in its hash type shall have its signature hash computed using a minimally revised form of the transaction digest algorithm specified in BIP143. RATIONALE: see Motivation section of BIP143 [2]. NOTE 1: refer to [3] for the specification of the revised transaction digest based on BIP143. Revisions were made to account for non-Segwit deployment. ### REQ-6-4 (mandatory use of SCRIPT_VERIFY_STRICTENC) Once the fork has activated, transactions shall be validated with SCRIPT_VERIFY_STRICTENC flag set. RATIONALE: Use of SCRIPT_VERIFY_STRICTENC also ensures that the nHashType is validated properly. NOTE: As SCRIPT_VERIFY_STRICTENC is not clearly defined by BIP, implementations seeking to be compliant should consult the Bitcoin C++ source code to emulate the checks enforced by this flag. ### REQ-7 Difficulty adjustement in case of hashrate drop In case the MTP of the tip of the chain is 12h or more after the MTP 6 block before the tip, the proof of work target is increased by a quarter, or 25%, which corresponds to a difficulty reduction of 20% . RATIONALE: The hashrate supporting the chain is dependent on market price and hard to predict. In order to make sure the chain remains viable no matter what difficulty needs to adjust down in case of abrupt hashrate drop. ### REQ-DISABLE (disable fork by setting fork time to 0) If the activation time is configured to 0, the client shall not enforce the new consensus rules of UAHF, including the activation of the fork, the size constraint at a certain time, and the enforcing of EB/AD constraints at startup. RATIONALE: To make it possible to use such a release as a compatible client with legacy chain / i.e. to decide to not follow the HF on one's node / make a decision at late stage without needing to change client. ### OPT-SERVICEBIT (NODE_BITCOIN_CASH service bit) A UAHF-compatible client should set service bit 5 (value 0x20). RATIONALE: This service bit allows signaling that the node is a UAHF supporting node, which helps DNS seeders distinguish UAHF implementations. NOTE 1: This is an optional feature which clients do not strictly have to implement. NOTE 2: This bit is currently referred to as NODE_BITCOIN_CASH and displayed as "CASH" in user interfaces of some Bitcoin clients (BU, ABC). ## References [1] https://bitco.in/forum/threads/buip040-passed-emergent-consensus-parameters-and-defaults-for-large-1mb-blocks.1643/ [2] https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki#Motivation [3] [Digest for replay protected signature verification across hard forks](replay-protected-sighash.md) [4] https://github.com/Bitcoin-UAHF/spec/blob/master/uahf-test-plan.md END diff --git a/doc/functional-tests.md b/doc/functional-tests.md index 3fc115f7e..11dc6a42c 100644 --- a/doc/functional-tests.md +++ b/doc/functional-tests.md @@ -1,340 +1,340 @@ # Functional tests The [/ est/](/test/) directory contains integration tests that test bitcoind and its utilities in their entirety. It does not contain unit tests, which can be found in [/src/test](/src/test), [/src/wallet/test](/src/wallet/test), etc. There are currently two sets of tests in the [/test/](/test/) directory: - [functional](/test/functional) which test the functionality of bitcoind and bitcoin-qt by interacting with them through the RPC and P2P interfaces. - [util](/test/util) which tests the bitcoin utilities, currently only bitcoin-tx. The util tests are run as part of `make check` target. The functional tests are run by the Teamcity continuous build process whenever a diff is created or updated on Phabricator. Both sets of tests can also be run locally. # Running functional tests locally Build for your system first. Be sure to enable wallet, utils and daemon when you configure. Tests will not run otherwise. ### Functional tests #### Dependencies The ZMQ functional test requires a python ZMQ library. To install it: -- on Unix, run `sudo apt-get install python3-zmq` -- on mac OS, run `pip3 install pyzmq` +- On Unix, run `sudo apt-get install python3-zmq` +- On mac OS, run `pip3 install pyzmq` #### Running the tests Individual tests can be run by directly calling the test script, eg: ``` test/functional/example_test.py ``` or can be run through the test_runner harness, eg: ``` test/functional/test_runner.py example_test ``` You can run any combination (incl. duplicates) of tests by calling: ``` test/functional/test_runner.py ... ``` Run the regression test suite with: ``` test/functional/test_runner.py ``` Run all possible tests with ``` test/functional/test_runner.py --extended ``` By default, up to 4 tests will be run in parallel by test_runner. To specify how many jobs to run, append `--jobs=n` The individual tests and the test_runner harness have many command-line options. Run `test_runner.py -h` to see them all. #### Troubleshooting and debugging test failures ##### Resource contention The P2P and RPC ports used by the bitcoind nodes-under-test are chosen to make conflicts with other processes unlikely. However, if there is another bitcoind process running on the system (perhaps from a previous test which hasn't successfully killed all its bitcoind nodes), then there may be a port conflict which will cause the test to fail. It is recommended that you run the tests on a system where no other bitcoind processes are running. On linux, the test_framework will warn if there is another bitcoind process running when the tests are started. If there are zombie bitcoind processes after test failure, you can kill them by running the following commands. **Note that these commands will kill all bitcoind processes running on the system, so should not be used if any non-test bitcoind processes are being run.** ```bash killall bitcoind ``` or ```bash pkill -9 bitcoind ``` ##### Data directory cache A pre-mined blockchain with 200 blocks is generated the first time a functional test is run and is stored in test/cache. This speeds up test startup times since new blockchains don't need to be generated for each test. However, the cache may get into a bad state, in which case tests will fail. If this happens, remove the cache directory (and make sure bitcoind processes are stopped as above): ```bash rm -rf cache killall bitcoind ``` ##### Test logging The tests contain logging at different levels (debug, info, warning, etc). By default: -- when run through the test_runner harness, *all* logs are written to +- When run through the test_runner harness, *all* logs are written to `test_framework.log` and no logs are output to the console. -- when run directly, *all* logs are written to `test_framework.log` and INFO +- When run directly, *all* logs are written to `test_framework.log` and INFO level and above are output to the console. -- when run on Travis, no logs are output to the console. However, if a test +- When run on Travis, no logs are output to the console. However, if a test fails, the `test_framework.log` and bitcoind `debug.log`s will all be dumped to the console to help troubleshooting. To change the level of logs output to the console, use the `-l` command line argument. `test_framework.log` and bitcoind `debug.log`s can be combined into a single aggregate log by running the `combine_logs.py` script. The output can be plain text, colorized text or html. For example: ``` combine_logs.py -c | less -r ``` will pipe the colorized logs from the test into less. Use `--tracerpc` to trace out all the RPC calls and responses to the console. For some tests (eg any that use `submitblock` to submit a full block over RPC), this can result in a lot of screen output. By default, the test data directory will be deleted after a successful run. Use `--nocleanup` to leave the test data directory intact. The test data directory is never deleted after a failed test. ##### Attaching a debugger A python debugger can be attached to tests at any point. Just add the line: ```py import pdb; pdb.set_trace() ``` anywhere in the test. You will then be able to inspect variables, as well as call methods that interact with the bitcoind nodes-under-test. If further introspection of the bitcoind instances themselves becomes necessary, this can be accomplished by first setting a pdb breakpoint at an appropriate location, running the test to that point, then using `gdb` to attach to the process and debug. For instance, to attach to `self.node[1]` during a run: ```bash 2017-06-27 14:13:56.686000 TestFramework (INFO): Initializing test directory /tmp/user/1000/testo9vsdjo3 ``` use the directory path to get the pid from the pid file: ```bash cat /tmp/user/1000/testo9vsdjo3/node1/regtest/bitcoind.pid gdb /home/example/bitcoind ``` Note: gdb attach step may require `sudo`. To get rid of this, you can run: ```bash echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope ``` ### Util tests Util tests can be run locally by running `test/util/bitcoin-util-test.py`. Use the `-v` option for verbose output. # Writing functional tests #### Example test The [example_test.py](example_test.py) is a heavily commented example of a test case that uses both the RPC and P2P interfaces. If you are writing your first test, copy that file and modify to fit your needs. #### Coverage Running `test_runner.py` with the `--coverage` argument tracks which RPCs are called by the tests and prints a report of uncovered RPCs in the summary. This can be used (along with the `--extended` argument) to find out which RPCs we don't have test cases for. #### Style guidelines - Where possible, try to adhere to [PEP-8 guidelines]([https://www.python.org/dev/peps/pep-0008/) - Use a python linter like flake8 before submitting PRs to catch common style nits (eg trailing whitespace, unused imports, etc) - Avoid wildcard imports where possible - Use a module-level docstring to describe what the test is testing, and how it is testing it. - When subclassing the BitcoinTestFramwork, place overrides for the `set_test_params()`, `add_options()` and `setup_xxxx()` methods at the top of the subclass, then locally-defined helper methods, then the `run_test()` method. #### General test-writing advice - Set `self.num_nodes` to the minimum number of nodes necessary for the test. Having additional unrequired nodes adds to the execution time of the test as well as memory/CPU/disk requirements (which is important when running tests in parallel or on Travis). - Avoid stop-starting the nodes multiple times during the test if possible. A stop-start takes several seconds, so doing it several times blows up the runtime of the test. - Set the `self.setup_clean_chain` variable in `set_test_params()` to control whether or not to use the cached data directories. The cached data directories contain a 200-block pre-mined blockchain and wallets for four nodes. Each node has 25 mature blocks (25x50=1250 BTC) in its wallet. - When calling RPCs with lots of arguments, consider using named keyword arguments instead of positional arguments to make the intent of the call clear to readers. #### RPC and P2P definitions Test writers may find it helpful to refer to the definitions for the RPC and P2P messages. These can be found in the following source files: - `/src/rpc/*` for RPCs - `/src/wallet/rpc*` for wallet RPCs - `ProcessMessage()` in `/src/net_processing.cpp` for parsing P2P messages #### Using the P2P interface - `mininode.py` contains all the definitions for objects that pass over the network (`CBlock`, `CTransaction`, etc, along with the network-level wrappers for them, `msg_block`, `msg_tx`, etc). - P2P tests have two threads. One thread handles all network communication with the bitcoind(s) being tested (using python's asyncore package); the other implements the test logic. - `P2PConnection` is the class used to connect to a bitcoind. `P2PInterface` contains the higher level logic for processing P2P payloads and connecting to the Bitcoin Core node application logic. For custom behaviour, subclass the P2PInterface object and override the callback methods. - Call `network_thread_start()` after all `P2PInterface` objects are created to start the networking thread. (Continue with the test logic in your existing thread.) - Can be used to write tests where specific P2P protocol behavior is tested. Examples tests are `p2p_unrequested_blocks.py`, `p2p_compactblocks.py`. #### Comptool - Comptool is a Testing framework for writing tests that compare the block/tx acceptance behavior of a bitcoind against 1 or more other bitcoind instances. It should not be used to write static tests with known outcomes, since that type of test is easier to write and maintain using the standard BitcoinTestFramework. - Set the `num_nodes` variable (defined in `ComparisonTestFramework`) to start up 1 or more nodes. If using 1 node, then `--testbinary` can be used as a command line option to change the bitcoind binary used by the test. If using 2 or more nodes, then `--refbinary` can be optionally used to change the bitcoind that will be used on nodes 2 and up. - Implement a (generator) function called `get_tests()` which yields `TestInstance`s. Each `TestInstance` consists of: - - a list of `[object, outcome, hash]` entries + - A list of `[object, outcome, hash]` entries * `object` is a `CBlock`, `CTransaction`, or `CBlockHeader`. `CBlock`'s and `CTransaction`'s are tested for acceptance. `CBlockHeader`s can be used so that the test runner can deliver complete headers-chains when requested from the bitcoind, to allow writing tests where blocks can be delivered out of order but still processed by headers-first bitcoind's. * `outcome` is `True`, `False`, or `None`. If `True` or `False`, the tip is compared with the expected tip -- either the block passed in, or the hash specified as the optional 3rd entry. If `None` is specified, then the test will compare all the bitcoind's being tested to see if they all agree on what the best tip is. * `hash` is the block hash of the tip to compare against. Optional to specify; if left out then the hash of the block passed in will be used as the expected tip. This allows for specifying an expected tip while testing the handling of either invalid blocks or blocks delivered out of order, which complete a longer chain. - `sync_every_block`: `True/False`. If `False`, then all blocks are inv'ed together, and the test runner waits until the node receives the last one, and tests only the last block for tip acceptance using the outcome and specified tip. If `True`, then each block is tested in sequence and synced (this is slower when processing many blocks). - `sync_every_transaction`: `True/False`. Analogous to `sync_every_block`, except if the outcome on the last tx is "None", then the contents of the entire mempool are compared across all bitcoind connections. If `True` or `False`, then only the last tx's acceptance is tested against the given outcome. - For examples of tests written in this framework, see `p2p_invalid_block.py` and `feature_block.py`. ### test-framework modules #### [test_framework/authproxy.py](test_framework/authproxy.py) Taken from the [python-bitcoinrpc repository](https://github.com/jgarzik/python-bitcoinrpc). #### [test_framework/test_framework.py](test_framework/test_framework.py) Base class for functional tests. #### [test_framework/util.py](test_framework/util.py) Generally useful functions. #### [test_framework/mininode.py](test_framework/mininode.py) Basic code to support P2P connectivity to a bitcoind. #### [test_framework/comptool.py](test_framework/comptool.py) Framework for comparison-tool style, P2P tests. #### [test_framework/script.py](test_framework/script.py) Utilities for manipulating transaction scripts (originally from python-bitcoinlib) #### [test_framework/blockstore.py](test_framework/blockstore.py) Implements disk-backed block and tx storage. #### [test_framework/key.py](test_framework/key.py) Wrapper around OpenSSL EC_Key (originally from python-bitcoinlib) #### [test_framework/bignum.py](test_framework/bignum.py) Helpers for script.py #### [test_framework/blocktools.py](test_framework/blocktools.py) Helper functions for creating blocks and transactions.