Skip to content

Commit 4612b04

Browse files
authored
Merge pull request #4821 from Munkybooty/backports-0.20
backport: v0.20 pr1
2 parents 1d39df6 + bbf79db commit 4612b04

File tree

11 files changed

+171
-69
lines changed

11 files changed

+171
-69
lines changed

.travis.yml

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -202,28 +202,6 @@ after_success:
202202
script:
203203
- set -o errexit; source ./ci/extended_lint/06_script.sh
204204

205-
- stage: extended-lint
206-
name: 'lint macOS 10.12 (compat)'
207-
os: osx
208-
# Use the earliest macOS that can build our lint dependencies:
209-
# Xcode 8.3.3, macOS 10.12, JDK 1.8.0_112-b16
210-
# https://docs.travis-ci.com/user/reference/osx/#OS-X-Version
211-
osx_image: xcode8.3
212-
# TODO: if you're updating osx_image, try using "rvm:" to supply the
213-
# version of ruby required by homebrew. Despite this "rvm:" declaration,
214-
# brew update installs ruby 2.3.7 as its first action.
215-
language: ruby
216-
rvm:
217-
- 2.3.7
218-
env:
219-
cache: false
220-
install:
221-
- set -o errexit; source ./ci/lint/04_install.sh
222-
before_script:
223-
- set -o errexit; source ./ci/lint/05_before_script.sh
224-
script:
225-
- set -o errexit; source ./ci/lint/06_script.sh
226-
227205
- stage: test
228206
name: 'ARM [GOAL: install] [unit tests, no functional tests]'
229207
env: >-

ci/lint/04_install.sh

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,11 @@
66

77
export LC_ALL=C
88

9-
if [ "$TRAVIS_OS_NAME" == "osx" ]; then
10-
# update first to install required ruby dependency
11-
travis_retry brew update
12-
travis_retry brew reinstall git -- --with-pcre2 # for --perl-regexp
13-
travis_retry brew install grep # gnu grep for --perl-regexp support
14-
PATH="$(brew --prefix grep)/libexec/gnubin:$PATH"
15-
travis_retry brew install shellcheck
16-
travis_retry brew upgrade python
17-
PATH="$(brew --prefix python)/bin:$PATH"
18-
export PATH
19-
else
20-
SHELLCHECK_VERSION=v0.7.1
21-
curl -sL "https://github.com/koalaman/shellcheck/releases/download/${SHELLCHECK_VERSION}/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" | tar --xz -xf - --directory /tmp/
22-
PATH="/tmp/shellcheck-${SHELLCHECK_VERSION}:${PATH}"
23-
export PATH
24-
fi
25-
269
travis_retry pip3 install codespell==1.17.1
2710
travis_retry pip3 install flake8==3.8.3
2811
travis_retry pip3 install vulture==2.3
2912
travis_retry pip3 install yq
13+
14+
SHELLCHECK_VERSION=v0.6.0
15+
curl -s "https://storage.googleapis.com/shellcheck/shellcheck-${SHELLCHECK_VERSION}.linux.x86_64.tar.xz" | tar --xz -xf - --directory /tmp/
16+
export PATH="/tmp/shellcheck-${SHELLCHECK_VERSION}:${PATH}"

doc/benchmarking.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Running
1111
For benchmarks purposes you only need to compile `dash_bench`. Beware of configuring without `--enable-debug` as this would impact
1212
benchmarking by unlatching log printers and lock analysis.
1313

14-
make -C src bench_dash
14+
make -C src dash_bench
1515

1616
After compiling Dash Core, the benchmarks can be run with:
1717

test/README.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ By default, up to 4 tests will be run in parallel by test_runner. To specify
100100
how many jobs to run, append `--jobs=n`
101101

102102
The individual tests and the test_runner harness have many command-line
103-
options. Run `test_runner.py -h` to see them all.
103+
options. Run `test/functional/test_runner.py -h` to see them all.
104104

105105
#### Troubleshooting and debugging test failures
106106

@@ -113,7 +113,7 @@ killed all its dashd nodes), then there may be a port conflict which will
113113
cause the test to fail. It is recommended that you run the tests on a system
114114
where no other dashd processes are running.
115115

116-
On linux, the test_framework will warn if there is another
116+
On linux, the test framework will warn if there is another
117117
dashd process running when the tests are started.
118118

119119
If there are zombie dashd processes after test failure, you can kill them
@@ -142,7 +142,7 @@ tests will fail. If this happens, remove the cache directory (and make
142142
sure dashd processes are stopped as above):
143143

144144
```bash
145-
rm -rf cache
145+
rm -rf test/cache
146146
killall dashd
147147
```
148148

@@ -161,6 +161,15 @@ levels using the logger included in the test_framework, e.g.
161161
fails, the `test_framework.log` and dashd `debug.log`s will all be dumped
162162
to the console to help troubleshooting.
163163

164+
These log files can be located under the test data directory (which is always
165+
printed in the first line of test output):
166+
- `<test data directory>/test_framework.log`
167+
- `<test data directory>/node<node number>/regtest/debug.log`.
168+
169+
The node number identifies the relevant test node, starting from `node0`, which
170+
corresponds to its position in the nodes list of the specific test,
171+
e.g. `self.nodes[0]`.
172+
164173
To change the level of logs output to the console, use the `-l` command line
165174
argument.
166175

@@ -169,7 +178,7 @@ aggregate log by running the `combine_logs.py` script. The output can be plain
169178
text, colorized text or html. For example:
170179

171180
```
172-
combine_logs.py -c <test data directory> | less -r
181+
test/functional/combine_logs.py -c <test data directory> | less -r
173182
```
174183

175184
will pipe the colorized logs from the test into less.

test/functional/README.md

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44

55
#### Example test
66

7-
The [example_test.py](example_test.py) is a heavily commented example of a test case that uses both
8-
the RPC and P2P interfaces. If you are writing your first test, copy that file
9-
and modify to fit your needs.
7+
The file [test/functional/example_test.py](example_test.py) is a heavily commented example
8+
of a test case that uses both the RPC and P2P interfaces. If you are writing your first test, copy
9+
that file and modify to fit your needs.
1010

1111
#### Coverage
1212

13-
Running `test_runner.py` with the `--coverage` argument tracks which RPCs are
13+
Running `test/functional/test_runner.py` with the `--coverage` argument tracks which RPCs are
1414
called by the tests and prints a report of uncovered RPCs in the summary. This
1515
can be used (along with the `--extended` argument) to find out which RPCs we
1616
don't have test cases for.
@@ -82,7 +82,7 @@ P2P messages. These can be found in the following source files:
8282

8383
#### Using the P2P interface
8484

85-
- `messages.py` contains all the definitions for objects that pass
85+
- [messages.py](test_framework/messages.py) contains all the definitions for objects that pass
8686
over the network (`CBlock`, `CTransaction`, etc, along with the network-level
8787
wrappers for them, `msg_block`, `msg_tx`, etc).
8888

@@ -96,29 +96,32 @@ the Bitcoin Core node application logic. For custom behaviour, subclass the
9696
P2PInterface object and override the callback methods.
9797

9898
- Can be used to write tests where specific P2P protocol behavior is tested.
99-
Examples tests are `p2p_unrequested_blocks.py`, `p2p_compactblocks.py`.
99+
Examples tests are [p2p_unrequested_blocks.py](p2p_unrequested_blocks.py),
100+
[p2p_compactblocks.py](p2p_compactblocks.py).
100101

101-
### test-framework modules
102+
### Test framework modules
103+
The following are useful modules for test developers. They are located in
104+
[test/functional/test_framework/](test_framework).
102105

103-
#### [test_framework/authproxy.py](test_framework/authproxy.py)
106+
#### [authproxy.py](test_framework/authproxy.py)
104107
Taken from the [python-bitcoinrpc repository](https://github.com/jgarzik/python-bitcoinrpc).
105108

106-
#### [test_framework/test_framework.py](test_framework/test_framework.py)
109+
#### [test_framework.py](test_framework/test_framework.py)
107110
Base class for functional tests.
108111

109-
#### [test_framework/util.py](test_framework/util.py)
112+
#### [util.py](test_framework/util.py)
110113
Generally useful functions.
111114

112-
#### [test_framework/mininode.py](test_framework/mininode.py)
115+
#### [mininode.py](test_framework/mininode.py)
113116
Basic code to support P2P connectivity to a dashd.
114117

115-
#### [test_framework/script.py](test_framework/script.py)
118+
#### [script.py](test_framework/script.py)
116119
Utilities for manipulating transaction scripts (originally from python-bitcoinlib)
117120

118-
#### [test_framework/key.py](test_framework/key.py)
121+
#### [key.py](test_framework/key.py)
119122
Test-only secp256k1 elliptic curve implementation
120123

121-
#### [test_framework/blocktools.py](test_framework/blocktools.py)
124+
#### [blocktools.py](test_framework/blocktools.py)
122125
Helper functions for creating blocks and transactions.
123126

124127
### Benchmarking with perf

test/functional/feature_bip68_sequence.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@
66

77
from test_framework.blocktools import create_block, create_coinbase
88
from test_framework.messages import COIN, COutPoint, CTransaction, CTxIn, CTxOut, FromHex, ToHex
9-
from test_framework.script import CScript
109
from test_framework.test_framework import BitcoinTestFramework
11-
from test_framework.util import assert_equal, assert_greater_than, assert_raises_rpc_error, get_bip9_status, satoshi_round
10+
from test_framework.util import (
11+
assert_equal,
12+
assert_greater_than,
13+
assert_raises_rpc_error,
14+
get_bip9_status,
15+
satoshi_round
16+
)
17+
from test_framework.script_util import DUMMY_P2SH_SCRIPT
1218

1319
SEQUENCE_LOCKTIME_DISABLE_FLAG = (1<<31)
1420
SEQUENCE_LOCKTIME_TYPE_FLAG = (1<<22) # this means use time (0 means height)
@@ -76,7 +82,7 @@ def test_disable_flag(self):
7682
# input to mature.
7783
sequence_value = SEQUENCE_LOCKTIME_DISABLE_FLAG | 1
7884
tx1.vin = [CTxIn(COutPoint(int(utxo["txid"], 16), utxo["vout"]), nSequence=sequence_value)]
79-
tx1.vout = [CTxOut(value, CScript([b'a']))]
85+
tx1.vout = [CTxOut(value, DUMMY_P2SH_SCRIPT)]
8086

8187
tx1_signed = self.nodes[0].signrawtransactionwithwallet(ToHex(tx1))["hex"]
8288
tx1_id = self.nodes[0].sendrawtransaction(tx1_signed)
@@ -88,7 +94,7 @@ def test_disable_flag(self):
8894
tx2.nVersion = 2
8995
sequence_value = sequence_value & 0x7fffffff
9096
tx2.vin = [CTxIn(COutPoint(tx1_id, 0), nSequence=sequence_value)]
91-
tx2.vout = [CTxOut(int(value - self.relayfee * COIN), CScript([b'a' * 35]))]
97+
tx2.vout = [CTxOut(int(value - self.relayfee * COIN), DUMMY_P2SH_SCRIPT)]
9298
tx2.rehash()
9399

94100
assert_raises_rpc_error(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, ToHex(tx2))
@@ -183,7 +189,7 @@ def test_sequence_lock_confirmed_inputs(self):
183189
value += utxos[j]["amount"]*COIN
184190
# Overestimate the size of the tx - signatures should be less than 120 bytes, and leave 50 for the output
185191
tx_size = len(ToHex(tx))//2 + 120*num_inputs + 50
186-
tx.vout.append(CTxOut(int(value-self.relayfee*tx_size*COIN/1000), CScript([b'a'])))
192+
tx.vout.append(CTxOut(int(value-self.relayfee*tx_size*COIN/1000), DUMMY_P2SH_SCRIPT))
187193
rawtx = self.nodes[0].signrawtransactionwithwallet(ToHex(tx))["hex"]
188194

189195
if (using_sequence_locks and not should_pass):
@@ -212,7 +218,7 @@ def test_sequence_lock_unconfirmed_inputs(self):
212218
tx2 = CTransaction()
213219
tx2.nVersion = 2
214220
tx2.vin = [CTxIn(COutPoint(tx1.sha256, 0), nSequence=0)]
215-
tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))]
221+
tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee*COIN), DUMMY_P2SH_SCRIPT)]
216222
tx2_raw = self.nodes[0].signrawtransactionwithwallet(ToHex(tx2))["hex"]
217223
tx2 = FromHex(tx2, tx2_raw)
218224
tx2.rehash()
@@ -230,7 +236,7 @@ def test_nonzero_locks(orig_tx, node, relayfee, use_height_lock):
230236
tx = CTransaction()
231237
tx.nVersion = 2
232238
tx.vin = [CTxIn(COutPoint(orig_tx.sha256, 0), nSequence=sequence_value)]
233-
tx.vout = [CTxOut(int(orig_tx.vout[0].nValue - relayfee * COIN), CScript([b'a' * 35]))]
239+
tx.vout = [CTxOut(int(orig_tx.vout[0].nValue - relayfee * COIN), DUMMY_P2SH_SCRIPT)]
234240
tx.rehash()
235241

236242
if (orig_tx.hash in node.getrawmempool()):
@@ -343,7 +349,7 @@ def test_bip68_not_consensus(self):
343349
tx2 = CTransaction()
344350
tx2.nVersion = 1
345351
tx2.vin = [CTxIn(COutPoint(tx1.sha256, 0), nSequence=0)]
346-
tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))]
352+
tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee*COIN), DUMMY_P2SH_SCRIPT)]
347353

348354
# sign tx2
349355
tx2_raw = self.nodes[0].signrawtransactionwithwallet(ToHex(tx2))["hex"]
@@ -358,7 +364,7 @@ def test_bip68_not_consensus(self):
358364
tx3 = CTransaction()
359365
tx3.nVersion = 2
360366
tx3.vin = [CTxIn(COutPoint(tx2.sha256, 0), nSequence=sequence_value)]
361-
tx3.vout = [CTxOut(int(tx2.vout[0].nValue - self.relayfee * COIN), CScript([b'a' * 35]))]
367+
tx3.vout = [CTxOut(int(tx2.vout[0].nValue - self.relayfee * COIN), DUMMY_P2SH_SCRIPT)]
362368
tx3.rehash()
363369

364370
assert_raises_rpc_error(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, ToHex(tx3))
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2017-2019 The Bitcoin Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
"""Test loadblock option
6+
7+
Test the option to start a node with the option loadblock which loads
8+
a serialized blockchain from a file (usually called bootstrap.dat).
9+
To generate that file this test uses the helper scripts available
10+
in contrib/linearize.
11+
"""
12+
13+
import os
14+
import subprocess
15+
import sys
16+
import tempfile
17+
import urllib
18+
19+
from test_framework.test_framework import (
20+
BitcoinTestFramework,
21+
)
22+
from test_framework.util import assert_equal, wait_until
23+
24+
25+
class LoadblockTest(BitcoinTestFramework):
26+
def set_test_params(self):
27+
self.setup_clean_chain = True
28+
self.num_nodes = 2
29+
30+
def run_test(self):
31+
self.nodes[1].setnetworkactive(state=False)
32+
self.nodes[0].generate(100)
33+
34+
# Parsing the url of our node to get settings for config file
35+
data_dir = self.nodes[0].datadir
36+
node_url = urllib.parse.urlparse(self.nodes[0].url)
37+
cfg_file = os.path.join(data_dir, "linearize.cfg")
38+
bootstrap_file = os.path.join(self.options.tmpdir, "bootstrap.dat")
39+
genesis_block = self.nodes[0].getblockhash(0)
40+
blocks_dir = os.path.join(data_dir, "regtest", "blocks")
41+
hash_list = tempfile.NamedTemporaryFile(dir=data_dir,
42+
mode='w',
43+
delete=False,
44+
encoding="utf-8")
45+
46+
self.log.info("Create linearization config file")
47+
with open(cfg_file, "a", encoding="utf-8") as cfg:
48+
cfg.write("datadir={}\n".format(data_dir))
49+
cfg.write("rpcuser={}\n".format(node_url.username))
50+
cfg.write("rpcpassword={}\n".format(node_url.password))
51+
cfg.write("port={}\n".format(node_url.port))
52+
cfg.write("host={}\n".format(node_url.hostname))
53+
cfg.write("output_file={}\n".format(bootstrap_file))
54+
cfg.write("max_height=100\n")
55+
cfg.write("netmagic=fcc1b7dc\n")
56+
cfg.write("input={}\n".format(blocks_dir))
57+
cfg.write("genesis={}\n".format(genesis_block))
58+
cfg.write("hashlist={}\n".format(hash_list.name))
59+
60+
base_dir = self.config["environment"]["SRCDIR"]
61+
linearize_dir = os.path.join(base_dir, "contrib", "linearize")
62+
63+
self.log.info("Run linearization of block hashes")
64+
linearize_hashes_file = os.path.join(linearize_dir, "linearize-hashes.py")
65+
subprocess.run([sys.executable, linearize_hashes_file, cfg_file],
66+
stdout=hash_list,
67+
check=True)
68+
69+
self.log.info("Run linearization of block data")
70+
linearize_data_file = os.path.join(linearize_dir, "linearize-data.py")
71+
subprocess.run([sys.executable, linearize_data_file, cfg_file],
72+
check=True)
73+
74+
self.log.info("Restart second, unsynced node with bootstrap file")
75+
self.stop_node(1)
76+
self.start_node(1, ["-loadblock=" + bootstrap_file])
77+
wait_until(lambda: self.nodes[1].getblockcount() == 100)
78+
79+
assert_equal(self.nodes[1].getblockchaininfo()['blocks'], 100)
80+
assert_equal(self.nodes[0].getbestblockhash(), self.nodes[1].getbestblockhash())
81+
82+
83+
if __name__ == '__main__':
84+
LoadblockTest().main()
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2019 The Bitcoin Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
"""Useful Script constants and utils."""
6+
from test_framework.script import CScript
7+
8+
# To prevent a "tx-size-small" policy rule error, a transaction has to have a
9+
# size of at least 83 bytes (MIN_STANDARD_TX_SIZE in
10+
# src/policy/policy.h). Considering a Tx with the smallest possible single
11+
# input (blank, empty scriptSig), and with an output omitting the scriptPubKey,
12+
# we get to a minimum size of 60 bytes:
13+
#
14+
# Tx Skeleton: 4 [Version] + 1 [InCount] + 1 [OutCount] + 4 [LockTime] = 10 bytes
15+
# Blank Input: 32 [PrevTxHash] + 4 [Index] + 1 [scriptSigLen] + 4 [SeqNo] = 41 bytes
16+
# Output: 8 [Amount] + 1 [scriptPubKeyLen] = 9 bytes
17+
#
18+
# Hence, the scriptPubKey of the single output has to have a size of at
19+
# least 23 bytes, which corresponds to the size of a P2SH scriptPubKey.
20+
# The following script constant consists of a single push of 22 bytes of 'a':
21+
# <PUSH_22> <22-bytes of 'a'>
22+
# resulting in a 23-byte size. It should be used whenever (small) fake
23+
# scriptPubKeys are needed, to guarantee that the minimum transaction size is
24+
# met.
25+
DUMMY_P2SH_SCRIPT = CScript([b'a' * 22])

test/functional/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@
231231
'feature_dip0020_activation.py',
232232
'feature_uacomment.py',
233233
'feature_filelock.py',
234+
'feature_loadblock.py',
234235
'p2p_blockfilters.py',
235236
'feature_asmap.py',
236237
'feature_includeconf.py',

test/lint/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Check for missing documentation of command line options.
77
commit-script-check.sh
88
======================
99
Verification of [scripted diffs](/doc/developer-notes.md#scripted-diffs).
10+
Scripted diffs are only assumed to run on the latest LTS release of Ubuntu. Running them on other operating systems
11+
might require installing GNU tools, such as GNU sed.
1012

1113
git-subtree-check.sh
1214
====================

0 commit comments

Comments
 (0)