Compare commits

...

280 Commits

Author SHA1 Message Date
Wladimir J. van der Laan
c1b7421781 Merge #9211: [0.12 branch] Backports
d609895 [Wallet] Bugfix: FRT: don't terminate when keypool is empty (Jonas Schnelli)
8dee97f [QA] add fundrawtransaction test on a locked wallet with empty keypool (Jonas Schnelli)
82e29e8 torcontrol: Explicitly request RSA1024 private key (Wladimir J. van der Laan)
cca151b Send tip change notification from invalidateblock (Russell Yanofsky)
ad99a79 [rpcwallet] Don't use floating point (MarcoFalke)
2016-12-14 10:18:23 +01:00
Jonas Schnelli
d6098956c3 [Wallet] Bugfix: FRT: don't terminate when keypool is empty
Github-Pull: #9295
Rebased-From: c24a4f5981
2016-12-07 23:48:46 +01:00
Jonas Schnelli
8dee97f982 [QA] add fundrawtransaction test on a locked wallet with empty keypool
Github-Pull: #9295
Rebased-From: 1a6eacbf3b
2016-12-07 23:48:12 +01:00
Wladimir J. van der Laan
82e29e8b7c torcontrol: Explicitly request RSA1024 private key
When generating a new service key, explicitly request a RSA1024 one.

The bitcoin P2P protocol has no support for the longer hidden service names
that will come with ed25519 keys, until it does, we depend on the old
hidden service type so make this explicit.

See #9214.

Github-Pull: #9234
Rebased-From: 7d3b627395
2016-11-30 22:15:37 +01:00
Russell Yanofsky
cca151b3a4 Send tip change notification from invalidateblock
This change is needed to prevent sync_blocks timeouts in the mempool_reorg
test after the sync_blocks update in the upcoming commit
"[qa] Change sync_blocks to pick smarter maxheight".

This change was initially suggested by Suhas Daftuar <sdaftuar@chaincode.com>
in https://github.com/bitcoin/bitcoin/pull/8680#r78209060

Github-Pull: #9196
Rebased-From: 67c6326abd
2016-11-23 13:24:14 +01:00
MarcoFalke
ad99a79869 [rpcwallet] Don't use floating point
Github-Pull: #8317
Rebased-From: 477777f250
2016-11-23 13:23:10 +01:00
Wladimir J. van der Laan
ec0afbd52b Merge #8176: [0.12.x]: Versionbits: GBT support
db4bacf getblocktemplate: Use version/force mutation to support pre-BIP9 clients (Luke Dashjr)
65ee332 getblocktemplate: Explicitly handle the distinction between GBT-affecting softforks vs not (Luke Dashjr)
40e81f5 qa/rpc-tests: bip9-softforks: Add tests for getblocktemplate versionbits updates (Luke Dashjr)
ddd8c01 Implement BIP 9 GBT changes (Luke Dashjr)
2016-09-01 16:25:34 +02:00
Wladimir J. van der Laan
15502d7b25 Merge #8187: [0.12.2] backport: [qa] Switch to py3
2826565 [qa] Switch to py3 (MarcoFalke)
2016-08-31 15:42:06 +02:00
MarcoFalke
28265655da [qa] Switch to py3
Github-Pull: #7814
Rebased-From: fa389d4edc
2016-07-15 19:31:08 +02:00
Wladimir J. van der Laan
1233cb42dd Merge #8302: 0.12.2: [Qt] Disable some menu items during splashscreen/verification state
fe98533 [Qt] Disable some menu items during splashscreen/verification state (Jonas Schnelli)
2016-07-11 12:29:01 +02:00
Wladimir J. van der Laan
5c84382076 Merge #8318: [0.12] Backport "Rename OP_NOP3 to OP_CHECKSEQUENCEVERIFY #7540"
c4e5688 Rename NOP3 to CHECSEQUENCEVERIFY in rpc tests (BtcDrak)
ac5577b Rename OP_NOP3 to OP_CHECKSEQUENCEVERIFY (BtcDrak)
2016-07-11 11:53:19 +02:00
BtcDrak
c4e5688230 Rename NOP3 to CHECSEQUENCEVERIFY in rpc tests 2016-07-08 11:44:16 +01:00
BtcDrak
ac5577b512 Rename OP_NOP3 to OP_CHECKSEQUENCEVERIFY 2016-07-08 11:44:16 +01:00
Jonas Schnelli
fe98533b40 [Qt] Disable some menu items during splashscreen/verification state
Github-Pull: #8042
Rebased-From: 276ce84fd3
2016-07-04 11:05:07 +02:00
Wladimir J. van der Laan
080457c4ee Merge #8148: Backport leveldb build integration to 0.12
9462e79 This is a cherry-pick of 89c844d back to 0.12. (Johnathan Corgan)
932aedd Cherry-pick of f59dceb (#7925) to 0.12. (Johnathan Corgan)
03c709b Backport leveldb build integration to 0.12 (Johnathan Corgan)
2016-06-28 16:05:07 +02:00
Wladimir J. van der Laan
9adad33938 Merge #8236: [doc] 0.12.2: prepare release notes
ffff324 [doc] 0.12: prepare release notes (MarcoFalke)
2016-06-22 16:44:06 +02:00
MarcoFalke
ffff324c1b [doc] 0.12: prepare release notes 2016-06-22 09:49:19 +02:00
Wladimir J. van der Laan
f3eebcf515 Merge #8230: Fix LogPrint to LogPrintf
ba61949 Fix LogPrint to LogPrintf (TheLazieR Yip)
2016-06-21 10:10:04 +02:00
TheLazieR Yip
ba6194928a Fix LogPrint to LogPrintf
Printing Log without category defined should use LogPrintf
2016-06-21 00:46:59 +07:00
Wladimir J. van der Laan
44fdacc19f Merge #8185: [0.12.2] Various qa and test backports
dc38a53 [qa] Move create_tx() to util.py (MarcoFalke)
c0fe8b5 [qa] smartfees: Properly use ordered dict (MarcoFalke)
493b89e [qa] test_framework: Properly print exceptions and assert empty dict (MarcoFalke)
7a83489 Tests: Fix deserialization of reject messages (Suhas Daftuar)
e0b1bbe [qa] pull-tester: Don't mute zmq ImportError (MarcoFalke)
697ed8c Check if zmq is installed in tests, update docs (Elliot Olds)
d5a9de3 tests: Check Content-Type header returned from RPC server (Wladimir J. van der Laan)
ed2f0e3 [qa] maxblocksinflight: Actually enable test (MarcoFalke)
3036282 [qa] httpbasics: Actually test second connection (MarcoFalke)
afbc000 test_framework: python3.4 authproxy compat (Wladimir J. van der Laan)
80b6bfa test_framework: detect failure of bitcoind startup (Wladimir J. van der Laan)
4ffd309 Create SingleNodeConnCB class for RPC tests (Alex Morcos)
4fd6008 travis: 'make check' in parallel and verbose (Cory Fields)
2d2b045 Reenable multithread scheduler test (Pavel Janík)
658307e test: Add more thorough test for dbwrapper iterators (Wladimir J. van der Laan)
2016-06-20 14:06:16 +02:00
MarcoFalke
dc38a53d56 [qa] Move create_tx() to util.py
(cherry picked from commit fa8cd46f39)
2016-06-10 00:33:26 +02:00
MarcoFalke
c0fe8b5c7d [qa] smartfees: Properly use ordered dict
Github-Pull: #7980
Rebased-From: fa17f93fbd 43bbcd0753
2016-06-10 00:25:22 +02:00
MarcoFalke
493b89e959 [qa] test_framework: Properly print exceptions and assert empty dict
Github-Pull: #7951
Rebased-From: 5555528b47 fada064f67
2016-06-10 00:22:41 +02:00
Suhas Daftuar
7a8348994b Tests: Fix deserialization of reject messages
Github-Pull: #7912
Rebased-From: 807fa47a1e
2016-06-10 00:20:33 +02:00
MarcoFalke
e0b1bbeae0 [qa] pull-tester: Don't mute zmq ImportError
Github-Pull: #7851
Rebased-From: fa05e22e91 faa4f22342 fae1f4ebfe
2016-06-10 00:11:51 +02:00
Elliot Olds
697ed8c827 Check if zmq is installed in tests, update docs
Github-Pull: #7635
Rebased-From: 2ab835ae6c
2016-06-10 00:07:50 +02:00
Wladimir J. van der Laan
d5a9de352c tests: Check Content-Type header returned from RPC server
Github-Pull: #7833
Rebased-From: 5078ca4543
2016-06-10 00:03:57 +02:00
MarcoFalke
ed2f0e3ac1 [qa] maxblocksinflight: Actually enable test
Github-Pull: #7803
Rebased-From: fac724c78f
2016-06-10 00:01:51 +02:00
MarcoFalke
3036282c7a [qa] httpbasics: Actually test second connection
Github-Pull: #7802
Rebased-From: fa24456d0c
2016-06-10 00:01:08 +02:00
Wladimir J. van der Laan
afbc000b0b test_framework: python3.4 authproxy compat
Github-Pull: #7751
Rebased-From: d7b80b54fb e7e48ba66c
2016-06-09 23:55:27 +02:00
Wladimir J. van der Laan
80b6bfaeaa test_framework: detect failure of bitcoind startup
Github-Pull: #7744
Rebased-From: 018b60c5ea
2016-06-09 23:51:53 +02:00
Alex Morcos
4ffd309b25 Create SingleNodeConnCB class for RPC tests
(cherry picked from commit 5fa66e4682)
2016-06-09 23:44:55 +02:00
Cory Fields
4fd6008105 travis: 'make check' in parallel and verbose
Github-Pull: #8072
Rebased-From: 401ae654b2
2016-06-09 23:30:18 +02:00
Pavel Janík
2d2b04543d Reenable multithread scheduler test
Github-Pull: #8016
Rebased-From: db18ab28c7 166e4b0dfa
2016-06-09 22:52:04 +02:00
Wladimir J. van der Laan
658307e835 test: Add more thorough test for dbwrapper iterators
Github-Pull: #7992
Rebased-From: 84c13e759d 6030625631 269a4402a8
2016-06-09 22:47:27 +02:00
Jonas Schnelli
0f8d574e8f OSX diskimages need 0775 folder permissions
Avoids endless Gatekeeper warnings (#7085)

Conflicts:
	contrib/gitian-descriptors/gitian-osx-signer.yml

Github-Pull: #8169
Rebased-From: cdf7dff424
2016-06-09 10:52:43 +02:00
Wladimir J. van der Laan
20d00a180e Merge #7938: [0.12.2] Backports
c3d1bc3 CBase58Data::SetString: cleanse the full vector (Kaz Wesley)
43c14ac Fix headers announcements edge case (Suhas Daftuar)
06c73a1 Removed call to `TryCreateDirectory` from `GetDefaultDataDir` in `src/util.cpp`. (Alexander Regueiro)
7e71785 Use txid as key in mapAlreadyAskedFor (Suhas Daftuar)
5583a3d Add curl to Gitian setup instrustions (BtcDrak)
d3ead9b Avoid "Unknown command" messages when receiving getaddr on outbound connections. (R E Broadley)
a5bc6a1 Remove vfReachable and modify IsReachable to only use vfLimited. (Patrick Strateman)
52c1011 Clarify description of blockindex (Matthew Zipkin)
21b2f82 Don't resend wallet txs that aren't in our own mempool (Alex Morcos)
66d5408 Fix memleak in TorController [rework] (Wladimir J. van der Laan)
1c3d38b Remove spurious dollar sign. Fixes #7189. (Chris Moore)
64fd0ce fix spelling of advertise in src and doc (jloughry)
a9e73f7 Fix and cleanup listreceivedbyX documentation (instagibbs)
9095594 Do not download transactions during inital sync (ptschip)
2016-06-09 10:22:52 +02:00
Luke Dashjr
db4bacf590 getblocktemplate: Use version/force mutation to support pre-BIP9 clients 2016-06-08 18:42:39 +00:00
Luke Dashjr
65ee3324fb getblocktemplate: Explicitly handle the distinction between GBT-affecting softforks vs not 2016-06-08 18:42:17 +00:00
Luke Dashjr
40e81f5f57 qa/rpc-tests: bip9-softforks: Add tests for getblocktemplate versionbits updates 2016-06-08 18:42:17 +00:00
Luke Dashjr
ddd8c01d70 Implement BIP 9 GBT changes
- BIP9DeploymentInfo struct for static deployment info
- VersionBitsDeploymentInfo: Avoid C++11ism by commenting parameter names
- getblocktemplate: Make sure to set deployments in the version if it is LOCKED_IN
- In this commit, all rules are considered required for clients to support
2016-06-08 18:42:17 +00:00
Johnathan Corgan
9462e791b7 This is a cherry-pick of 89c844d back to 0.12.
=====

Re-instate TARGET_OS=linux in configure.ac. Removed by 351abf9e03.
2016-06-08 06:41:03 -07:00
Johnathan Corgan
932aedd99a Cherry-pick of f59dceb (#7925) to 0.12.
=====

qt: Fix out-of-tree GUI builds

Without this patch:

- When I compile the GUI from the bitcoin directory itself, it works as
  expected.

- When I build the GUI in an out-of-tree build, I cannot get it to
  select tabs. When I click, say the "Receive" tab nothing happens,
  the button selects but it doesn't switch the page. The rest - even
  the debug window - seems to work.

See full discussion here:
https://github.com/bitcoin/bitcoin/pull/7911#issuecomment-212413442

This turned out to be caused by a mismatch in the arguments to moc,
preventing it from finding `bitcoin-config.h`. Fix this by passing
`$(DEFAULT_INCLUDES)` to it, which gets set to the appropriate
path by autoconf itself.
2016-06-08 06:29:27 -07:00
Johnathan Corgan
03c709b422 Backport leveldb build integration to 0.12
This is a cherry-pick of a4625acb with minor conflict
resolution.

Conflicts:
	src/Makefile.am

=====

leveldb: integrate leveldb into our buildsystem

leveldb's buildsystem causes us a few problems:
- breaks out-of-tree builds
- forces flags used for some tools
- limits cross builds

Rather than continuing to add wrappers around it, simply integrate it into our
build.
2016-06-05 12:48:57 -07:00
Kaz Wesley
c3d1bc33b5 CBase58Data::SetString: cleanse the full vector
SetString seems to be passing the length of the wrong variable to
memory_cleanse, resulting in the last byte of the temporary buffer not being
securely erased.

Github-Pull: #7922
Rebased-From: 57704499be
2016-06-04 18:01:02 +02:00
Wladimir J. van der Laan
e7ec24e336 Merge #8001: [0.12.2] backport script_tests improvements
e3a9ce9 Refactor script tests (Pieter Wuille)
87129b2 test: script_error checking in script_invalid tests (Wladimir J. van der Laan)
2016-05-31 15:52:55 +02:00
Wladimir J. van der Laan
c3aedca2df doc: Remove outdated qt4 install information from README.md
- doc: Remove outdated qt4 install information from README.md
- doc: 32 and 64 bit packages are seperate

Github-Pull: #8048
Rebased-From: e5764e69cb 6075bc4d67
2016-05-18 12:17:58 +02:00
Pieter Wuille
e3a9ce9c94 Refactor script tests
Github-Pull: #7818
Rebased-From: c7c664191f 269281b7cc d03e46625a 76da761351 009b503792 dde46d3ae1
2016-05-04 13:01:59 +02:00
Wladimir J. van der Laan
87129b24e1 test: script_error checking in script_invalid tests
Github-Pull: #7517
Rebased-From: b0ff8572ae 2317ad7c56 0ecb3401fe
2016-05-04 13:01:55 +02:00
Suhas Daftuar
43c14acf14 Fix headers announcements edge case
Previously we would assert that if every block in vBlockHashesToAnnounce is in
chainActive, then the blocks to be announced must connect.  However, there are
edge cases where this assumption could be violated (eg using invalidateblock /
reconsiderblock), so just check for this case and revert to inv-announcement
instead.

Github-Pull: #7919
Rebased-From: 3a99fb2cb1
2016-04-27 22:34:48 +02:00
Alexander Regueiro
06c73a1751 Removed call to TryCreateDirectory from GetDefaultDataDir in src/util.cpp.
See https://github.com/bitcoin/bitcoin/issues/7845#issuecomment-207684728.
Also refactored `GetDefaultDataDir` function to return path for Mac in one expression.

Github-Pull: #7850
Rebased-From: 41dbc4849e
2016-04-27 22:34:48 +02:00
Suhas Daftuar
7e71785c40 Use txid as key in mapAlreadyAskedFor
Previously we used the CInv that would be sent to the peer announcing the
transaction as the key, but using the txid instead allows us to decouple the
p2p layer from the application logic (which relies on this map to avoid
duplicate tx requests).

Github-Pull: #7862
Rebased-From: 7e91f632c7
2016-04-27 22:34:48 +02:00
BtcDrak
5583a3d0a7 Add curl to Gitian setup instrustions
curl is required to fetch dependencies

Github-Pull: #7658
Rebased-From: ce41cf082c
2016-04-27 22:34:48 +02:00
R E Broadley
d3ead9bcb6 Avoid "Unknown command" messages when receiving getaddr on outbound connections.
Github-Pull: #7642
Rebased-From: d84ea1a59ce3704457a162f1fd8a7353047156de
2016-04-27 22:34:48 +02:00
Patrick Strateman
a5bc6a1bc4 Remove vfReachable and modify IsReachable to only use vfLimited.
We do not know that a class of Network is reachable, only that it is not.

Github-Pull: #7553
Rebased-From: 110b62f069
2016-04-27 22:34:48 +02:00
Matthew Zipkin
52c101158f Clarify description of blockindex
see issues:

https://github.com/bitcoin-dot-org/bitcoin.org/issues/1237

https://github.com/bitcoin/bitcoin/issues/7532

Github-Pull: #7541
Rebased-From: 7eef1d0dad
2016-04-27 22:34:48 +02:00
Alex Morcos
21b2f82eb7 Don't resend wallet txs that aren't in our own mempool
Github-Pull: #7521
Rebased-From: 5a2b1c0c8b
2016-04-27 22:34:48 +02:00
Wladimir J. van der Laan
66d5408559 Fix memleak in TorController [rework]
It looks like, TorController::disconnected_cb(TorControlConnection&
conn) gets called multiple times which results in multiple event_new().

Avoid this by creating the event only once in the constructore, and
deleting it only once in the destructor (thanks to Cory Fields for the
idea).

Replaces the fix by Jonas Schnelli in #7610, see discussion there.

Github-Pull: #7637
Rebased-From: e219503711
2016-04-27 22:34:48 +02:00
Chris Moore
1c3d38bde7 Remove spurious dollar sign. Fixes #7189.
Github-Pull: #7189
Rebased-From: 3d19193f14
2016-04-27 22:34:48 +02:00
jloughry
64fd0ce1d9 fix spelling of advertise in src and doc
Github-Pull: #7526
Rebased-From: 37767fd46f
2016-04-27 22:34:48 +02:00
instagibbs
a9e73f71d4 Fix and cleanup listreceivedbyX documentation
Github-Pull: #7527
Rebased-From: c372572595
2016-04-27 22:34:48 +02:00
ptschip
90955940d5 Do not download transactions during inital sync
Github-Pull: #7164
Rebased-From: 39a525c21f
2016-04-27 22:34:47 +02:00
Wladimir J. van der Laan
18b3c3ced8 Merge #7950: [0.12] travis: switch to Trusty
564aaa2 travis: switch to Trusty (Cory Fields)
9ca957b tests: Make proxy_test work on travis servers without IPv6 (Wladimir J. van der Laan)
2016-04-27 14:11:44 +02:00
Cory Fields
564aaa2cd0 travis: switch to Trusty
Github-Pull: #7920
Rebased-From: 06fdffd222, 9267a47d86, cf77fcdb1f, 174023c9b0, a33b7c9cb5
2016-04-27 12:29:56 +02:00
Wladimir J. van der Laan
9ca957bcd4 tests: Make proxy_test work on travis servers without IPv6
Github-Pull: #7489
Rebased-From: 7539f1aae3
2016-04-27 12:29:56 +02:00
MarcoFalke
89ae85484c Merge #7811: [0.12.2] qa Backports
6862627 Add listunspent() test for spendable/unspendable UTXO (Joao Fonseca)
28ba22c [qa] Remove misleading "errorString syntax" (MarcoFalke)
f1f1b82 [qa] py2: Unfiddle strings into bytes explicitly (MarcoFalke)
c0d9e31 Tests: make prioritise_transaction.py more robust (Suhas Daftuar)
ff9b436 [qa] Bug fixes and refactor (MarcoFalke)
b1dd64b [qa] wallet: Wait for reindex to catch up (MarcoFalke)
f23cb7c [qa] Add tests verifychain, lockunspent, getbalance, listsinceblock (MarcoFalke)
3316552 [qa] Test walletpassphrase timeout (MarcoFalke)
6aae129 [qa] wallet: Print maintenance (MarcoFalke)
ad8c743 [qa] Extend tests (MarcoFalke)
d89fbfe [qa] rpc-test: Normalize assert() (MarcoFalke)
2016-04-25 14:59:52 +02:00
Joao Fonseca
6862627ce6 Add listunspent() test for spendable/unspendable UTXO
Github-Pull: #7822
Rebased-From: fa942c755a 5d217decc1
2016-04-19 16:37:14 +02:00
MarcoFalke
28ba22c202 [qa] Remove misleading "errorString syntax"
Github-Pull: #7801
Rebased-From: ffff866da8
2016-04-19 16:36:41 +02:00
MarcoFalke
f1f1b82033 [qa] py2: Unfiddle strings into bytes explicitly
Github-Pull: #7853
Rebased-From: faa41ee204, fa7abe0a00

 Conflicts:
	qa/rpc-tests/invalidtxrequest.py
	qa/rpc-tests/p2p-feefilter.py
	qa/rpc-tests/proxy_test.py
	qa/rpc-tests/test_framework/mininode.py
	qa/rpc-tests/test_framework/netutil.py
	src/test/bctest.py
2016-04-15 09:55:12 +02:00
Wladimir J. van der Laan
9779e1e1f3 Merge #7852: [0.12] Add missing reference to release notes
de7c34c Add missing link to BIP113 (BtcDrak)
2016-04-11 13:01:43 +02:00
BtcDrak
de7c34cab0 Add missing link to BIP113 2016-04-10 11:32:16 +01:00
Suhas Daftuar
c0d9e31611 Tests: make prioritise_transaction.py more robust
Github-Pull: #7697
Rebased-From: ec143391ef
2016-04-10 11:46:16 +02:00
Wladimir J. van der Laan
465d30915c doc: update release notes for #7835 2016-04-08 14:24:57 +02:00
Suhas Daftuar
46898e7e94 Version 2 transactions remain non-standard until CSV activates
Before activation, such transactions might not be mined, so don't
allow into the mempool.

- Tests: move get_bip9_status to util.py

- Test relay of version 2 transactions

Github-Pull: #7835
Rebased-From: e4ba9f6b04 5cb1d8a207 da5fdbb3a2
2016-04-08 14:22:04 +02:00
Wladimir J. van der Laan
cada7c2418 Fill in rest of release notes 2016-04-07 14:00:30 +02:00
Wladimir J. van der Laan
4c3a00d35c Reduce block timeout to 10 minutes
Now that #7804 fixed the timeout handling, reduce the block timeout from
20 minutes to 10 minutes. 20 minutes is overkill.

Conflicts:
	src/main.h

Github-Pull: #7832
Rebased-From: 62b9a557fc
2016-04-07 13:53:48 +02:00
Pieter Wuille
90f1d246d3 Track block download times per individual block
Currently, we're keeping a timeout for each requested block, starting
from when it is requested, with a correction factor for the number of
blocks in the queue.

That's unnecessarily complicated and inaccurate.

As peers process block requests in order, we can make the timeout for each
block start counting only when all previous ones have been received, and
have a correction based on the number of peers, rather than the total number
of blocks.

Conflicts:
	src/main.cpp
	src/main.h

Self check after the last peer is removed

Github-Pull: #7804
Rebased-From: 2d1d6581ec 0e24bbf679
2016-04-07 13:16:16 +02:00
Wladimir J. van der Laan
4226aacdba init: allow shutdown during 'Activating best chain...'
Two-line patch to make it possible to shut down bitcoind cleanly during
the initial ActivateBestChain.

Fixes #6459 (among other complaints).

To reproduce:

- shutdown bitcoind
- copy chainstate
- start bitcoind
- let the chain sync a bit
- shutdown bitcoind
- copy back old chainstate
- start bitcoind
- bitcoind will catch up with all blocks during Init()

(the `boost::this_thread::interruption_point` / `ShutdownRequested()`
dance is ugly, this should be refactored all over bitcoind at some point
when moving from boost::threads to c++11 threads, but it works...)

Github-Pull: #7821
Rebased-From: 07398e8e9d
2016-04-07 13:00:17 +02:00
Wladimir J. van der Laan
c2106543fe pre-rc1 translations update
New languages:

- `af` Afrikaans
- `es_AR` Spanish (Argentina)
- `es_CO` Spanish (Colombia)
- `ro` Romanian
- `ta` Tamil
- `uz@Latn` Uzbek in Latin script
2016-04-05 18:01:12 +02:00
Wladimir J. van der Laan
a784675a32 build: Remove unnecessary executables from gitian release
This removes the following executables from the binary gitian release:

- test_bitcoin-qt[.exe]
- bench_bitcoin[.exe]

@jonasschnelli and me discussed this on IRC a few days ago - unlike the
normal `bitcoin_tests` which is useful to see if it is safe to run
bitcoin on a certain OS/environment combination, there is no good reason
to include these. Better to leave them out to reduce the download
size.

Sizes from the 0.12 release:
```
2.4M bitcoin-0.12.0/bin/bench_bitcoin.exe
 22M bitcoin-0.12.0/bin/test_bitcoin-qt.exe
```

Github-Pull: #7776
Rebased-From: f063863d1f
2016-04-05 15:45:38 +02:00
MarcoFalke
ff9b436163 [qa] Bug fixes and refactor
Github-Pull: #7778
Rebased-From: fa524d9ddb fa2cea163b faaa3c9b65 444480649f
2016-04-05 11:55:07 +02:00
MarcoFalke
b1dd64bffe [qa] wallet: Wait for reindex to catch up
Github-Pull: #7757
Rebased-From: fa3fafc960
2016-04-05 11:53:51 +02:00
MarcoFalke
f23cb7c944 [qa] Add tests verifychain, lockunspent, getbalance, listsinceblock
Github-Pull: #7702
Rebased-From: fa4a522541
2016-04-05 11:53:50 +02:00
MarcoFalke
331655253d [qa] Test walletpassphrase timeout
Github-Pull: #7320
Rebased-From: fa1cb1ae15
2016-04-05 11:53:50 +02:00
MarcoFalke
6aae129a60 [qa] wallet: Print maintenance
Github-Pull: #7372
Rebased-From: facd288c31
2016-04-05 11:53:50 +02:00
MarcoFalke
ad8c743421 [qa] Extend tests
Github-Pull: #7684
Rebased-From: fa3a81af18 fad7dc8a6c fad8cfb893
2016-04-05 11:53:50 +02:00
MarcoFalke
d89fbfe899 [qa] rpc-test: Normalize assert()
Github-Pull: #7720
Rebased-From: fab3890156
2016-04-05 11:53:50 +02:00
Wladimir J. van der Laan
e3341aa94e Merge #7800: [0.12] Update release notes
e10c044 [0.12] Update release notes (BtcDrak)
2016-04-04 14:40:59 +02:00
Wladimir J. van der Laan
834aaef7bd Merge #7543: [0.12] Backport BIP9, BIP68 and BIP112 with softfork
640666b [qa] rpc-tests: Properly use integers, floats (BtcDrak)
c270b62 Fix comments in tests (BtcDrak)
caf1381 Add bip68-sequence.py to extended rpc tests (BtcDrak)
26e9a05 Test of BIP9 fork activation of mtp, csv, sequence_lock (NicolasDorier)
3a99feb Add RPC test for BIP 68/112/113 soft fork. (Alex Morcos)
159ee3d Policy: allow transaction version 2 relay policy. (BtcDrak)
9713ed3 Soft fork logic for BIP68 (BtcDrak)
648be9b Soft fork logic for BIP113 (BtcDrak)
ee40924 Add CHECKSEQUENCEVERIFY softfork through BIP9 (Pieter Wuille)
6ff0b9f RPC test for BIP9 warning logic (Suhas Daftuar)
0710b30 Test versionbits deployments (Suhas Daftuar)
8ebc6f2 Add testing of ComputeBlockVersion (Suhas Daftuar)
0bdaacd Softfork status report in RPC (Pieter Wuille)
5f90d4e Versionbits tests (Pieter Wuille)
6f83cf2 BIP9 Implementation (Pieter Wuille)
ade85e1 Add LockPoints (Alex Morcos)
c8d309e Code style fix. (BtcDrak)
6170506 Separate CheckLockTime() and CheckSequence() logic (BtcDrak)
c0c5e09 BIP112: Implement CHECKSEQUENCEVERIFY (Mark Friedenbach)
197c376 fix sdaftuar's nits again (Alex Morcos)
0a79c04 Bug fix to RPC test (Alex Morcos)
0d09af7 Add RPC test exercising BIP68 (mempool only) (Suhas Daftuar)
15ba08c Implement SequenceLocks functions (Alex Morcos)
2016-04-04 13:08:29 +02:00
BtcDrak
640666b22f [qa] rpc-tests: Properly use integers, floats
partial backport from #7778 using fa2cea1
2016-04-03 18:06:06 +01:00
BtcDrak
e10c044c78 [0.12] Update release notes 2016-04-03 17:53:53 +01:00
Wladimir J. van der Laan
c5f94f6584 Merge #7780: [0.12] Disable bad-chain alert
8692626 Disable bad chain alerts (BtcDrak)
2016-04-01 14:16:40 +02:00
BtcDrak
869262605f Disable bad chain alerts
Continuous false positives lead to them being ignored entirely
so it's better to disable now until this can be fixed more
thoroughly.
2016-03-31 20:50:54 +01:00
accraze
4d035bcc9a [doc] added depends cross compile info
Conflicts:
	doc/build-unix.md

Github-Pull: #7747
Rebased-From: 3e55b3a004
2016-03-31 13:49:36 +02:00
BtcDrak
c270b62cc2 Fix comments in tests 2016-03-31 10:28:57 +01:00
Wladimir J. van der Laan
ba80ceef59 bump version to 0.12.1 2016-03-30 20:12:21 +02:00
BtcDrak
caf138122d Add bip68-sequence.py to extended rpc tests 2016-03-29 10:34:07 +01:00
Wladimir J. van der Laan
a0cea89456 Merge #7741: [0.12] Mark p2p alert system as deprecated
c0fe2c9 Mark p2p alert system as deprecated. (BtcDrak)
2016-03-29 10:52:28 +02:00
NicolasDorier
26e9a05cc3 Test of BIP9 fork activation of mtp, csv, sequence_lock 2016-03-26 04:05:42 +00:00
BtcDrak
c0fe2c9e03 Mark p2p alert system as deprecated.
Set default to off
This feature is removed entirely as of 0.13.0
2016-03-24 20:06:06 +00:00
Jonas Schnelli
597494f5a9 Remove openssl info from init/log and from Qt debug window
Conflicts:
	src/init.cpp

Github-Merge: #7605
Rebased-From: 5ecfa36fd0
2016-03-24 12:09:23 +01:00
Jonas Schnelli
7ffc2bd943 [Wallet][RPC] add abandoned status to listtransactions
Github-Pull: #7739
Rebased-From: 263de3d1c8
2016-03-23 16:30:49 +01:00
Alex Morcos
19866c1ffc Fix calculation of balances and available coins.
No longer consider coins which aren't in our mempool.

Add test for regression in abandonconflict.py

Github-Pull: #7715
Rebased-From: 68d4282774
2016-03-23 15:11:22 +01:00
Alex Morcos
3a99feba85 Add RPC test for BIP 68/112/113 soft fork.
This RPC test will test both the activation mechanism of the first versionbits soft fork as well as testing many code branches of the consensus logic for BIP's 68, 112, and 113.
2016-03-18 09:28:41 +00:00
BtcDrak
159ee3dd90 Policy: allow transaction version 2 relay policy.
This commit introduces a way to gracefully bump the default
transaction version in a two step process.
2016-03-18 09:28:41 +00:00
BtcDrak
9713ed3015 Soft fork logic for BIP68 2016-03-18 09:28:40 +00:00
BtcDrak
648be9b442 Soft fork logic for BIP113 2016-03-18 09:28:40 +00:00
Pieter Wuille
ee40924fef Add CHECKSEQUENCEVERIFY softfork through BIP9 2016-03-18 09:28:40 +00:00
Suhas Daftuar
6ff0b9f96e RPC test for BIP9 warning logic 2016-03-18 09:14:53 +00:00
Suhas Daftuar
0710b303d6 Test versionbits deployments 2016-03-18 09:14:53 +00:00
Suhas Daftuar
8ebc6f2aac Add testing of ComputeBlockVersion 2016-03-18 09:14:53 +00:00
Pieter Wuille
0bdaacd791 Softfork status report in RPC 2016-03-18 09:14:52 +00:00
Pieter Wuille
5f90d4e294 Versionbits tests 2016-03-18 09:14:52 +00:00
Pieter Wuille
6f83cf2adb BIP9 Implementation
Inspired by former implementations by Eric Lombrozo and Rusty Russell, and
based on code by Jorge Timon.
2016-03-18 09:14:52 +00:00
Alex Morcos
ade85e126d Add LockPoints
Obtain LockPoints to store in CTxMemPoolEntry and during a reorg, evaluate whether they are still valid and if not, recalculate them.
2016-03-18 09:14:52 +00:00
BtcDrak
c8d309e4b4 Code style fix.
This if statement is a little obtuse and using braces here
improves readability.
2016-03-18 09:14:52 +00:00
BtcDrak
6170506fdf Separate CheckLockTime() and CheckSequence() logic
For the sake of a little repetition, make code more readable.
2016-03-18 09:14:52 +00:00
Mark Friedenbach
c0c5e09fe2 BIP112: Implement CHECKSEQUENCEVERIFY
- Replace NOP3 with CHECKSEQUENCEVERIFY (BIP112)
  <nSequence> CHECKSEQUENCEVERIFY -> <nSequence>
- Fails if txin.nSequence < nSequence, allowing funds of a txout to be locked for a number of blocks or a duration of time after its inclusion in a block.
- Pull most of CheckLockTime() out into VerifyLockTime(), a local function that will be reused for CheckSequence()
- Add bitwise AND operator to CScriptNum
- Enable CHECKSEQUENCEVERIFY as a standard script verify flag
- Transactions that fail CSV verification will be rejected from the mempool, making it easy to test the feature. However blocks containing "invalid" CSV-using transactions will still be accepted; this is *not* the soft-fork required to actually enable CSV for production use.
2016-03-18 09:14:52 +00:00
Alex Morcos
197c3760ff fix sdaftuar's nits again
it boggles the mind why these nits can't be delivered on a more timely basis
2016-03-18 09:14:52 +00:00
Alex Morcos
0a79c04af3 Bug fix to RPC test 2016-03-18 09:14:52 +00:00
Suhas Daftuar
0d09af77b7 Add RPC test exercising BIP68 (mempool only) 2016-03-18 09:14:52 +00:00
Alex Morcos
15ba08c3b5 Implement SequenceLocks functions
SequenceLocks functions are used to evaluate sequence lock times or heights per BIP 68.

The majority of this code is copied from maaku in #6312
Further credit: btcdrak, sipa, NicolasDorier
2016-03-18 09:14:52 +00:00
MarcoFalke
f04f4fd2ee [doc/log] Fix markdown syntax and line terminate LogPrint
- Fix doxygen comment for payTxFee
- [doc] Fix markdown
- Make sure LogPrintf strings are line-terminated

Github-Pull: #7617
Rebased-From: fa06ce0949 fa97f95c15 fa26652459
2016-03-11 09:44:17 +01:00
Luke Dashjr
ca8f160af5 Bugfix: gitian: Add curl to packages (now needed for depends)
Github-Pull: #7614
Rebased-From: 5c70a6d6d1
2016-03-01 15:13:22 +01:00
MarcoFalke
a10da9aa49 [depends] builders: No need to set -L and --location for curl
Github-Pull: #7606
Rebased-From: fa7a5c54fc
2016-03-01 15:03:54 +01:00
Luke Dashjr
00d57b4d3a Workaround Travis-side CI issues
Github-Pull: #7487
Rebased-From: 149641e8fc c01f08db12 5d1148cb79 1ecbb3b0f7
2016-03-01 15:03:44 +01:00
Wladimir J. van der Laan
35af157641 doc: Clean out release notes
0.12.0 was released, prepare empty release notes for 0.12.1.
2016-03-01 13:52:01 +01:00
Wladimir J. van der Laan
188ca9c305 Merge #7548: Correct duplicate names in release notes
ea52530 Fix duplicate names in release notes (fanquake)
2016-02-17 09:40:03 +01:00
fanquake
ea52530906 Fix duplicate names in release notes
Fixes #7547
2016-02-17 11:55:22 +08:00
Wladimir J. van der Laan
b466264635 doc: Remove another duplicate author name from release notes
The list of contributors is automatically generated from git, so people
that use multiple author names will end up on the list multiple times.
2016-02-16 12:40:13 +01:00
Wladimir J. van der Laan
02d707ff37 Merge #7523: Fix of semantic failure "meet pay"
e473c2d Fix of semantic failure "meet pay" (wodry)
2016-02-12 10:11:38 +01:00
wodry
e473c2dd02 Fix of semantic failure "meet pay"
"do not meet pay the minimum relay fee" ? I can understand English language quite well, but that I do not understand. So, if it's not an semantic nonsense, I would suggest to write it in more simple English.
2016-02-12 09:50:32 +01:00
Wladimir J. van der Laan
04503f78c7 Merge #7346: 0.12 release notes: Mining Policy Changes
b460004 release-notes: Minor corrections and clarifications re Priority (Luke Dashjr)
3450f4c release-notes: Significantly rewrite priority transactions section (Gregory Maxwell)
d0dbb6d release-notes: Remove suggestion to use 0.11 (Luke Dashjr)
73a0375 release-notes: Mention possibility of priority removal in 0.13, uncertainty of priority calculation being changed back, and request community input (Luke Dashjr)
4b8d2bc release-notes: Cover priority changes correctly, removing mentions of possible futures (Luke Dashjr)
2016-02-11 15:30:20 +01:00
Wladimir J. van der Laan
772863583c doc: fix author list in release notes 2016-02-10 21:37:49 +01:00
Wladimir J. van der Laan
68134263e2 qt: Translation update pre-rc5 2016-02-10 21:18:33 +01:00
Wladimir J. van der Laan
10be44a0bb doc: Release notes update pre-rc5 2016-02-10 21:03:40 +01:00
instagibbs
c3faf78c0e Changed getnetworkhps value to double to avoid overflow.
Github-Pull; #7480
Rebased-From: 993d089e82
2016-02-10 20:45:42 +01:00
mrbandrews
947c4ff724 [rpc-tests] Change solve() to use rehash
Github-Pull: #7468
Rebased-From: 7689041c03
2016-02-10 20:39:52 +01:00
Matt
9cb31e664a Fix spelling: misbeha{b,v}ing
Github-Pull: #7469
Rebased-From: 0830552673
2016-02-10 20:38:10 +01:00
Pieter Wuille
889e5b3050 Correctly report high-S violations
Github-Pull: #7500
Rebased-From: 9d95187d5d
2016-02-10 20:32:42 +01:00
Pieter Wuille
1329963001 Update the wallet best block marker when pruning
Github-Pull: #7502
Rebased-From: e4eebb604e
2016-02-10 19:59:01 +01:00
Wladimir J. van der Laan
00ec73e062 wallet: Ignore MarkConflict if block hash is not known
If number of conflict confirms cannot be determined, this means
that the block is still unknown or not yet part of the main chain,
for example during a reindex. Do nothing in that case,
instead of crash with an assertion.

Fixes #7234.

Github-Pull: #7491
Rebased-From: 40e7b61835
2016-02-10 19:58:19 +01:00
Luke Dashjr
b46000415c release-notes: Minor corrections and clarifications re Priority 2016-02-09 23:31:30 +00:00
Gregory Maxwell
3450f4cc95 release-notes: Significantly rewrite priority transactions section 2016-02-09 23:21:36 +00:00
Luke Dashjr
d0dbb6daee release-notes: Remove suggestion to use 0.11 2016-02-09 21:28:57 +00:00
Wladimir J. van der Laan
827a2b6736 qt: Translations update pre-rc4 2016-02-09 10:53:13 +01:00
Wladimir J. van der Laan
43484d7c08 doc: Update release notes for rc4 changes 2016-02-09 10:50:05 +01:00
Luke Dashjr
73a0375ebe release-notes: Mention possibility of priority removal in 0.13, uncertainty of priority calculation being changed back, and request community input 2016-02-09 08:13:38 +00:00
Suhas Daftuar
e16f5b40c2 Update nQueuedValidatedHeaders after peer disconnection
Github-Pull: #7482
Rebased-From: 301bc7bc7e
2016-02-09 08:55:03 +01:00
Wladimir J. van der Laan
b2f2b85ad5 rpc: Add WWW-Authenticate header to 401 response
A WWW-Authenticate header must be present in the 401
response to make clients know that they can authenticate,
and how.

    WWW-Authenticate: Basic realm="jsonrpc"

Fixes #7462.

Github-Pull: #7472
Rebased-From: 7c06fbd8f5
2016-02-09 08:52:33 +01:00
MarcoFalke
b9ed8c9969 [doc] Update release-process.md
Conflicts:
	doc/release-process.md

Github-Pull: #7465
Rebased-From: fa616c2fed
2016-02-08 10:47:12 +01:00
Wladimir J. van der Laan
996c27d1d9 doc: add PR authors to release notes
Take full names from github API if available, otherwise
github username.
2016-02-05 15:06:53 +01:00
Wladimir J. van der Laan
b1f031d435 qt: translations update pre-rc3 2016-02-03 10:59:04 +01:00
Wladimir J. van der Laan
a7939f8695 doc: update release notes for rc3 2016-02-03 10:56:18 +01:00
MarcoFalke
294f4320a2 [qt] Peertable: Increase SUBVERSION_COLUMN_WIDTH
Github-Pull: #7384
Rebased-From: faa9011d09
2016-02-03 10:31:34 +01:00
Wladimir J. van der Laan
c76bfff11e Merge #7440: [0.12] Rename permitrbf to mempoolreplacement and provide minimal string-list forward compatibility
af9f564 release-notes: Update for replacebyfee->mempoolreplacement rename (Luke Dashjr)
4ad418b Rename replacebyfee=opt-in to mempoolreplacement=fee (Luke Dashjr)
b2287a7 release-notes: Update for permitrbf->replacebyfee rename (Luke Dashjr)
5f456a6 Simplify check for replacebyfee=opt-in (Luke Dashjr)
e8d19ab Accept replacebyfee=opt-in for turning on opt-in RBF (Luke Dashjr)
1205f87 Rename permitrbf to replacebyfee (Luke Dashjr)
2016-02-03 10:30:10 +01:00
Luke Dashjr
af9f564267 release-notes: Update for replacebyfee->mempoolreplacement rename 2016-02-01 19:32:54 +00:00
Luke Dashjr
4ad418bc9b Rename replacebyfee=opt-in to mempoolreplacement=fee 2016-02-01 19:31:36 +00:00
Gregory Maxwell
86755bc85a Add whitelistforcerelay to control forced relaying. [#7099 redux]
- Add whitelistforcerelay to control forced relaying.

Also renames whitelistalwaysrelay.

Nodes relay all transactions from whitelisted peers, this
 gets in the way of some useful reasons for whitelisting
 peers-- for example, bypassing bandwidth limitations.

The purpose of this forced relaying is for specialized gateway
 applications where a node is being used as a P2P connection
 filter and multiplexer, but where you don't want it getting
 in the way of (re-)broadcast.

This change makes it configurable with whitelistforcerelay.

- Blacklist -whitelistalwaysrelay; replaced by -whitelistrelay.

Github-Pull: #7439
Rebased-From: 325c725fb6 89d113e02a
2016-02-01 14:15:40 +01:00
Wladimir J. van der Laan
e2d9a58588 Merge #7438: Do not absolutely protect local peers; decide group ties based on time.
8e09f91 Decide eviction group ties based on time. (Gregory Maxwell)
46dbcd4 Do not absolutely protect local peers from eviction. (Gregory Maxwell)
2016-02-01 10:46:44 +01:00
Luke Dashjr
b2287a7e01 release-notes: Update for permitrbf->replacebyfee rename 2016-01-29 01:33:50 +00:00
Luke Dashjr
5f456a6546 Simplify check for replacebyfee=opt-in 2016-01-29 01:31:55 +00:00
Luke Dashjr
e8d19ab79f Accept replacebyfee=opt-in for turning on opt-in RBF
Basic forward-compatibility with more flexible parameters like fss
2016-01-29 01:31:52 +00:00
Luke Dashjr
1205f87d36 Rename permitrbf to replacebyfee
"permit" is currently used to configure transaction filtering, whereas replacement is more to do with the memory pool state than the transaction itself.
2016-01-29 01:31:33 +00:00
Gregory Maxwell
8e09f914f8 Decide eviction group ties based on time.
This corrects a bug the case of tying group size where the code may
 fail to select the group with the newest member. Since newest time
 is the final selection criteria, failing to break ties on it
 on the step before can undermine the final selection.

Tied netgroups are very common.
2016-01-28 22:46:06 +00:00
Gregory Maxwell
46dbcd4833 Do not absolutely protect local peers from eviction.
With automatic tor HS support in place we should probably not be providing
 absolute protection for local peers, since HS inbound could be used to
 attack pretty easily.  Instead, this counts on the latency metric inside
 AttemptToEvictConnection to privilege actually local peers.
2016-01-28 22:45:22 +00:00
Wladimir J. van der Laan
cb83beb375 net: Hardcoded seeds update January 2016
Github-Pull: #7415
Rebased-From: 4818dba900
2016-01-28 10:55:11 +01:00
Wladimir J. van der Laan
32e3538752 Merge #7416: doc: Explain effects of -prune=<n> parameter in release notes
8c5f903 doc: In release notes, reduce length of pruning section (xor-freenet)
15c0263 doc: Minor spelling fix (xor-freenet)
54d3907 doc: Fix wrong claims about blockchain reorganization with pruning (xor-freenet)
a683d20 doc: Minor sentence length / capitalization fixes (xor-freenet)
58e3abf doc: In release notes, increase estimate of disk usage with pruning (xor-freenet)
be4b474 doc: In release notes, do not claim that pruning is leeching (xor-freenet)
46d7eb6 doc: Fix minimal disk usage with pruning enabled (xor-freenet)
fe074cc doc: Explain effects of -prune=<n> parameter in release notes (xor-freenet)
2016-01-27 17:09:41 +01:00
xor-freenet
8c5f90306c doc: In release notes, reduce length of pruning section 2016-01-27 16:29:39 +01:00
xor-freenet
15c0263ff1 doc: Minor spelling fix 2016-01-27 15:58:18 +01:00
xor-freenet
54d390780f doc: Fix wrong claims about blockchain reorganization with pruning 2016-01-27 15:54:56 +01:00
xor-freenet
a683d20d5f doc: Minor sentence length / capitalization fixes 2016-01-27 15:23:30 +01:00
Wladimir J. van der Laan
38bf790d70 Merge #7422: Improve section title in release-notes.md
42b521d Update release-notes.md (฿tcDrak)
2016-01-27 12:02:29 +01:00
Cory Fields
aa26ee0101 release: Add security/export checks to gitian and fix current failures
- fix parsing of BIND_NOW with older readelf
- add _IO_stdin_used to ignored exports

For details see: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=634261#109

- add check-symbols and check-security make targets

These are not added to the default checks because some of them depend on
release-build configs.

- always link librt for glibc back-compat builds

glibc absorbed clock_gettime in 2.17. librt (its previous location) is safe to
link in anyway for back-compat.

Fixes #7420

- add security/symbol checks to gitian

Github-Pull: #7424
Rebased-From: cd27bf51e0 475813ba5b f3d3eaf78e a8ce872118 a81c87fafc
2016-01-27 11:33:33 +01:00
Wladimir J. van der Laan
568c32411d Merge #7421: [doc] Release notes update for 0.12
65d384f doc: Update release notes for 0.12 (Suhas Daftuar)
2016-01-27 10:25:47 +01:00
Suhas Daftuar
65d384fe82 doc: Update release notes for 0.12
Update and reword BIP 125 section

Mention changes to banlist (clearbanned/setban)

Pruning nodes can relay
2016-01-26 10:36:13 -05:00
฿tcDrak
42b521d8a0 Update release-notes.md 2016-01-26 15:06:37 +00:00
xor-freenet
58e3abfffc doc: In release notes, increase estimate of disk usage with pruning
Jonas Schnelli recommended this to account for growth of utxo set, debug
log, etc.
2016-01-26 13:09:59 +01:00
xor-freenet
be4b474287 doc: In release notes, do not claim that pruning is leeching
Peter Todd says it does not matter currently.
2016-01-26 13:07:05 +01:00
xor-freenet
46d7eb6137 doc: Fix minimal disk usage with pruning enabled 2016-01-25 18:38:51 +01:00
xor-freenet
fe074ccb37 doc: Explain effects of -prune=<n> parameter in release notes
As discussed in the mailing list thread:
    [bitcoin-dev] Bitcoin Core 0.12.0 release candidate 1 available
in the replies to this message:
http://lists.linuxfoundation.org/pipermail/bitcoin-dev/2016-January/012276.html

Please review thoroughly, I'm a newbie.
2016-01-25 18:23:06 +01:00
Wladimir J. van der Laan
7c5e90e8dd doc: forgot #7222 in release notes 2016-01-22 11:58:48 +01:00
Wladimir J. van der Laan
1bc1d796be doc: Add commits since rc1 to release notes 2016-01-22 11:51:01 +01:00
Wladimir J. van der Laan
5df314b927 qt: pre-rc2 translations update 2016-01-22 11:43:19 +01:00
Wladimir J. van der Laan
b16b5bc191 Merge #7371: [0.12] backports
236686b [init] Add missing help for args (MarcoFalke)
44438a1 [init] Fix error message of maxtxfee invalid amount (MarcoFalke)
a74fa1f [Wallet] Transaction View: LastMonth calculation fixed (crowning-)
2016-01-22 11:41:04 +01:00
Wladimir J. van der Laan
f4b2ce8ee8 Merge #7387: Get rid of inaccurate ScriptSigArgsExpected
52b29dc Get rid of inaccurate ScriptSigArgsExpected (Pieter Wuille)
2016-01-22 11:39:58 +01:00
MarcoFalke
7726c487f8 [qt] Windows: Make rpcconsole monospace font larger
Github-Pull: #7364
Rebased-From: fa6a59dd39
2016-01-22 11:21:33 +01:00
Pieter Wuille
52b29dca76 Get rid of inaccurate ScriptSigArgsExpected 2016-01-21 13:52:32 +01:00
Wladimir J. van der Laan
da83ecd454 Add option -permitrbf to set transaction replacement policy
Add a configuration option `-permitrbf` to set transaction replacement policy
for the mempool.

Enabling it will enable (opt-in) RBF, disabling it will refuse all
conflicting transactions.

Conflicts:
	src/init.cpp
	src/main.cpp
	src/main.h

Github-Pull: #7386
Rebased-From: b768108d9c
2016-01-21 12:38:52 +01:00
Suhas Daftuar
e25b158ab8 RPC: indicate which transactions are replaceable
Add "bip125-replaceable" output field to listtransactions and gettransaction
which indicates if an unconfirmed transaction, or any unconfirmed parent, is
signaling opt-in RBF according to BIP 125.

Github-Pull: #7286
Rebased-From: eaa8d2754b
2016-01-20 13:50:58 +01:00
BtcDrak
64612f1820 Update project URL
Github-Pull: #7328
Rebased-From: b07b103e8a
2016-01-20 13:31:33 +01:00
Wladimir J. van der Laan
5bb3e263e2 build: Make networking work inside LXC builder in gitian-building.md
These are changes I needed to get gitian building to work with Debian
8.2, which is the version we tell to use.

- Set up NAT, so that container can access network beyond host
- Remove explicit cgroup setup - these are mounted automatically now
- gitian: Need `ca-certificates` and `python` for LXC builds

Github-Pull: #7060
Rebased-From: 99fda26de0 3b468a0e60
2016-01-20 13:26:49 +01:00
MarcoFalke
621bbd88ba [walletdb] Fix syntax error in key parser
Github-Pull: #7381
Rebased-From: fa6d4cc095
2016-01-20 13:08:40 +01:00
Luke Dashjr
4b8d2bc625 release-notes: Cover priority changes correctly, removing mentions of possible futures 2016-01-18 18:12:33 +00:00
Wladimir J. van der Laan
cda064caa1 Merge pull request #7370
fa31133 [Doc] Wallet & Pruning (MarcoFalke)
2016-01-18 16:31:07 +01:00
MarcoFalke
fa311338d2 [Doc] Wallet & Pruning 2016-01-18 16:26:57 +01:00
Suhas Daftuar
51af87f078 Fix error in blockchain.py introduced in merge
Github-Pull: #7373
Rebased-From: 4a04879378
2016-01-18 16:01:31 +01:00
MarcoFalke
236686b844 [init] Add missing help for args
Github-Pull: #7290
Rebased-From: fa6ab96799 faa572a329 fa461df685
2016-01-18 14:24:07 +01:00
MarcoFalke
44438a192a [init] Fix error message of maxtxfee invalid amount
Github-Pull: #7290
Rebased-From: fac11ea310
2016-01-18 14:18:49 +01:00
crowning-
a74fa1f06b [Wallet] Transaction View: LastMonth calculation fixed
Github-Pull: #7327
Rebased-From: 30cdacea3c
2016-01-18 14:14:31 +01:00
James O'Beirne
351ffd8482 Fix help, add RPC tests for getblockheader
- Add assert_is_hex_string and assert_is_hash_string to RPC test utils.
- Add RPC documentation for getblockheader[chainwork].
- Add RPC tests for getblockheader.

Github-Pull: #7194
Rebased-From: 16d4fce0b2 4745636126 135d6ec8ce
2016-01-18 12:25:50 +01:00
Gregory Sanders
c0d2382170 Added help text for chainwork value
Github-Pull: #7232
Rebased-From: 94bdd71f9b
2016-01-18 12:20:42 +01:00
MarcoFalke
d8b062d752 [qa] Fix pyton syntax in rpc tests
Github-Pull: #7335
Rebased-From: 7777994846
2016-01-18 10:46:46 +01:00
Wladimir J. van der Laan
d04525a065 Merge pull request #7345
fa8c497 [doc] backwards-compatibility issues due to chainstate obfuscation (MarcoFalke)
2016-01-18 10:39:10 +01:00
Wladimir J. van der Laan
1709cc5cb0 Merge pull request #7338
f17b00b release-notes: Combine NOP2->CLTV asm change into "RPC: Low-level API changes" section (Luke Dashjr)
e20704b Replace some instances of formatWithUnit with formatHtmlWithUnit (fanquake)
6f8346d qt5: Use the fixed font the system recommends (MarcoFalke)
605de4a Rename OP_NOP2 to OP_CHECKLOCKTIMEVERIFY. (mb300sd)
6191a9b [RPC-Tests] add option to run rpc test over QT clients (Jonas Schnelli)
6307beb Note that reviewers should mention the commit hash of the commits they reviewed. (Patrick Strateman)
6092ff2 Set link from http:// to https:// (Suriyaa Kudo)
2016-01-18 10:36:57 +01:00
Wladimir J. van der Laan
b0cb055673 Merge pull request #7347
5cacb8f Add comment about mining changes and more about priority (Alex Morcos)
2016-01-18 10:35:56 +01:00
Wladimir J. van der Laan
8b7a0f88cb Merge pull request #7367
2e552b0 Mention mempool chain limits in release notes (Suhas Daftuar)
2016-01-18 10:32:28 +01:00
Prayag Verma
098fcb5694 Update license year range to 2016
Conflicts:
	configure.ac

Github-Pull: #7363
Rebased-From: bd34174ebc
2016-01-18 10:31:30 +01:00
Suhas Daftuar
1488fc8eac Eliminate race condition in mempool_packages test
Github-Pull: #7368
Rebased-From: 4d10d2e16f
2016-01-18 10:29:32 +01:00
Suhas Daftuar
2e552b04c2 Mention mempool chain limits in release notes 2016-01-17 22:21:08 -05:00
Alex Morcos
5cacb8f319 Add comment about mining changes and more about priority 2016-01-17 07:40:21 -06:00
MarcoFalke
fa8c497d84 [doc] backwards-compatibility issues due to chainstate obfuscation 2016-01-17 12:05:13 +01:00
Wladimir J. van der Laan
d7c54c5a9d Merge pull request #7336
82667af release note fixups (Alex Morcos)
2016-01-16 11:06:02 +01:00
Cory Fields
fbea2f64e2 release: remove libc6 dependency from the osx signing descriptor
It is unneeded after the last toolchain update, and missing from Trusty.

Github-Pull: #7342
Rebased-From: 3503a78670
2016-01-14 13:47:06 +01:00
Luke Dashjr
f17b00b66f release-notes: Combine NOP2->CLTV asm change into "RPC: Low-level API changes" section 2016-01-13 21:34:02 +00:00
fanquake
e20704ba71 Replace some instances of formatWithUnit with formatHtmlWithUnit
Strings in a HTML context should be using formatHtmlWithUnit.

Github-Pull: #7255
Rebased-From: 5fdf32de7e
2016-01-13 21:25:36 +00:00
MarcoFalke
6f8346db5f qt5: Use the fixed font the system recommends
Github-Pull: #7214
Rebased-From: fa2f4bc4eb
2016-01-13 21:25:36 +00:00
mb300sd
605de4a88a Rename OP_NOP2 to OP_CHECKLOCKTIMEVERIFY.
Github-Pull: #7213
Rebased-From: 37d271d7cc
2016-01-13 21:25:36 +00:00
Jonas Schnelli
6191a9b628 [RPC-Tests] add option to run rpc test over QT clients
Github-Pull: #7068
Rebased-From: 979698c171
2016-01-13 21:25:35 +00:00
Patrick Strateman
6307beb09f Note that reviewers should mention the commit hash of the commits they reviewed.
Github-Pull: #7185
Rebased-From: e1030dddab
2016-01-13 21:25:35 +00:00
Suriyaa Kudo
6092ff205b Set link from http:// to https://
For opensource.org/licenses/MIT!
Github-Pull: #7197
Rebased-From: 00423e1a71
2016-01-13 21:10:51 +00:00
Alex Morcos
82667afd78 release note fixups 2016-01-13 15:20:16 -05:00
Wladimir J. van der Laan
5771b71ca5 doc: Remove BIP65 mention from release notes
This is already done, not new in 0.12.
2016-01-13 18:20:06 +01:00
Wladimir J. van der Laan
3d5cf698d6 Merge pull request #7333
a06a8b4 add InMempool() function (Jonas Schnelli)
2016-01-13 18:08:05 +01:00
Jonas Schnelli
a06a8b4888 add InMempool() function 2016-01-13 11:28:28 -05:00
Wladimir J. van der Laan
2a3161bf8b Merge pull request #7332 2016-01-13 16:02:12 +01:00
Wladimir J. van der Laan
afe825f075 Update translations pre-rc1 2016-01-13 15:58:59 +01:00
Wladimir J. van der Laan
071f704a70 Preliminary release notes 0.12.0 2016-01-13 15:56:51 +01:00
Alex Morcos
fd4bd5009e Add RPC call abandontransaction
- Make wallet descendant searching more efficient
- Add new rpc call: abandontransaction

Unconfirmed transactions that are not in your mempool either due to eviction or other means may be unlikely to be mined.  abandontransaction gives the wallet a way to no longer consider as spent the coins that are inputs to such a transaction.  All dependent transactions in the wallet will also be marked as abandoned.

- Add RPC test for abandoned and conflicted transactions.
- [Wallet] Call notification signal when a transaction is abandoned

Github-Pull: #7312
Rebased-From: 9e69717254 01e06d1fa3 df0e2226d9 d11fc1695c
2016-01-13 15:55:00 +01:00
Wladimir J. van der Laan
2c5c2154c9 Merge pull request #7309
fab88af Add fallbackfee default value (MarcoFalke)
fa0a391 Add Replace-by-fee to release-notes (MarcoFalke)
fa4ba40 Expand section "Wallet transaction fees" & fix format and typos (MarcoFalke)
fabba1c Update release-notes.md (MarcoFalke)
2016-01-13 12:44:02 +01:00
MarcoFalke
fab88af4d5 Add fallbackfee default value 2016-01-13 11:26:46 +01:00
Alex Morcos
a36d79bfe2 Add sane fallback for fee estimation
- Always respect GetRequiredFee for wallet txs
- Add sane fallback for fee estimation
- SQUASHME: Fix rpc tests that assumed fallback to minRelayTxFee

Add new commandline option "-fallbackfee" to use when fee estimation does not have sufficient data.

Github-Pull: #7296
Rebased-From: 995b9f3 e420a1b bebe58b
2016-01-13 11:06:17 +01:00
Wladimir J. van der Laan
8f25d6eb0e Merge pull request #7324 2016-01-13 10:55:54 +01:00
MarcoFalke
fa0a391b35 Add Replace-by-fee to release-notes 2016-01-13 09:14:36 +01:00
Luke Dashjr
d570a1f41b doc/bips: Document BIP 125 support 2016-01-09 17:40:39 +00:00
Wladimir J. van der Laan
a344880e6a Merge pull request #7323
45b8e27 -bytespersigop option to additionally limit sigops in transactions we relay and mine (Luke Dashjr)
2016-01-09 18:17:34 +01:00
Luke Dashjr
5b144b7113 Merge branch bytespersigop 2016-01-09 17:02:35 +00:00
Suhas Daftuar
d513405cb7 [Tests] Eliminate intermittent failures in sendheaders.py
- Add race-condition debugging tool to mininode
- Eliminate race condition in sendheaders.py test

Clear the last block announcement before mining new blocks.

Github-Pull: #7308
Rebased-From: 82a0ce09b4 168915e6de
2016-01-09 16:32:30 +01:00
Alex Morcos
4707797df2 Make sure conflicted wallet tx's update balances
Github-Pull: #7306
Rebased-From: f61766b37b
2016-01-08 17:38:04 +01:00
Wladimir J. van der Laan
9265e89a77 Merge pull request #7318
daa8da2 Backport: quickfix for RPC timer interface problem (Jonas Schnelli)
2016-01-08 17:33:59 +01:00
Wladimir J. van der Laan
1320300ea1 Merge pull request #7319
b1a8374 [qt] Intro: Display required space (MarcoFalke)
2016-01-08 17:32:57 +01:00
MarcoFalke
fa4ba40d8c Expand section "Wallet transaction fees" & fix format and typos 2016-01-08 17:24:25 +01:00
MarcoFalke
b1a8374aaa [qt] Intro: Display required space
Required space depends on the user's choice:
 -prune=0
 -prune=<n>
2016-01-08 11:22:08 +01:00
Jonas Schnelli
daa8da281b Backport: quickfix for RPC timer interface problem 2016-01-08 11:09:34 +01:00
MarcoFalke
fabba1c1a4 Update release-notes.md
Transaction memory pool limiting

Priority transactions

Wallet transaction fees
2016-01-07 16:46:03 +01:00
MarcoFalke
ff9b610026 [wallet] Add regression test for vValue sort order
- [wallet] Add regression test for vValue sort order
- [trivial] Merge test cases and replace CENT with COIN

Github-Pull: #7293
Rebased-From: fa3c7e644f faf538bfdb
2016-01-07 09:25:57 +01:00
MarcoFalke
1ed938b5fe [qa] wallet: Check if maintenance changes the balance
- [qa] Cleanup wallet.py test
- [qa] check if wallet or blochchain maintenance changes the balance
- [walletdb] Add missing LOCK() in Recover() for dummyWallet

Github-Pull: #7229
Rebased-From: fa0765d433 fa14d99484 fa33d9740c
2016-01-07 09:19:25 +01:00
MarcoFalke
333e1eaeea Bump copyright headers to 2015
- Bump copyright headers to 2015
- [devtools] Rewrite fix-copyright-headers.py
- [devtools] Use git pretty-format for year parsing

Github-Pull: #7205
Rebased-From: fa6ad855e9 fa24439ff3 fa71669452
2016-01-05 14:13:33 +01:00
Jonas Schnelli
5cadf3eb60 [Qt] fix coincontrol update issue when deleting a send coin entry
Github-Pull: #7282
Rebased-From: 621bd6919f
2016-01-05 13:08:32 +01:00
MarcoFalke
bfdaa3c87f [wallet] Adjust pruning test
Github-Pull: #7193
Rebased-From: fafd09375e
2016-01-05 12:57:57 +01:00
Suhas Daftuar
e08b7cb33c Mark blocks with too many sigops as failed
Github-Pull: #7217
Rebased-From: 5246180f16
2016-01-05 12:05:28 +01:00
Wladimir J. van der Laan
3cb066c62b Update translations after #7253
Include translations that omit raw number from the singular case.
2016-01-04 12:12:50 +01:00
Luke Dashjr
a75a03a5f2 Bugfix: update-translations: Allow numerus translations to omit %n specifier (usually when it only has one possible value)
Github-Pull: #7253
Rebased-From: 0d595894f0
2016-01-04 12:01:01 +01:00
MarcoFalke
bdd0f9e286 [qa] Move gen_return_txouts() to util.py
Github-Pull: #7250
Rebased-From: fa0a9749eb
2016-01-04 11:58:36 +01:00
MarcoFalke
f6c8c1242b [gitian] Set reference date to something more recent
Github-Pull: #7251
Rebased-From: fa095622c2
2016-01-04 11:43:06 +01:00
MarcoFalke
e70fc6f842 [debian] Bump manpages and only mention -?
The manpages are outdated and are very rarely updated when changes
to the code happen.

Github-Pull: #7274
Rebased-From: fae7a369cb fa6ce44bf9
2016-01-04 10:05:34 +01:00
Wladimir J. van der Laan
5ba42bad6d qt: periodic translations pull from transifex 2016-01-04 09:48:18 +01:00
Wladimir J. van der Laan
2d6a493493 Merge pull request #7245
fa8c8d7 torcontrol debug: Change to a blanket message that covers both cases (MarcoFalke)
2016-01-04 09:44:01 +01:00
Pieter Wuille
76de36fd2e Report non-mandatory script failures correctly
Github-Pull: #7276
Rebased-From: 7ef8f3c072
2016-01-04 09:13:09 +01:00
Wladimir J. van der Laan
453c56701a tests: Disable Tor interaction
This is unnecessary during the current tests (any test for Tor
interaction can explicitly enable it) and interferes with the proxy
test.

Github-Pull: #7170
Rebased-From: 4c40ec0451
2015-12-22 16:45:56 +01:00
Jonas Schnelli
9ef7c54ef0 [Tests] Add mempool_limit.py test
- [Tests] Add mempool_limit.py test
- [Tests] Refactor some shared functions

Github-Pull: #7153
Rebased-From: 110ff1142c 7632cf689a
2015-12-22 14:08:22 +01:00
Suhas Daftuar
301f16ad1c Add more tests to p2p-fullblocktest
Github-Pull: #7226
Rebased-From: 9b41a5fba2
2015-12-22 09:54:52 +01:00
Suhas Daftuar
12c469b236 [Mempool] Fix mempool limiting and replace-by-fee for PrioritiseTransaction
1) Fix mempool limiting for PrioritiseTransaction

Redo the feerate index to be based on mining score, rather than fee.

Update mempool_packages.py to test prioritisetransaction's effect on
package scores.

2) Update replace-by-fee logic to use fee deltas

3) Use fee deltas for determining mempool acceptance

4) Remove GetMinRelayFee

One test in AcceptToMemoryPool was to compare a transaction's fee
agains the value returned by GetMinRelayFee. This value was zero for
all small transactions.  For larger transactions (between
DEFAULT_BLOCK_PRIORITY_SIZE and MAX_STANDARD_TX_SIZE), this function
was preventing low fee transactions from ever being accepted.

With this function removed, we will now allow transactions in that range
with fees (including modifications via PrioritiseTransaction) below
the minRelayTxFee, provided that they have sufficient priority.

Github-Pull: #7062
Rebased-From: eb306664e7 9ef2a25603 27fae3484c 901b01d674
2015-12-21 17:19:53 +01:00
fanquake
eccd67106d [Depends] Bump Boost, miniupnpc, ccache & zeromq
Bring dependencies up to date with master:
[depends] Boost 1.59.0
[depends] miniupnpc 1.9.20151026
[depends] native ccache 3.2.4
[depends] zeromq 4.0.7
[depends] Latest config.guess & config.sub
[depends] Fix miniupnpc compilation on osx

Github-Pull: #6980
Rebased-From: 9e940fa4c6 17ad964c2f 26f8ea5342 10d3c77644 23a3c47f95 e0769e1928
2015-12-18 09:42:09 +01:00
Wladimir J. van der Laan
f3ad812208 test: don't override BITCOIND and BITCOINCLI if they're set
In rpc-tests.py, don't override BITCOIND and BITCOINCLI if they're
already set. Makes it possible to run the tests with either another tree
or the GUI.

Github-Pull: #7209
Rebased-From: 83cdcbdca4
2015-12-17 10:58:33 +01:00
Elias Rohrer
9572e4944a Removed offline testnet DNSSeed 'alexykot.me'.
Github-Pull: #7216
Rebased-From: e18378e53f
2015-12-17 10:40:50 +01:00
MarcoFalke
fa8c8d7fa6 torcontrol debug: Change to a blanket message that covers both cases 2015-12-16 12:57:06 +01:00
Pieter Wuille
10b88be798 Replace trickle nodes with per-node/message Poisson delays
We used to have a trickle node, a node which was chosen in each iteration of
the send loop that was privileged and allowed to send out queued up non-time
critical messages. Since the removal of the fixed sleeps in the network code,
this resulted in fast and attackable treatment of such broadcasts.

This pull request changes the 3 remaining trickle use cases by random delays:
* Local address broadcast (while also removing the the wiping of the seen filter)
* Address relay
* Inv relay (for transactions; blocks are always relayed immediately)

The code is based on older commits by Patrick Strateman.

Github-Pull: #7125
Rebased-From: 5400ef6bcb
2015-12-14 13:43:53 +01:00
accraze
06c6a58463 Checks for null data transaction before issuing error to debug.log
CWalletTx::GetAmounts could not find output address for null data transactions, thus issuing an error in debug.log. This change checks to see if the transaction is OP_RETURN before issuing error.

resolves #6142

Github-Pull: #7200
Rebased-From: b6915b8239 c611acc38a d812daf967
2015-12-14 13:10:02 +01:00
Matt Corallo
f43c2f9a8a Add "NODE_BLOOM" to guiutil so that peers don't get UNKNOWN[4]
Rebased-From: daf6466330
Github-Pull: #7206
2015-12-14 09:54:56 +01:00
Wladimir J. van der Laan
8fc174aae6 net: Add and document network messages in protocol.h
- Avoids string typos (by making the compiler check)
- Makes it easier to grep for handling/generation of a certain message type
- Refer directly to documentation by following the symbol in IDE
- Move list of valid message types to protocol.cpp:
    protocol.cpp is a more appropriate place for this, and having
    the array there makes it easier to keep things consistent.

Github-Pull: #7181
Rebased-From: 9bbe71b641
2015-12-11 11:18:50 +01:00
Wladimir J. van der Laan
44fef99e66 net: Fix sent reject messages for blocks and transactions
Ever since we #5913 have been sending invalid reject messages
for transactions and blocks.

test: Add basic test for `reject` code

Extend P2P test framework to make it possible to expect reject
codes for transactions and blocks.

Github-Pull: #7179
Rebased-From: 9fc6ed6003 20411903d7
2015-12-10 11:59:34 +01:00
AlSzacrel
96e8d12033 Coinselection prunes extraneous inputs from ApproximateBestSubset
This is a combination of 3 commits.

- Coinselection prunes extraneous inputs from ApproximateBestSubset
  A further pass over the available inputs has been added to ApproximateBestSubset after a candidate set has been found. It will prune any extraneous inputs in the selected subset, in order to decrease the number of input and the resulting change.
- Moved set reduction to the end of ApproximateBestSubset to reduce performance impact
- Added a test for the pruning of extraneous inputs after ApproximateBestSet

Github-Pull: #4906
Rebased-From: 5c03483e26 af9510e037 fc0f52d780
2015-12-08 10:25:58 +01:00
Wladimir J. van der Laan
b2d7ada372 test: remove necessity to call create_callback_map
Remove necessity to call create_callback_map (as well as the function
itself) from the Python P2P test framework. Invoke the appropriate
methods directly.

- Easy to forget to call it and wonder why it doesn't work
- Simplifies the code
- This makes it easier to handle new messages in subclasses

Github-Pull: #7171
Rebased-From: 2f601d215d
2015-12-07 12:45:14 +01:00
Matt Corallo
82aff880d3 Don't do mempool lookups for "mempool" command without a filter
Github-Pull: #7174
Rebased-From: 96918a2f09
2015-12-07 12:35:20 +01:00
Gregory Maxwell
f31955d9da Replace setInventoryKnown with a rolling bloom filter.
Github-Pull: #7133
Rebased-From: ec73ef37ec e20672479e 6b849350ab b6a0da45db d41e44c9ac aa4b0c26b0
2015-12-04 15:01:09 +01:00
Gregory Maxwell
6ba25d2886 Disconnect on mempool requests from peers when over the upload limit.
Mempool requests use a fair amount of bandwidth when the mempool is large,
 disconnecting peers using them follows the same logic as disconnecting
 peers fetching historical blocks.

Rebased-From: 6aadc75578
Github-Pull: #7166
2015-12-04 09:44:24 +01:00
Matt Bogosian
cfb44ce97a Add missing automake package to deb-based UNIX install instructions.
Rebased-From: b440409025
Github-Pull: #7152
2015-12-03 13:57:51 +01:00
Wladimir J. van der Laan
2985000808 Bump version to 0.12.0
Bump version from 0.11.99 to 0.12.0 so that we don't forget to do this
when rc1 is released.
2015-12-03 12:18:53 +01:00
Luke Dashjr
45b8e278fb -bytespersigop option to additionally limit sigops in transactions we relay and mine 2015-12-01 20:57:08 +00:00
482 changed files with 24213 additions and 7351 deletions

View File

@@ -3,6 +3,11 @@
# compiler key (which we don't use anyway). This is worked around for now by
# replacing the "compilers" with a build name prefixed by the no-op ":"
# command. See: https://github.com/travis-ci/travis-ci/issues/4393
# - sudo/dist/group are set so as to get Blue Box VMs, necessary for [loopback]
# IPv6 support
sudo: required
dist: trusty
os: linux
language: cpp
@@ -31,28 +36,31 @@ matrix:
- compiler: ": ARM"
env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
- compiler: ": Win32"
env: HOST=i686-w64-mingw32 PPA="ppa:ubuntu-wine/ppa" PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine1.7 bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2"
env: HOST=i686-w64-mingw32 DPKG_ADD_ARCH="i386" DEP_OPTS="NO_QT=1" PACKAGES="python3 nsis g++-mingw-w64-i686 wine1.6 bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports"
- compiler: ": 32-bit + dash"
env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python-zmq" PPA="ppa:chris-lea/zeromq" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash"
env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc python3-zmq" DEP_OPTS="NO_QT=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash"
- compiler: ": Win64"
env: HOST=x86_64-w64-mingw32 PPA="ppa:ubuntu-wine/ppa" PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine1.7 bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2"
env: HOST=x86_64-w64-mingw32 DPKG_ADD_ARCH="i386" DEP_OPTS="NO_QT=1" PACKAGES="python3 nsis g++-mingw-w64-x86-64 wine1.6 bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports"
- compiler: ": bitcoind"
env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc python-zmq" PPA="ppa:chris-lea/zeromq" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER"
env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc python3-zmq" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER"
- compiler: ": No wallet"
env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
env: HOST=x86_64-unknown-linux-gnu PACKAGES="python3" DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
- compiler: ": Cross-Mac"
env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy"
exclude:
- compiler: gcc
before_install:
- export PATH=$(echo $PATH | tr ':' "\n" | sed '/\/opt\/python/d' | tr "\n" ":" | sed "s|::|:|g")
install:
- if [ -n "$PACKAGES" ]; then sudo rm -f /etc/apt/sources.list.d/travis_ci_zeromq3-source.list; fi
- if [ -n "$PACKAGES" ]; then sudo rm -f /etc/apt/sources.list.d/google-chrome.list; fi
- if [ -n "$PPA" ]; then travis_retry sudo add-apt-repository "$PPA" -y; fi
- if [ -n "$DPKG_ADD_ARCH" ]; then sudo dpkg --add-architecture "$DPKG_ADD_ARCH" ; fi
- if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi
- if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi
before_script:
- unset CC; unset CXX
- mkdir -p depends/SDKs depends/sdk-sources
- if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then wget $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -O depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
- if [ -n "$OSX_SDK" -a ! -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then curl --location --fail $SDK_URL/MacOSX${OSX_SDK}.sdk.tar.gz -o depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
- if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
- make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS
script:
@@ -60,7 +68,6 @@ script:
- OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST
- BITCOIN_CONFIG_ALL="--disable-dependency-tracking --prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib"
- depends/$HOST/native/bin/ccache --max-size=$CCACHE_SIZE
- if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then export CCACHE_READONLY=1; fi
- test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh
- ./configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false)
- make distdir PACKAGE=bitcoin VERSION=$HOST
@@ -68,7 +75,7 @@ script:
- ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false)
- make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false )
- export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib
- if [ "$RUN_TESTS" = "true" ]; then make check; fi
- if [ "$RUN_TESTS" = "true" ]; then make $MAKEJOBS check VERBOSE=1; fi
- if [ "$RUN_TESTS" = "true" ]; then qa/pull-tester/rpc-tests.py --coverage; fi
after_script:
- if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then (echo "Upload goes here. Something like: scp -r $BASE_OUTDIR server" || echo "upload failed"); fi

View File

@@ -95,6 +95,8 @@ Anyone may participate in peer review which is expressed by comments in the pull
- Concept ACK means "I agree in the general principle of this pull request";
- Nit refers to trivial, often non-blocking issues.
Reviewers should include the commit hash which they reviewed in their comments.
Project maintainers reserve the right to weigh the opinions of peer reviewers using common sense judgement and also may weight based on meritocracy: Those that have demonstrated a deeper commitment and understanding towards the project (over time) or have clear domain expertise may naturally have more weight, as one would expect in all walks of life.
Where a patch set affects consensus critical code, the bar will be set much higher in terms of discussion and peer review requirements, keeping in mind that mistakes could be very costly to the wider community. This includes refactoring of consensus critical code.

View File

@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2009-2015 The Bitcoin Core developers
Copyright (c) 2009-2016 The Bitcoin Core developers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -26,6 +26,9 @@ OSX_QT_TRANSLATIONS = da,de,es,hu,ru,uk,zh_CN,zh_TW
DIST_DOCS = $(wildcard doc/*.md) $(wildcard doc/release-notes/*.md)
BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \
$(top_srcdir)/contrib/devtools/security-check.py
WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \
$(top_srcdir)/share/pixmaps/nsis-header.bmp \
$(top_srcdir)/share/pixmaps/nsis-wizard.bmp \
@@ -213,7 +216,7 @@ endif
dist_noinst_SCRIPTS = autogen.sh
EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.py qa/rpc-tests $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING)
EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.py qa/rpc-tests $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) $(BIN_CHECKS)
CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER)

View File

@@ -3,7 +3,7 @@ Bitcoin Core integration/staging tree
[![Build Status](https://travis-ci.org/bitcoin/bitcoin.svg?branch=master)](https://travis-ci.org/bitcoin/bitcoin)
https://www.bitcoin.org
https://bitcoincore.org
What is Bitcoin?
----------------
@@ -15,13 +15,14 @@ out collectively by the network. Bitcoin Core is the name of open source
software which enables the use of this currency.
For more information, as well as an immediately useable, binary version of
the Bitcoin Core software, see https://www.bitcoin.org/en/download.
the Bitcoin Core software, see https://bitcoin.org/en/download, or read the
[original whitepaper](https://bitcoincore.org/bitcoin.pdf).
License
-------
Bitcoin Core is released under the terms of the MIT license. See [COPYING](COPYING) for more
information or see http://opensource.org/licenses/MIT.
information or see https://opensource.org/licenses/MIT.
Development Process
-------------------
@@ -54,10 +55,10 @@ submit new unit tests for old code. Unit tests can be compiled and run
There are also [regression and integration tests](/qa) of the RPC interface, written
in Python, that are run automatically on the build server.
These tests can be run with: `qa/pull-tester/rpc-tests.py`
These tests can be run (if the [test dependencies](/qa) are installed) with: `qa/pull-tester/rpc-tests.py`
The Travis CI system makes sure that every pull request is built for Windows
and Linux, OSX, and that unit and sanity tests are automatically run.
and Linux, OS X, and that unit and sanity tests are automatically run.
### Manual Quality Assurance (QA) Testing

View File

@@ -384,7 +384,7 @@ AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG],[
dnl qt version is set to 'auto' and the preferred version wasn't found. Now try the other.
if test x$have_qt = xno && test x$bitcoin_qt_want_version = xauto; then
if test x$auto_priority_version = x$qt5; then
if test x$auto_priority_version = xqt5; then
PKG_CHECK_MODULES([QT], [$qt4_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt; bitcoin_qt_got_major_vers=4], [have_qt=no])
else
PKG_CHECK_MODULES([QT], [$qt5_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt5; bitcoin_qt_got_major_vers=5], [have_qt=no])

View File

@@ -1,11 +1,11 @@
dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N)
AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 0)
define(_CLIENT_VERSION_MINOR, 11)
define(_CLIENT_VERSION_REVISION, 99)
define(_CLIENT_VERSION_MINOR, 12)
define(_CLIENT_VERSION_REVISION, 1)
define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_IS_RELEASE, false)
define(_COPYRIGHT_YEAR, 2015)
define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2016)
AC_INIT([Bitcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/bitcoin/bitcoin/issues],[bitcoin])
AC_CONFIG_SRCDIR([src/main.cpp])
AC_CONFIG_HEADERS([src/config/bitcoin-config.h])
@@ -64,6 +64,8 @@ AC_PATH_PROG([GIT], [git])
AC_PATH_PROG(CCACHE,ccache)
AC_PATH_PROG(XGETTEXT,xgettext)
AC_PATH_PROG(HEXDUMP,hexdump)
AC_PATH_TOOL(READELF, readelf)
AC_PATH_TOOL(CPPFILT, c++filt)
dnl pkg-config check.
PKG_PROG_PKG_CONFIG
@@ -92,6 +94,11 @@ AC_ARG_ENABLE(tests,
[use_tests=$enableval],
[use_tests=yes])
AC_ARG_ENABLE(gui-tests,
AS_HELP_STRING([--disable-gui-tests],[do not compile GUI tests (default is to compile if GUI and tests enabled)]),
[use_gui_tests=$enableval],
[use_gui_tests=$use_tests])
AC_ARG_ENABLE(bench,
AS_HELP_STRING([--disable-bench],[do not compile benchmarks (default is to compile)]),
[use_bench=$enableval],
@@ -245,7 +252,7 @@ case $host in
fi
CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB"
LEVELDB_TARGET_FLAGS="TARGET_OS=OS_WINDOWS_CROSSCOMPILE"
LEVELDB_TARGET_FLAGS="-DOS_WINDOWS"
if test "x$CXXFLAGS_overridden" = "xno"; then
CXXFLAGS="$CXXFLAGS -w"
fi
@@ -267,7 +274,7 @@ case $host in
;;
*darwin*)
TARGET_OS=darwin
LEVELDB_TARGET_FLAGS="TARGET_OS=Darwin"
LEVELDB_TARGET_FLAGS="-DOS_MACOSX"
if test x$cross_compiling != xyes; then
BUILD_OS=darwin
AC_CHECK_PROG([PORT],port, port)
@@ -330,8 +337,11 @@ case $host in
;;
*linux*)
TARGET_OS=linux
LEVELDB_TARGET_FLAGS="-DOS_LINUX"
;;
*)
OTHER_OS=`echo ${host_os} | awk '{print toupper($0)}'`
LEVELDB_TARGET_FLAGS="-DOS_${OTHER_OS}"
;;
esac
@@ -409,6 +419,10 @@ AX_GCC_FUNC_ATTRIBUTE([dllimport])
if test x$use_glibc_compat != xno; then
#glibc absorbed clock_gettime in 2.17. librt (its previous location) is safe to link
#in anyway for back-compat.
AC_CHECK_LIB([rt],[clock_gettime],, AC_MSG_ERROR(lib missing))
#__fdelt_chk's params and return type have changed from long unsigned int to long int.
# See which one is present here.
AC_MSG_CHECKING(__fdelt_chk type)
@@ -422,7 +436,8 @@ if test x$use_glibc_compat != xno; then
[ fdelt_type="long int"])
AC_MSG_RESULT($fdelt_type)
AC_DEFINE_UNQUOTED(FDELT_TYPE, $fdelt_type,[parameter and return value type for __fdelt_chk])
else
AC_SEARCH_LIBS([clock_gettime],[rt])
fi
if test x$TARGET_OS != xwindows; then
@@ -489,8 +504,6 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]],
[ AC_MSG_RESULT(no)]
)
AC_SEARCH_LIBS([clock_gettime],[rt])
AC_MSG_CHECKING([for visibility attribute])
AC_LINK_IFELSE([AC_LANG_SOURCE([
int foo_def( void ) __attribute__((visibility("default")));
@@ -513,6 +526,18 @@ if test x$use_reduce_exports = xyes; then
[AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])])
fi
dnl This can go away when we require c++11
TEMP_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS -std=c++0x"
AC_MSG_CHECKING(for c++11 atomics)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <atomic>
]],[[]])],
[ AC_MSG_RESULT(yes); LEVELDB_ATOMIC_CPPFLAGS="-DLEVELDB_ATOMIC_PRESENT"; LEVELDB_ATOMIC_CXXFLAGS="-std=c++0x"],
[ AC_MSG_RESULT(no)]
)
CXXFLAGS="$TEMP_CXXFLAGS"
LEVELDB_CPPFLAGS=
LIBLEVELDB=
LIBMEMENV=
@@ -827,8 +852,8 @@ else
fi
dnl these are only used when qt is enabled
BUILD_TEST_QT=""
if test x$bitcoin_enable_qt != xno; then
BUILD_QT=qt
dnl enable dbus support
AC_MSG_CHECKING([whether to build GUI with support for D-Bus])
if test x$bitcoin_enable_qt_dbus != xno; then
@@ -858,9 +883,9 @@ if test x$bitcoin_enable_qt != xno; then
fi
AC_MSG_CHECKING([whether to build test_bitcoin-qt])
if test x$use_tests$bitcoin_enable_qt_test = xyesyes; then
if test x$use_gui_tests$bitcoin_enable_qt_test = xyesyes; then
AC_MSG_RESULT([yes])
BUILD_TEST_QT="test"
BUILD_TEST_QT="yes"
else
AC_MSG_RESULT([no])
fi
@@ -871,9 +896,10 @@ AM_CONDITIONAL([ENABLE_ZMQ], [test "x$use_zmq" = "xyes"])
AC_MSG_CHECKING([whether to build test_bitcoin])
if test x$use_tests = xyes; then
AC_MSG_RESULT([yes])
BUILD_TEST="test"
BUILD_TEST="yes"
else
AC_MSG_RESULT([no])
BUILD_TEST=""
fi
AC_MSG_CHECKING([whether to reduce exports])
@@ -891,15 +917,16 @@ AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin])
AM_CONDITIONAL([BUILD_DARWIN], [test x$BUILD_OS = xdarwin])
AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows])
AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet = xyes])
AM_CONDITIONAL([ENABLE_TESTS],[test x$use_tests = xyes])
AM_CONDITIONAL([ENABLE_TESTS],[test x$BUILD_TEST = xyes])
AM_CONDITIONAL([ENABLE_QT],[test x$bitcoin_enable_qt = xyes])
AM_CONDITIONAL([ENABLE_QT_TESTS],[test x$use_tests$bitcoin_enable_qt_test = xyesyes])
AM_CONDITIONAL([ENABLE_QT_TESTS],[test x$BUILD_TEST_QT = xyes])
AM_CONDITIONAL([ENABLE_BENCH],[test x$use_bench = xyes])
AM_CONDITIONAL([USE_QRCODE], [test x$use_qr = xyes])
AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes])
AM_CONDITIONAL([USE_COMPARISON_TOOL],[test x$use_comparison_tool != xno])
AM_CONDITIONAL([USE_COMPARISON_TOOL_REORG_TESTS],[test x$use_comparison_tool_reorg_test != xno])
AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes])
AM_CONDITIONAL([HARDEN],[test x$use_hardening = xyes])
AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version])
AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version])
@@ -926,11 +953,10 @@ AC_SUBST(USE_QRCODE)
AC_SUBST(BOOST_LIBS)
AC_SUBST(TESTDEFS)
AC_SUBST(LEVELDB_TARGET_FLAGS)
AC_SUBST(BUILD_TEST)
AC_SUBST(BUILD_QT)
AC_SUBST(BUILD_TEST_QT)
AC_SUBST(MINIUPNPC_CPPFLAGS)
AC_SUBST(MINIUPNPC_LIBS)
AC_SUBST(LEVELDB_ATOMIC_CPPFLAGS)
AC_SUBST(LEVELDB_ATOMIC_CXXFLAGS)
AC_CONFIG_FILES([Makefile src/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py])
AC_CONFIG_FILES([qa/pull-tester/run-bitcoind-for-test.sh],[chmod +x qa/pull-tester/run-bitcoind-for-test.sh])
AC_CONFIG_FILES([qa/pull-tester/tests_config.py],[chmod +x qa/pull-tester/tests_config.py])

View File

@@ -23,7 +23,7 @@ Build-Depends: debhelper,
libprotobuf-dev, protobuf-compiler,
python
Standards-Version: 3.9.2
Homepage: https://www.bitcoin.org/
Homepage: https://bitcoincore.org/
Vcs-Git: git://github.com/bitcoin/bitcoin.git
Vcs-Browser: https://github.com/bitcoin/bitcoin

View File

@@ -5,7 +5,7 @@ Upstream-Contact: Satoshi Nakamoto <satoshin@gmx.com>
Source: https://github.com/bitcoin/bitcoin
Files: *
Copyright: 2009-2015, Bitcoin Core Developers
Copyright: 2009-2016, Bitcoin Core Developers
License: Expat
Comment: The Bitcoin Core Developers encompasses the current developers listed on bitcoin.org,
as well as the numerous contributors to the project.

View File

@@ -1,4 +1,4 @@
.TH BITCOIN-CLI "1" "February 2015" "bitcoin-cli 0.10"
.TH BITCOIN-CLI "1" "February 2016" "bitcoin-cli 0.12"
.SH NAME
bitcoin-cli \- a remote procedure call client for Bitcoin Core.
.SH SYNOPSIS
@@ -11,31 +11,7 @@ This manual page documents the bitcoin-cli program. bitcoin-cli is an RPC client
.SH OPTIONS
.TP
\fB\-?\fR
Show the help message.
.TP
\fB\-conf=\fR<file>
Specify configuration file (default: bitcoin.conf).
.TP
\fB\-datadir=\fR<dir>
Specify data directory.
.TP
\fB\-testnet\fR
Connect to a Bitcoin Core instance running in testnet mode.
.TP
\fB\-regtest\fR
Connect to a Bitcoin Core instance running in regtest mode (see documentation for -regtest on bitcoind).
.TP
\fB\-rpcuser=\fR<user>
Username for JSON\-RPC connections.
.TP
\fB\-rpcpassword=\fR<pw>
Password for JSON\-RPC connections.
.TP
\fB\-rpcport=\fR<port>
Listen for JSON\-RPC connections on <port> (default: 8332 or testnet: 18332).
.TP
\fB\-rpcconnect=\fR<ip>
Send commands to node running on <ip> (default: 127.0.0.1).
Show possible options.
.SH "SEE ALSO"
\fBbitcoind\fP, \fBbitcoin.conf\fP

View File

@@ -1,4 +1,4 @@
.TH BITCOIN-QT "1" "April 2013" "bitcoin-qt 1"
.TH BITCOIN-QT "1" "February 2016" "bitcoin-qt 0.12"
.SH NAME
bitcoin-qt \- peer-to-peer network based digital currency
.SH DESCRIPTION
@@ -8,184 +8,6 @@ bitcoin\-qt [command\-line options]
.SH OPTIONS
.TP
\-?
This help message
.TP
\fB\-conf=\fR<file>
Specify configuration file (default: bitcoin.conf)
.TP
\fB\-pid=\fR<file>
Specify pid file (default: bitcoind.pid)
.TP
\fB\-gen\fR
Generate coins
.TP
\fB\-gen\fR=\fI0\fR
Don't generate coins
.TP
\fB\-datadir=\fR<dir>
Specify data directory
.TP
\fB\-dbcache=\fR<n>
Set database cache size in megabytes (default: 25)
.TP
\fB\-timeout=\fR<n>
Specify connection timeout in milliseconds (default: 5000)
.TP
\fB\-proxy=\fR<ip:port>
Connect through SOCKS5 proxy
.TP
\fB\-tor=\fR<ip:port>
Use proxy to reach tor hidden services (default: same as \fB\-proxy\fR)
.TP
\fB\-dns\fR
Allow DNS lookups for \fB\-addnode\fR, \fB\-seednode\fR and \fB\-connect\fR
.TP
\fB\-port=\fR<port>
Listen for connections on <port> (default: 8333 or testnet: 18333)
.TP
\fB\-maxconnections=\fR<n>
Maintain at most <n> connections to peers (default: 125)
.TP
\fB\-addnode=\fR<ip>
Add a node to connect to and attempt to keep the connection open
.TP
\fB\-connect=\fR<ip>
Connect only to the specified node(s)
.TP
\fB\-seednode=\fR<ip>
Connect to a node to retrieve peer addresses, and disconnect
.TP
\fB\-externalip=\fR<ip>
Specify your own public address
.TP
\fB\-onlynet=\fR<net>
Only connect to nodes in network <net> (IPv4, IPv6 or Tor)
.TP
\fB\-discover\fR
Discover own IP address (default: 1 when listening and no \fB\-externalip\fR)
.TP
\fB\-checkpoints\fR
Only accept block chain matching built\-in checkpoints (default: 1)
.TP
\fB\-listen\fR
Accept connections from outside (default: 1 if no \fB\-proxy\fR or \fB\-connect\fR)
.TP
\fB\-bind=\fR<addr>
Bind to given address and always listen on it. Use [host]:port notation for IPv6
.TP
\fB\-dnsseed\fR
Find peers using DNS lookup (default: 1 unless \fB\-connect\fR)
.TP
\fB\-banscore=\fR<n>
Threshold for disconnecting misbehaving peers (default: 100)
.TP
\fB\-bantime=\fR<n>
Number of seconds to keep misbehaving peers from reconnecting (default: 86400)
.TP
\fB\-maxreceivebuffer=\fR<n>
Maximum per\-connection receive buffer, <n>*1000 bytes (default: 5000)
.TP
\fB\-maxsendbuffer=\fR<n>
Maximum per\-connection send buffer, <n>*1000 bytes (default: 1000)
.TP
\fB\-upnp\fR
Use UPnP to map the listening port (default: 1 when listening)
.TP
\fB\-paytxfee=\fR<amt>
Fee per KB to add to transactions you send
.TP
\fB\-server\fR
Accept command line and JSON\-RPC commands
.TP
\fB\-testnet\fR
Use the test network
.TP
\fB\-debug\fR
Output extra debugging information. Implies all other \fB\-debug\fR* options
.TP
\fB\-debugnet\fR
Output extra network debugging information
.TP
\fB\-logtimestamps\fR
Prepend debug output with timestamp
.TP
\fB\-shrinkdebugfile\fR
Shrink debug.log file on client startup (default: 1 when no \fB\-debug\fR)
.TP
\fB\-printtoconsole\fR
Send trace/debug info to console instead of debug.log file
.TP
\fB\-rpcuser=\fR<user>
Username for JSON\-RPC connections
.TP
\fB\-rpcpassword=\fR<pw>
Password for JSON\-RPC connections
.TP
\fB\-rpcport=\fR<port>
Listen for JSON\-RPC connections on <port> (default: 8332 or testnet: 18332)
.TP
\fB\-rpcallowip=\fR<ip>
Allow JSON\-RPC connections from specified IP address
.TP
\fB\-rpcthreads=\fR<n>
Set the number of threads to service RPC calls (default: 4)
.TP
\fB\-blocknotify=\fR<cmd>
Execute command when the best block changes (%s in cmd is replaced by block hash)
.TP
\fB\-walletnotify=\fR<cmd>
Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)
.TP
\fB\-alertnotify=\fR<cmd>
Execute command when a relevant alert is received (%s in cmd is replaced by message)
.TP
\fB\-upgradewallet\fR
Upgrade wallet to latest format
.TP
\fB\-keypool=\fR<n>
Set key pool size to <n> (default: 100)
.TP
\fB\-rescan\fR
Rescan the block chain for missing wallet transactions
.TP
\fB\-salvagewallet\fR
Attempt to recover private keys from a corrupt wallet.dat
.TP
\fB\-checkblocks=\fR<n>
How many blocks to check at startup (default: 288, 0 = all)
.TP
\fB\-checklevel=\fR<n>
How thorough the block verification is (0\-4, default: 3)
.TP
\fB\-txindex\fR
Maintain a full transaction index (default: 0)
.TP
\fB\-loadblock=\fR<file>
Imports blocks from external blk000??.dat file
.TP
\fB\-reindex\fR
Rebuild block chain index from current blk000??.dat files
.TP
\fB\-par=\fR<n>
Set the number of script verification threads (1\-16, 0=auto, default: 0)
.SS "Block creation options:"
.TP
\fB\-blockminsize=\fR<n>
Set minimum block size in bytes (default: 0)
.TP
\fB\-blockmaxsize=\fR<n>
Set maximum block size in bytes (default: 250000)
.HP
\fB\-blockprioritysize=\fR<n> Set maximum size of high\-priority/low\-fee transactions in bytes (default: 27000)
.PP
Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)
.SS "UI options:"
.TP
\fB\-lang=\fR<lang>
Set language, for example "de_DE" (default: system locale)
.TP
\fB\-min\fR
Start minimized
.TP
\fB\-splash\fR
Show splash screen on startup (default: 1)
List options.
.SH "SEE ALSO"
bitcoind(1)

View File

@@ -1,75 +1,15 @@
.TH BITCOIN.CONF "5" "January 2011" "bitcoin.conf 3.19"
.TH BITCOIN.CONF "5" "February 2016" "bitcoin.conf 0.12"
.SH NAME
bitcoin.conf \- bitcoin configuration file
.SH SYNOPSIS
All command-line options (except for '\-conf') may be specified in a configuration file, and all configuration file options may also be specified on the command line. Command-line options override values set in the configuration file.
.TP
The configuration file is a list of 'setting=value' pairs, one per line, with optional comments starting with the '#' character.
The configuration file is a list of 'setting=value' pairs, one per line, with optional comments starting with the '#' character. Please refer to bitcoind(1) for a up to date list of valid options.
.TP
The configuration file is not automatically created; you can create it using your favorite plain-text editor. By default, bitcoind(1) will look for a file named bitcoin.conf(5) in the bitcoin data directory, but both the data directory and the configuration file path may be changed using the '\-datadir' and '\-conf' command-line arguments.
.SH LOCATION
bitcoin.conf should be located in $HOME/.bitcoin
.SH NETWORK-RELATED SETTINGS
.TP
.TP
\fBtestnet=\fR[\fI'1'\fR|\fI'0'\fR]
Enable or disable run on the test network instead of the real *bitcoin* network.
.TP
\fBproxy=\fR\fI'127.0.0.1:9050'\fR
Connect via a socks4 proxy.
.TP
\fBaddnode=\fR\fI'10.0.0.2:8333'\fR
Use as many *addnode=* settings as you like to connect to specific peers.
.TP
\fBconnect=\fR\fI'10.0.0.1:8333'\fR
Use as many *connect=* settings as you like to connect ONLY to specific peers.
.TP
\fRmaxconnections=\fR\fI'value'\fR
Maximum number of inbound+outbound connections.
.SH JSON-RPC OPTIONS
.TP
\fBserver=\fR[\fI'1'\fR|\fI'0'\fR]
Tells *bitcoin* to accept or not accept JSON-RPC commands.
.TP
\fBrpcuser=\fR\fI'username'\fR
You must set *rpcuser* to secure the JSON-RPC api.
.TP
\fBrpcpassword=\fR\fI'password'\fR
You must set *rpcpassword* to secure the JSON-RPC api.
.TP
\fBrpcallowip=\fR\fI'192.168.1.*'\fR
By default, only RPC connections from localhost are allowed. Specify as many *rpcallowip=* settings as you like to allow connections from other hosts (and you may use * as a wildcard character).
.TP
\fBrpcport=\fR\fI'8332'\fR
Listen for RPC connections on this TCP port.
.TP
\fBrpcconnect=\fR\fI'127.0.0.1'\fR
You can use *bitcoin* or *bitcoind(1)* to send commands to *bitcoin*/*bitcoind(1)* running on another host using this option.
.TP
.SH MISCELLANEOUS OPTIONS
.TP
\fBgen=\fR[\fI'0'\fR|\fI'1'\fR]
Enable or disable attempt to generate bitcoins.
.TP
\fB4way=\fR[\fI'0'\fR|\fI'1'\fR]
Enable or disable use SSE instructions to try to generate bitcoins faster.
.TP
\fBkeypool=\fR\fI'100'\fR
Pre-generate this many public/private key pairs, so wallet backups will be valid for both prior transactions and several dozen future transactions.
.TP
\fBpaytxfee=\fR\fI'0.00'\fR
Pay an optional transaction fee every time you send bitcoins. Transactions with fees are more likely than free transactions to be included in generated blocks, so may be validated sooner.
.TP
\fBallowreceivebyip=\fR\fI'1'\fR
Allow direct connections for the 'pay via IP address' feature.
.TP
.SH USER INTERFACE OPTIONS
.TP
\fBmin=\fR[\fI'0'\fR|\fI'1'\fR]
Enable or disable start bitcoind minimized.
.TP
\fBminimizetotray=\fR[\fI'0'\fR|\fI'1'\fR]
Enable or disable minimize to the system tray.
.SH "SEE ALSO"
bitcoind(1)
.SH AUTHOR

View File

@@ -1,4 +1,4 @@
.TH BITCOIND "1" "January 2011" "bitcoind 3.19"
.TH BITCOIND "1" "February 2016" "bitcoind 0.12"
.SH NAME
bitcoind \- peer-to-peer network based digital currency
.SH SYNOPSIS
@@ -6,185 +6,20 @@ bitcoin [options] <command> [params]
.TP
bitcoin [options] help <command> \- Get help for a command
.SH DESCRIPTION
This manual page documents the bitcoind program. Bitcoin is a peer-to-peer digital currency. Peer-to-peer (P2P) means that there is no central authority to issue new money or keep track of transactions. Instead, these tasks are managed collectively by the nodes of the network. Advantages:
Bitcoins can be sent easily through the Internet, without having to trust middlemen. Transactions are designed to be irreversible. Be safe from instability caused by fractional reserve banking and central banks. The limited inflation of the Bitcoin systems money supply is distributed evenly (by CPU power) throughout the network, not monopolized by banks.
This manual page documents the bitcoind program. Bitcoin is an experimental new digital currency that enables instant payments to anyone, anywhere in the world. Bitcoin uses peer-to-peer technology to operate with no central authority: managing transactions and issuing money are carried out collectively by the network. Bitcoin Core is the name of open source software which enables the use of this currency.
.SH OPTIONS
.TP
\fB\-conf=\fR<file>
Specify configuration file (default: bitcoin.conf)
.TP
\fB\-gen\fR
Generate coins
.TP
\fB\-gen\fR=\fI0\fR
Don't generate coins
.TP
\fB\-min\fR
Start minimized
.TP
\fB\-datadir=\fR<dir>
Specify data directory
.TP
\fB\-proxy=\fR<ip:port>
Connect through SOCKS5 proxy
.TP
\fB\-addnode=\fR<ip>
Add a node to connect to
.TP
\fB\-connect=\fR<ip>
Connect only to the specified node
.TP
\fB\-paytxfee=\fR<amt>
Fee per KB to add to transactions you send
.TP
\fB\-server\fR
Accept command line and JSON\-RPC commands
.TP
\fB\-daemon\fR
Run in the background as a daemon and accept commands
.TP
\fB\-testnet\fR
Use the test network
.TP
\fB\-rpcuser=\fR<user>
Username for JSON\-RPC connections
.TP
\fB\-rpcpassword=\fR<pw>
Password for JSON\-RPC connections
.TP
\fB\-rpcport=\fR<port>
Listen for JSON\-RPC connections on <port>
.TP
\fB\-rpcallowip=\fR<ip>
Allow JSON\-RPC connections from specified IP address
.TP
\fB\-rpcconnect=\fR<ip>
Send commands to node running on <ip>
.TP
\-?
This help message
List of possible options.
.SH COMMANDS
.TP
\fBbackupwallet 'destination'\fR
Safely copies *wallet.dat* to 'destination', which can be a directory or a path with filename.
.TP
\fBgetaccount 'bitcoinaddress'\fR
DEPRECATED. Returns the account associated with the given address.
.TP
\fBsetaccount 'bitcoinaddress' ['account']\fR
DEPRECATED. Sets the ['account'] associated with the given address. ['account'] may be omitted to remove an address from ['account'].
.TP
\fBgetaccountaddress 'account'\fR
DEPRECATED. Returns a new bitcoin address for 'account'.
.TP
\fBgetaddressesbyaccount 'account'\fR
DEPRECATED. Returns the list of addresses associated with the given 'account'.
.TP
\fBgetbalance 'account'\fR
Returns the server's available balance, or the balance for 'account' (accounts are deprecated).
.TP
\fBgetblockcount\fR
Returns the number of blocks in the longest block chain.
.TP
\fBgetblocknumber\fR
Returns the block number of the latest block in the longest block chain.
.TP
\fBgetconnectioncount\fR
Returns the number of connections to other nodes.
.TP
\fBgetdifficulty\fR
Returns the proof-of-work difficulty as a multiple of the minimum difficulty.
.TP
\fBgetgenerate\fR
Returns boolean true if server is trying to generate bitcoins, false otherwise.
.TP
\fBsetgenerate 'generate' ['genproclimit']\fR
Generation is limited to ['genproclimit'] processors, \-1 is unlimited.
.TP
\fBgethashespersec\fR
Returns a recent hashes per second performance measurement while generating.
.TP
\fBgetinfo\fR
Returns an object containing server information.
.TP
\fBgetnewaddress 'account'\fR
Returns a new bitcoin address for receiving payments. If 'account' is specified (deprecated), it is added to the address book so payments received with the address will be credited to 'account'.
.TP
\fBgetreceivedbyaccount 'account' ['minconf=1']\fR
DEPRECATED. Returns the total amount received by addresses associated with 'account' in transactions with at least ['minconf'] confirmations.
.TP
\fBgetreceivedbyaddress 'bitcoinaddress' ['minconf=1']\fR
Returns the total amount received by 'bitcoinaddress' in transactions with at least ['minconf'] confirmations.
.TP
\fBgettransaction 'txid'\fR
Returns information about a specific transaction, given hexadecimal transaction ID.
.TP
\fBgetwork 'data'\fR
If 'data' is specified, tries to solve the block and returns true if it was successful. If 'data' is not specified, returns formatted hash 'data' to work on:
\fBhelp\fR
List commands.
"midstate" : precomputed hash state after hashing the first half of the data.
"data" : block data.
"hash1" : formatted hash buffer for second hash.
"target" : little endian hash target.
.TP
\fBhelp 'command'\fR
List commands, or get help for a command.
.TP
\fBlistaccounts ['minconf=1']\fR
DEPRECATED. List accounts and their current balances.
*note: requires bitcoin 0.3.20 or later.
.TP
\fBlistreceivedbyaccount ['minconf=1'] ['includeempty=false']\fR
['minconf'] is the minimum number of confirmations before payments are included. ['includeempty'] whether to include addresses that haven't received any payments. Returns an array of objects containing:
"account" : DEPRECATED. the account of the receiving address.
"amount" : total amount received by the address.
"confirmations" : number of confirmations of the most recent transaction included.
.TP
\fBlistreceivedbyaddress ['minconf=1'] ['includeempty=false']\fR
['minconf'] is the minimum number of confirmations before payments are included. ['includeempty'] whether to include addresses that haven't received any payments. Returns an array of objects containing:
"address" : receiving address.
"account" : DEPRECATED. the account of the receiving address.
"amount" : total amount received by the address.
"confirmations" : number of confirmations of the most recent transaction included.
.TP
\fBlisttransactions 'account' ['count=10']\fR
Returns a list of the last ['count'] transactions for 'account' \- for all accounts if 'account' is not specified or is "*". Each entry in the list may contain:
"category" : will be generate, send, receive, or move.
"amount" : amount of transaction.
"fee" : Fee (if any) paid (only for send transactions).
"confirmations" : number of confirmations (only for generate/send/receive).
"txid" : transaction ID (only for generate/send/receive).
"otheraccount" : account funds were moved to or from (only for move).
"message" : message associated with transaction (only for send).
"to" : message-to associated with transaction (only for send).
*note: requires bitcoin 0.3.20 or later.
.TP
\fBmove <'fromaccount'> <'toaccount'> <'amount'> ['minconf=1'] ['comment']\fR
DEPRECATED. Moves funds between accounts.
.TP
\fBsendfrom* <'account'> <'bitcoinaddress'> <'amount'> ['minconf=1'] ['comment'] ['comment-to']\fR
DEPRECATED. Sends amount from account's balance to 'bitcoinaddress'. This method will fail if there is less than amount bitcoins with ['minconf'] confirmations in the account's balance (unless account is the empty-string-named default account; it behaves like the *sendtoaddress* method). Returns transaction ID on success.
.TP
\fBsendtoaddress 'bitcoinaddress' 'amount' ['comment'] ['comment-to']\fR
Sends amount from the server's available balance to 'bitcoinaddress'. amount is a real and is rounded to the nearest 0.01. Returns transaction id on success.
.TP
\fBstop\fR
Stops the bitcoin server.
.TP
\fBvalidateaddress 'bitcoinaddress'\fR
Checks that 'bitcoinaddress' looks like a proper bitcoin address. Returns an object containing:
"isvalid" : true or false.
"ismine" : true if the address is in the server's wallet.
"address" : bitcoinaddress.
*note: ismine and address are only returned if the address is valid.
Get help for a command.
.SH "SEE ALSO"
bitcoin.conf(5)

View File

@@ -11,16 +11,16 @@ fix-copyright-headers.py
========================
Every year newly updated files need to have its copyright headers updated to reflect the current year.
If you run this script from src/ it will automatically update the year on the copyright header for all
.cpp and .h files if these have a git commit from the current year.
If you run this script from the root folder it will automatically update the year on the copyright header for all
source files if these have a git commit from the current year.
For example a file changed in 2014 (with 2014 being the current year):
For example a file changed in 2015 (with 2015 being the current year):
```// Copyright (c) 2009-2013 The Bitcoin Core developers```
would be changed to:
```// Copyright (c) 2009-2014 The Bitcoin Core developers```
```// Copyright (c) 2009-2015 The Bitcoin Core developers```
git-subtree-check.sh
====================

View File

@@ -1,53 +1,46 @@
#!/usr/bin/env python
'''
Run this script inside of src/ and it will look for all the files
that were changed this year that still have the last year in the
copyright headers, and it will fix the headers on that file using
a perl regex one liner.
Run this script to update all the copyright headers of files
that were changed this year.
For example: if it finds something like this and we're in 2014
For example:
// Copyright (c) 2009-2013 The Bitcoin Core developers
// Copyright (c) 2009-2012 The Bitcoin Core developers
it will change it to
// Copyright (c) 2009-2014 The Bitcoin Core developers
It will do this for all the files in the folder and its children.
Author: @gubatron
// Copyright (c) 2009-2015 The Bitcoin Core developers
'''
import os
import time
import re
year = time.gmtime()[0]
last_year = year - 1
command = "perl -pi -e 's/%s The Bitcoin/%s The Bitcoin/' %s"
listFilesCommand = "find . | grep %s"
CMD_GIT_DATE = 'git log --format=@%%at -1 %s | date +"%%Y" -u -f -'
CMD_REGEX= "perl -pi -e 's/(20\d\d)(?:-20\d\d)? The Bitcoin/$1-%s The Bitcoin/' %s"
REGEX_CURRENT= re.compile("%s The Bitcoin" % year)
CMD_LIST_FILES= "find %s | grep %s"
extensions = [".cpp",".h"]
FOLDERS = ["./qa", "./src"]
EXTENSIONS = [".cpp",".h", ".py"]
def getLastGitModifiedDate(filePath):
gitGetLastCommitDateCommand = "git log " + filePath +" | grep Date | head -n 1"
p = os.popen(gitGetLastCommitDateCommand)
result = ""
for l in p:
result = l
break
result = result.replace("\n","")
return result
def get_git_date(file_path):
r = os.popen(CMD_GIT_DATE % file_path)
for l in r:
# Result is one line, so just return
return l.replace("\n","")
return ""
n=1
for extension in extensions:
foundFiles = os.popen(listFilesCommand % extension)
for filePath in foundFiles:
filePath = filePath[1:-1]
if filePath.endswith(extension):
filePath = os.getcwd() + filePath
modifiedTime = getLastGitModifiedDate(filePath)
if len(modifiedTime) > 0 and str(year) in modifiedTime:
print n,"Last Git Modified: ", modifiedTime, " - ", filePath
os.popen(command % (last_year,year,filePath))
n = n + 1
for folder in FOLDERS:
for extension in EXTENSIONS:
for file_path in os.popen(CMD_LIST_FILES % (folder, extension)):
file_path = os.getcwd() + file_path[1:-1]
if file_path.endswith(extension):
git_date = get_git_date(file_path)
if str(year) == git_date:
# Only update if current year is not found
if REGEX_CURRENT.search(open(file_path, "r").read()) is None:
print n,"Last git edit", git_date, "-", file_path
os.popen(CMD_REGEX % (year,file_path))
n = n + 1

View File

@@ -94,7 +94,7 @@ def check_ELF_RELRO(executable):
raise IOError('Error opening file')
for line in stdout.split('\n'):
tokens = line.split()
if len(tokens)>1 and tokens[1] == '(BIND_NOW)':
if len(tokens)>1 and tokens[1] == '(BIND_NOW)' or (len(tokens)>2 and tokens[1] == '(FLAGS)' and 'BIND_NOW' in tokens[2]):
have_bindnow = True
return have_gnu_relro and have_bindnow

View File

@@ -42,9 +42,12 @@ MAX_VERSIONS = {
'GLIBCXX': (3,4,13),
'GLIBC': (2,11)
}
# See here for a description of _IO_stdin_used:
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=634261#109
# Ignore symbols that are exported as part of every executable
IGNORE_EXPORTS = {
'_edata', '_end', '_init', '__bss_start', '_fini'
'_edata', '_end', '_init', '__bss_start', '_fini', '_IO_stdin_used'
}
READELF_CMD = os.getenv('READELF', '/usr/bin/readelf')
CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt')

View File

@@ -72,7 +72,7 @@ def sanitize_string(s):
'''Sanitize string for printing'''
return s.replace('\n',' ')
def check_format_specifiers(source, translation, errors):
def check_format_specifiers(source, translation, errors, numerus):
source_f = split_format_specifiers(find_format_specifiers(source))
# assert that no source messages contain both Qt and strprintf format specifiers
# if this fails, go change the source as this is hacky and confusing!
@@ -80,10 +80,13 @@ def check_format_specifiers(source, translation, errors):
try:
translation_f = split_format_specifiers(find_format_specifiers(translation))
except IndexError:
errors.append("Parse error in translation '%s'" % sanitize_string(translation))
errors.append("Parse error in translation for '%s': '%s'" % (sanitize_string(source), sanitize_string(translation)))
return False
else:
if source_f != translation_f:
if numerus and source_f == (set(), ['n']) and translation_f == (set(), []) and translation.find('%') == -1:
# Allow numerus translations to omit %n specifier (usually when it only has one possible value)
return True
errors.append("Mismatch between '%s' and '%s'" % (sanitize_string(source), sanitize_string(translation)))
return False
return True
@@ -150,7 +153,7 @@ def postprocess_translations(reduce_diff_hacks=False):
if translation is None:
continue
errors = []
valid = check_format_specifiers(source, translation, errors)
valid = check_format_specifiers(source, translation, errors, numerus)
for error in errors:
print('%s: %s' % (filename, error))

View File

@@ -6,6 +6,7 @@ suites:
architectures:
- "amd64"
packages:
- "curl"
- "g++-multilib"
- "git-core"
- "pkg-config"
@@ -15,7 +16,9 @@ packages:
- "faketime"
- "bsdmainutils"
- "binutils-gold"
reference_datetime: "2015-06-01 00:00:00"
- "ca-certificates"
- "python"
reference_datetime: "2016-01-01 00:00:00"
remotes:
- "url": "https://github.com/bitcoin/bitcoin.git"
"dir": "bitcoin"
@@ -23,7 +26,7 @@ files: []
script: |
WRAP_DIR=$HOME/wrapped
HOSTS="i686-pc-linux-gnu x86_64-unknown-linux-gnu"
CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++"
CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests LDFLAGS=-static-libstdc++"
FAKETIME_HOST_PROGS=""
FAKETIME_PROGS="date ar ranlib nm strip"
@@ -94,6 +97,8 @@ script: |
./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS}
make ${MAKEOPTS}
make ${MAKEOPTS} -C src check-security
make ${MAKEOPTS} -C src check-symbols
make install-strip
cd installed
find . -name "lib*.la" -delete

View File

@@ -5,9 +5,8 @@ suites:
architectures:
- "amd64"
packages:
- "libc6:i386"
- "faketime"
reference_datetime: "2015-06-01 00:00:00"
reference_datetime: "2016-01-01 00:00:00"
remotes:
- "url": "https://github.com/bitcoin/bitcoin-detached-sigs.git"
"dir": "signature"
@@ -34,5 +33,5 @@ script: |
tar -xf ${UNSIGNED}
./detached-sig-apply.sh ${UNSIGNED} signature/osx
${WRAP_DIR}/genisoimage -no-cache-inodes -D -l -probe -V "Bitcoin-Core" -no-pad -r -apple -o uncompressed.dmg signed-app
${WRAP_DIR}/genisoimage -no-cache-inodes -D -l -probe -V "Bitcoin-Core" -no-pad -r -dir-mode 0755 -apple -o uncompressed.dmg signed-app
${WRAP_DIR}/dmg dmg uncompressed.dmg ${OUTDIR}/${SIGNED}

View File

@@ -6,6 +6,7 @@ suites:
architectures:
- "amd64"
packages:
- "curl"
- "g++"
- "git-core"
- "pkg-config"
@@ -18,7 +19,9 @@ packages:
- "libcap-dev"
- "libz-dev"
- "libbz2-dev"
reference_datetime: "2015-06-01 00:00:00"
- "ca-certificates"
- "python"
reference_datetime: "2016-01-01 00:00:00"
remotes:
- "url": "https://github.com/bitcoin/bitcoin.git"
"dir": "bitcoin"
@@ -27,7 +30,7 @@ files:
script: |
WRAP_DIR=$HOME/wrapped
HOSTS="x86_64-apple-darwin11"
CONFIGFLAGS="--enable-reduce-exports GENISOIMAGE=$WRAP_DIR/genisoimage"
CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests GENISOIMAGE=$WRAP_DIR/genisoimage"
FAKETIME_HOST_PROGS=""
FAKETIME_PROGS="ar ranlib date dmg genisoimage"

View File

@@ -7,7 +7,7 @@ architectures:
packages:
- "libssl-dev"
- "autoconf"
reference_datetime: "2015-06-01 00:00:00"
reference_datetime: "2016-01-01 00:00:00"
remotes:
- "url": "https://github.com/bitcoin/bitcoin-detached-sigs.git"
"dir": "signature"

View File

@@ -6,6 +6,7 @@ suites:
architectures:
- "amd64"
packages:
- "curl"
- "g++"
- "git-core"
- "pkg-config"
@@ -18,7 +19,9 @@ packages:
- "g++-mingw-w64"
- "nsis"
- "zip"
reference_datetime: "2015-06-01 00:00:00"
- "ca-certificates"
- "python"
reference_datetime: "2016-01-01 00:00:00"
remotes:
- "url": "https://github.com/bitcoin/bitcoin.git"
"dir": "bitcoin"
@@ -26,7 +29,7 @@ files: []
script: |
WRAP_DIR=$HOME/wrapped
HOSTS="x86_64-w64-mingw32 i686-w64-mingw32"
CONFIGFLAGS="--enable-reduce-exports"
CONFIGFLAGS="--enable-reduce-exports --disable-gui-tests"
FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip"
FAKETIME_PROGS="date makensis zip"
@@ -124,6 +127,7 @@ script: |
./configure --prefix=${BASEPREFIX}/${i} --bindir=${INSTALLPATH}/bin --includedir=${INSTALLPATH}/include --libdir=${INSTALLPATH}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS}
make ${MAKEOPTS}
make ${MAKEOPTS} -C src check-security
make deploy
make install-strip
cp -f bitcoin-*setup*.exe $OUTDIR/

View File

@@ -3,6 +3,9 @@
Utility to generate the seeds.txt list that is compiled into the client
(see [src/chainparamsseeds.h](/src/chainparamsseeds.h) and other utilities in [contrib/seeds](/contrib/seeds)).
The 512 seeds compiled into the 0.10 release were created from sipa's DNS seed data, like this:
The seeds compiled into the release are created from sipa's DNS seed data, like this:
curl -s http://bitcoin.sipa.be/seeds.txt > seeds_main.txt
python makeseeds.py < seeds_main.txt > nodes_main.txt
python generate-seeds.py . > ../../src/chainparamsseeds.h
curl -s http://bitcoin.sipa.be/seeds.txt | makeseeds.py

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
### Verify SF Binaries ###
### Verify Binaries ###
This script attempts to download the signature file `SHA256SUMS.asc` from https://bitcoin.org.
It first checks if the signature passes, and then downloads the files specified in the file, and checks if the hashes of these files match those that are specified in the signature file.
The script returns 0 if everything passes the checks. It returns 1 if either the signature check or the hash check doesn't pass. If an error occurs the return value is 2.
The script returns 0 if everything passes the checks. It returns 1 if either the signature check or the hash check doesn't pass. If an error occurs the return value is 2.

View File

@@ -7,7 +7,7 @@ build_darwin_OTOOL: = $(shell xcrun -f otool)
build_darwin_NM: = $(shell xcrun -f nm)
build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool)
build_darwin_SHA256SUM = shasum -a 256
build_darwin_DOWNLOAD = curl --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -L -o
build_darwin_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o
#darwin host on darwin builder. overrides darwin host preferences.
darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION)

View File

@@ -1,2 +1,2 @@
build_linux_SHA256SUM = sha256sum
build_linux_DOWNLOAD = wget --timeout=$(DOWNLOAD_CONNECT_TIMEOUT) --tries=$(DOWNLOAD_RETRIES) -nv -O
build_linux_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o

View File

@@ -2,7 +2,7 @@
# Attempt to guess a canonical system name.
# Copyright 1992-2015 Free Software Foundation, Inc.
timestamp='2015-10-21'
timestamp='2015-11-19'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -1393,6 +1393,9 @@ EOF
x86_64:VMkernel:*:*)
echo ${UNAME_MACHINE}-unknown-esx
exit ;;
amd64:Isilon\ OneFS:*:*)
echo x86_64-unknown-onefs
exit ;;
esac
cat >&2 <<EOF

8
depends/config.sub vendored
View File

@@ -2,7 +2,7 @@
# Configuration validation subroutine script.
# Copyright 1992-2015 Free Software Foundation, Inc.
timestamp='2015-08-20'
timestamp='2015-11-22'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -53,8 +53,7 @@ timestamp='2015-08-20'
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS
$0 [OPTION] ALIAS
Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
Canonicalize a configuration name.
@@ -1399,7 +1398,8 @@ case $os in
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
| -onefs* | -tirtos*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)

View File

@@ -1,8 +1,8 @@
package=boost
$(package)_version=1_58_0
$(package)_download_path=http://sourceforge.net/projects/boost/files/boost/1.58.0
$(package)_version=1_59_0
$(package)_download_path=http://sourceforge.net/projects/boost/files/boost/1.59.0
$(package)_file_name=$(package)_$($(package)_version).tar.bz2
$(package)_sha256_hash=fdfc204fc33ec79c99b9a74944c3e54bd78be4f7f15e260c0e2700a36dc7d3e5
$(package)_sha256_hash=727a932322d94287b62abb1bd2d41723eec4356a7728909e38adb65ca25241ca
define $(package)_set_vars
$(package)_config_opts_release=variant=release

View File

@@ -1,12 +1,12 @@
package=miniupnpc
$(package)_version=1.9.20151008
$(package)_version=1.9.20151026
$(package)_download_path=http://miniupnp.free.fr/files
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=e444ac3b587ce82709c4d0cfca1fe71f44f9fc433e9f946b12b9e1bfe667a633
$(package)_sha256_hash=f3cf9a5a31588a917d4d9237e5bc50f84d00c5aa48e27ed50d9b88dfa6a25d47
define $(package)_set_vars
$(package)_build_opts=CC="$($(package)_cc)"
$(package)_build_opts_darwin=OS=Darwin
$(package)_build_opts_darwin=OS=Darwin LIBTOOL="$($(package)_libtool)"
$(package)_build_opts_mingw32=-f Makefile.mingw
$(package)_build_env+=CFLAGS="$($(package)_cflags) $($(package)_cppflags)" AR="$($(package)_ar)"
endef

View File

@@ -1,8 +1,8 @@
package=native_ccache
$(package)_version=3.2.3
$(package)_version=3.2.4
$(package)_download_path=http://samba.org/ftp/ccache
$(package)_file_name=ccache-$($(package)_version).tar.bz2
$(package)_sha256_hash=b07165d4949d107d17f2f84b90b52953617bf1abbf249d5cc20636f43337c98c
$(package)_sha256_hash=ffeb967edb549e67da0bd5f44f729a2022de9fdde65dfd80d2a7204d7f75332e
define $(package)_set_vars
$(package)_config_opts=

View File

@@ -31,7 +31,7 @@ $(package)_config_opts += -no-iconv
$(package)_config_opts += -no-gif
$(package)_config_opts += -no-freetype
$(package)_config_opts += -no-nis
$(package)_config_opts += -no-pch
$(package)_config_opts += -pch
$(package)_config_opts += -no-qml-debug
$(package)_config_opts += -nomake examples
$(package)_config_opts += -nomake tests

View File

@@ -1,8 +1,8 @@
package=zeromq
$(package)_version=4.0.4
$(package)_version=4.0.7
$(package)_download_path=http://download.zeromq.org
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=1ef71d46e94f33e27dd5a1661ed626cd39be4d2d6967792a275040e34457d399
$(package)_sha256_hash=e00b2967e074990d0538361cc79084a0a92892df2c6e7585da34e4c61ee47b03
define $(package)_set_vars
$(package)_config_opts=--without-documentation --disable-shared

View File

@@ -34,7 +34,7 @@ PROJECT_NAME = Bitcoin
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = 0.11.99
PROJECT_NUMBER = 0.12.1
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer

View File

@@ -1,4 +1,4 @@
Bitcoin Core 0.11.99
Bitcoin Core 0.12.1
=====================
Setup
@@ -11,16 +11,10 @@ The following are some helpful notes on how to run Bitcoin on your native platfo
### Unix
You need the Qt4 run-time libraries to run Bitcoin-Qt. On Debian or Ubuntu:
sudo apt-get install libqtgui4
Unpack the files into a directory and run:
- bin/32/bitcoin-qt (GUI, 32-bit) or bin/32/bitcoind (headless, 32-bit)
- bin/64/bitcoin-qt (GUI, 64-bit) or bin/64/bitcoind (headless, 64-bit)
- `bin/bitcoin-qt` (GUI) or
- `bin/bitcoind` (headless)
### Windows
@@ -49,7 +43,7 @@ The following are developer notes on how to build Bitcoin on your native platfor
Development
---------------------
The Bitcoin repo's [root README](https://github.com/bitcoin/bitcoin/blob/master/README.md) contains relevant information on the development process and automated testing.
The Bitcoin repo's [root README](/README.md) contains relevant information on the development process and automated testing.
- [Developer Notes](developer-notes.md)
- [Multiwallet Qt Development](multiwallet-qt.md)

View File

@@ -1,4 +1,4 @@
Bitcoin Core 0.11.99
Bitcoin Core 0.12.1
=====================
Intro

View File

@@ -18,4 +18,5 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.12.0**):
* [`BIP 66`](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki): The strict DER rules and associated version 3 blocks have been implemented since **v0.10.0** ([PR #5713](https://github.com/bitcoin/bitcoin/pull/5713)).
* [`BIP 70`](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) [`71`](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki) [`72`](https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki): Payment Protocol support has been available in Bitcoin Core GUI since **v0.9.0** ([PR #5216](https://github.com/bitcoin/bitcoin/pull/5216)).
* [`BIP 111`](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki): `NODE_BLOOM` service bit added, but only enforced for peer versions `>=70011` as of **v0.12.0** ([PR #6579](https://github.com/bitcoin/bitcoin/pull/6579)).
* [`BIP 125`](https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki): Opt-in full replace-by-fee signaling honoured in mempool and mining as of **v0.12.0** ([PR 6871](https://github.com/bitcoin/bitcoin/pull/6871)).
* [`BIP 130`](https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki): direct headers announcement is negotiated with peer versions `>=70012` as of **v0.12.0** ([PR 6494](https://github.com/bitcoin/bitcoin/pull/6494)).

View File

@@ -61,7 +61,7 @@ Dependency Build Instructions: Ubuntu & Debian
----------------------------------------------
Build requirements:
sudo apt-get install build-essential libtool autotools-dev autoconf pkg-config libssl-dev libevent-dev bsdmainutils
sudo apt-get install build-essential libtool autotools-dev automake pkg-config libssl-dev libevent-dev bsdmainutils
On at least Ubuntu 14.04+ and Debian 7+ there are generic names for the
individual boost development packages, so the following can be used to only
@@ -236,3 +236,31 @@ In this case there is no dependency on Berkeley DB 4.8.
Mining is also possible in disable-wallet mode, but only using the `getblocktemplate` RPC
call not `getwork`.
Additional Configure Flags
--------------------------
A list of additional configure flags can be displayed with:
./configure --help
ARM Cross-compilation
-------------------
These steps can be performed on, for example, an Ubuntu VM. The depends system
will also work on other Linux distributions, however the commands for
installing the toolchain will be different.
First install the toolchain:
sudo apt-get install g++-arm-linux-gnueabihf
To build executables for ARM:
cd depends
make HOST=arm-linux-gnueabihf NO_QT=1
cd ..
./configure --prefix=$PWD/depends/arm-linux-gnueabihf --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++
make
For further documentation on the depends system see [README.md](../depends/README.md) in the depends directory.
>>>>>>> 3e55b3a... [doc] added depends cross compile info

View File

@@ -252,22 +252,22 @@ First we need to log in as `root` to set up dependencies and make sure that our
user can use the sudo command. Type/paste the following in the terminal:
```bash
apt-get install git ruby sudo apt-cacher-ng qemu-utils debootstrap lxc python-cheetah parted kpartx bridge-utils make ubuntu-archive-keyring
apt-get install git ruby sudo apt-cacher-ng qemu-utils debootstrap lxc python-cheetah parted kpartx bridge-utils make ubuntu-archive-keyring curl
adduser debian sudo
```
Then set up LXC and the rest with the following, which is a complex jumble of settings and workarounds:
```bash
# the version of lxc-start in Debian 7.4 needs to run as root, so make sure
# the version of lxc-start in Debian needs to run as root, so make sure
# that the build script can execute it without providing a password
echo "%sudo ALL=NOPASSWD: /usr/bin/lxc-start" > /etc/sudoers.d/gitian-lxc
# add cgroup for LXC
echo "cgroup /sys/fs/cgroup cgroup defaults 0 0" >> /etc/fstab
# make /etc/rc.local script that sets up bridge between guest and host
echo '#!/bin/sh -e' > /etc/rc.local
echo 'brctl addbr br0' >> /etc/rc.local
echo 'ifconfig br0 10.0.3.2/24 up' >> /etc/rc.local
echo 'iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE' >> /etc/rc.local
echo 'echo 1 > /proc/sys/net/ipv4/ip_forward' >> /etc/rc.local
echo 'exit 0' >> /etc/rc.local
# make sure that USE_LXC is always set when logging in as debian,
# and configure LXC IP addresses

View File

@@ -1,239 +1,47 @@
(note: this is a temporary file, to be added-to by anybody, and moved to
release-notes at release time)
Bitcoin Core version 0.12.2 is now available from:
<https://bitcoin.org/bin/bitcoin-core-0.12.2/>
This is a new minor version release, including ........,
various bugfixes and updated translations.
Please report bugs using the issue tracker at github:
<https://github.com/bitcoin/bitcoin/issues>
Upgrading and downgrading
=========================
How to Upgrade
--------------
If you are running an older version, shut it down. Wait until it has completely
shut down (which might take a few minutes for older versions), then run the
installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
bitcoind/bitcoin-qt (on Linux).
Downgrade warning
-----------------
### Downgrade to a version < 0.12.0
Because release 0.12.0 and later will obfuscate the chainstate on every
fresh sync or reindex, the chainstate is not backwards-compatible with
pre-0.12 versions of Bitcoin Core or other software.
If you want to downgrade after you have done a reindex with 0.12.0 or later,
you will need to reindex when you first start Bitcoin Core version 0.11 or
earlier.
Notable changes
===============
SSL support for RPC dropped
----------------------------
SSL support for RPC, previously enabled by the option `rpcssl` has been dropped
from both the client and the server. This was done in preparation for removing
the dependency on OpenSSL for the daemon completely.
Trying to use `rpcssl` will result in an error:
Error: SSL mode for RPC (-rpcssl) is no longer supported.
If you are one of the few people that relies on this feature, a flexible
migration path is to use `stunnel`. This is an utility that can tunnel
arbitrary TCP connections inside SSL. On e.g. Ubuntu it can be installed with:
sudo apt-get install stunnel4
Then, to tunnel a SSL connection on 28332 to a RPC server bound on localhost on port 18332 do:
stunnel -d 28332 -r 127.0.0.1:18332 -p stunnel.pem -P ''
It can also be set up system-wide in inetd style.
Another way to re-attain SSL would be to setup a httpd reverse proxy. This solution
would allow the use of different authentication, loadbalancing, on-the-fly compression and
caching. A sample config for apache2 could look like:
Listen 443
NameVirtualHost *:443
<VirtualHost *:443>
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
<Location /bitcoinrpc>
ProxyPass http://127.0.0.1:8332/
ProxyPassReverse http://127.0.0.1:8332/
# optional enable digest auth
# AuthType Digest
# ...
# optional bypass bitcoind rpc basic auth
# RequestHeader set Authorization "Basic <hash>"
# get the <hash> from the shell with: base64 <<< bitcoinrpc:<password>
</Location>
# Or, balance the load:
# ProxyPass / balancer://balancer_cluster_name
</VirtualHost>
Random-cookie RPC authentication
---------------------------------
When no `-rpcpassword` is specified, the daemon now uses a special 'cookie'
file for authentication. This file is generated with random content when the
daemon starts, and deleted when it exits. Its contents are used as
authentication token. Read access to this file controls who can access through
RPC. By default it is stored in the data directory but its location can be
overridden with the option `-rpccookiefile`.
This is similar to Tor's CookieAuthentication: see
https://www.torproject.org/docs/tor-manual.html.en
This allows running bitcoind without having to do any manual configuration.
Low-level RPC API changes
--------------------------
- Monetary amounts can be provided as strings. This means that for example the
argument to sendtoaddress can be "0.0001" instead of 0.0001. This can be an
advantage if a JSON library insists on using a lossy floating point type for
numbers, which would be dangerous for monetary amounts.
Option parsing behavior
-----------------------
Command line options are now parsed strictly in the order in which they are
specified. It used to be the case that `-X -noX` ends up, unintuitively, with X
set, as `-X` had precedence over `-noX`. This is no longer the case. Like for
other software, the last specified value for an option will hold.
`NODE_BLOOM` service bit
------------------------
Support for the `NODE_BLOOM` service bit, as described in [BIP
111](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki), has been
added to the P2P protocol code.
BIP 111 defines a service bit to allow peers to advertise that they support
bloom filters (such as used by SPV clients) explicitly. It also bumps the protocol
version to allow peers to identify old nodes which allow bloom filtering of the
connection despite lacking the new service bit.
In this version, it is only enforced for peers that send protocol versions
`>=70011`. For the next major version it is planned that this restriction will be
removed. It is recommended to update SPV clients to check for the `NODE_BLOOM`
service bit for nodes that report versions newer than 70011.
Any sequence of pushdatas in OP_RETURN outputs now allowed
----------------------------------------------------------
Previously OP_RETURN outputs with a payload were only relayed and mined if they
had a single pushdata. This restriction has been lifted to allow any
combination of data pushes and numeric constant opcodes (OP_1 to OP_16). The
limit on OP_RETURN output size is now applied to the entire serialized
scriptPubKey, 83 bytes by default. (the previous 80 byte default plus three
bytes overhead)
Merkle branches removed from wallet
-----------------------------------
Previously, every wallet transaction stored a Merkle branch to prove its
presence in blocks. This wasn't being used for more than an expensive
sanity check. Since 0.12, these are no longer stored. When loading a
0.12 wallet into an older version, it will automatically rescan to avoid
failed checks.
BIP65 - CHECKLOCKTIMEVERIFY
---------------------------
Previously it was impossible to create a transaction output that was guaranteed
to be unspendable until a specific date in the future. CHECKLOCKTIMEVERIFY is a
new opcode that allows a script to check if a specific block height or time has
been reached, failing the script otherwise. This enables a wide variety of new
functionality such as time-locked escrows, secure payment channels, etc.
BIP65 implements CHECKLOCKTIMEVERIFY by introducing block version 4, which adds
additional restrictions to the NOP2 opcode. The same miner-voting mechanism as
in BIP34 and BIP66 is used: when 751 out of a sequence of 1001 blocks have
version number 4 or higher, the new consensus rule becomes active for those
blocks. When 951 out of a sequence of 1001 blocks have version number 4 or
higher, it becomes mandatory for all blocks and blocks with versions less than
4 are rejected.
Bitcoin Core's block templates are now for version 4 blocks only, and any
mining software relying on its `getblocktemplate` must be updated in parallel
to use either libblkmaker version 0.4.3 or any version from 0.5.2 onward. If
you are solo mining, this will affect you the moment you upgrade Bitcoin Core,
which must be done prior to BIP65 achieving its 951/1001 status. If you are
mining with the stratum mining protocol: this does not affect you. If you are
mining with the getblocktemplate protocol to a pool: this will affect you at
the pool operator's discretion, which must be no later than BIP65 achieving its
951/1001 status.
Automatically use Tor hidden services
-------------------------------------
Starting with Tor version 0.2.7.1 it is possible, through Tor's control socket
API, to create and destroy 'ephemeral' hidden services programmatically.
Bitcoin Core has been updated to make use of this.
This means that if Tor is running (and proper authorization is available),
Bitcoin Core automatically creates a hidden service to listen on, without
manual configuration. Bitcoin Core will also use Tor automatically to connect
to other .onion nodes if the control socket can be successfully opened. This
will positively affect the number of available .onion nodes and their usage.
This new feature is enabled by default if Bitcoin Core is listening, and
a connection to Tor can be made. It can be configured with the `-listenonion`,
`-torcontrol` and `-torpassword` settings. To show verbose debugging
information, pass `-debug=tor`.
Reduce upload traffic
---------------------
A major part of the outbound traffic is caused by serving historic blocks to
other nodes in initial block download state.
It is now possible to reduce the total upload traffic via the `-maxuploadtarget`
parameter. This is *not* a hard limit but a threshold to minimize the outbound
traffic. When the limit is about to be reached, the uploaded data is cut by not
serving historic blocks (blocks older than one week).
Moreover, any SPV peer is disconnected when they request a filtered block.
This option can be specified in MiB per day and is turned off by default
(`-maxuploadtarget=0`).
The recommended minimum is 144 * MAX_BLOCK_SIZE (currently 144MB) per day.
Whitelisted peers will never be disconnected, although their traffic counts for
calculating the target.
A more detailed documentation about keeping traffic low can be found in
[/doc/reducetraffic.md](/doc/reducetraffic.md).
Signature validation using libsecp256k1
Example item
---------------------------------------
ECDSA signatures inside Bitcoin transactions now use validation using
[https://github.com/bitcoin/secp256k1](libsecp256k1) instead of OpenSSL.
Example text.
Depending on the platform, this means a significant speedup for raw signature
validation speed. The advantage is largest on x86_64, where validation is over
five times faster. In practice, this translates to a raw reindexing and new
block validation times that are less than half of what it was before.
Libsecp256k1 has undergone very extensive testing and validation.
A side effect of this change is that libconsensus no longer depends on OpenSSL.
Direct headers announcement (BIP 130)
-------------------------------------
Between compatible peers, BIP 130 direct headers announcement is used. This
means that blocks are advertized by announcing their headers directly, instead
of just announcing the hash. In a reorganization, all new headers are sent,
instead of just the new tip. This can often prevent an extra roundtrip before
the actual block is downloaded.
Negative confirmations and conflict detection
---------------------------------------------
The wallet will now report a negative number for confirmations that indicates
how deep in the block chain the conflict is found. For example, if a transaction
A has 5 confirmations and spends the same input as a wallet transaction B, B
will be reported as having -5 confirmations. If another wallet transaction C
spends an output from B, it will also be reported as having -5 confirmations.
To detect conflicts with historical transactions in the chain a one-time
`-rescan` may be needed.
Unlike earlier versions, unconfirmed but non-conflicting transactions will never
get a negative confirmation count. They are not treated as spendable unless
they're coming from ourself (change) and accepted into our local mempool,
however. The new "trusted" field in the `listtransactions` RPC output
indicates whether outputs of an unconfirmed transaction are considered
spendable.
0.12.0 Change log
0.12.1 Change log
=================
Detailed release notes follow. This overview includes changes that affect
@@ -243,33 +51,23 @@ git merge commit are mentioned.
### RPC and REST
Asm representations of scriptSig signatures now contain SIGHASH type decodes
----------------------------------------------------------------------------
Asm script outputs replacements for OP_NOP2 and OP_NOP3
-------------------------------------------------------
The `asm` property of each scriptSig now contains the decoded signature hash
type for each signature that provides a valid defined hash type.
OP_NOP2 has been renamed to OP_CHECKLOCKTIMEVERIFY by [BIP
65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki)
The following items contain assembly representations of scriptSig signatures
and are affected by this change:
OP_NOP3 has been renamed to OP_CHECKSEQUENCEVERIFY by [BIP
112](https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki)
- RPC `getrawtransaction`
The following outputs are affected by this change:
- RPC `getrawtransaction` (in verbose mode)
- RPC `decoderawtransaction`
- RPC `decodescript`
- REST `/rest/tx/` (JSON format)
- REST `/rest/block/` (JSON format when including extended tx details)
- `bitcoin-tx -json`
For example, the `scriptSig.asm` property of a transaction input that
previously showed an assembly representation of:
304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c509001
now shows as:
304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090[ALL]
Note that the output of the RPC `decodescript` did not change because it is
configured specifically to process scriptPubKey and not scriptSig scripts.
### Configuration and command-line options
### Block and transaction handling
@@ -284,17 +82,16 @@ configured specifically to process scriptPubKey and not scriptSig scripts.
### GUI
### Tests
### Tests and QA
### Miscellaneous
- Removed bitrpc.py from contrib
Credits
=======
Thanks to everyone who directly contributed to this release:
As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).
Addition of ZMQ-based Notifications
==================================
Bitcoind can now (optionally) asynchronously notify clients through a
ZMQ-based PUB socket of the arrival of new transactions and blocks.
This feature requires installation of the ZMQ C API library 4.x and
configuring its use through the command line or configuration file.
Please see docs/zmq.md for details of operation.

View File

@@ -0,0 +1,891 @@
Bitcoin Core version 0.12.0 is now available from:
<https://bitcoin.org/bin/bitcoin-core-0.12.0/>
This is a new major version release, bringing new features and other improvements.
Please report bugs using the issue tracker at github:
<https://github.com/bitcoin/bitcoin/issues>
Upgrading and downgrading
=========================
How to Upgrade
--------------
If you are running an older version, shut it down. Wait until it has completely
shut down (which might take a few minutes for older versions), then run the
installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
bitcoind/bitcoin-qt (on Linux).
Downgrade warning
-----------------
### Downgrade to a version < 0.10.0
Because release 0.10.0 and later makes use of headers-first synchronization and
parallel block download (see further), the block files and databases are not
backwards-compatible with pre-0.10 versions of Bitcoin Core or other software:
* Blocks will be stored on disk out of order (in the order they are
received, really), which makes it incompatible with some tools or
other programs. Reindexing using earlier versions will also not work
anymore as a result of this.
* The block index database will now hold headers for which no block is
stored on disk, which earlier versions won't support.
If you want to be able to downgrade smoothly, make a backup of your entire data
directory. Without this your node will need start syncing (or importing from
bootstrap.dat) anew afterwards. It is possible that the data from a completely
synchronised 0.10 node may be usable in older versions as-is, but this is not
supported and may break as soon as the older version attempts to reindex.
This does not affect wallet forward or backward compatibility.
### Downgrade to a version < 0.12.0
Because release 0.12.0 and later will obfuscate the chainstate on every
fresh sync or reindex, the chainstate is not backwards-compatible with
pre-0.12 versions of Bitcoin Core or other software.
If you want to downgrade after you have done a reindex with 0.12.0 or later,
you will need to reindex when you first start Bitcoin Core version 0.11 or
earlier.
Notable changes
===============
Signature validation using libsecp256k1
---------------------------------------
ECDSA signatures inside Bitcoin transactions now use validation using
[libsecp256k1](https://github.com/bitcoin-core/secp256k1) instead of OpenSSL.
Depending on the platform, this means a significant speedup for raw signature
validation speed. The advantage is largest on x86_64, where validation is over
five times faster. In practice, this translates to a raw reindexing and new
block validation times that are less than half of what it was before.
Libsecp256k1 has undergone very extensive testing and validation.
A side effect of this change is that libconsensus no longer depends on OpenSSL.
Reduce upload traffic
---------------------
A major part of the outbound traffic is caused by serving historic blocks to
other nodes in initial block download state.
It is now possible to reduce the total upload traffic via the `-maxuploadtarget`
parameter. This is *not* a hard limit but a threshold to minimize the outbound
traffic. When the limit is about to be reached, the uploaded data is cut by not
serving historic blocks (blocks older than one week).
Moreover, any SPV peer is disconnected when they request a filtered block.
This option can be specified in MiB per day and is turned off by default
(`-maxuploadtarget=0`).
The recommended minimum is 144 * MAX_BLOCK_SIZE (currently 144MB) per day.
Whitelisted peers will never be disconnected, although their traffic counts for
calculating the target.
A more detailed documentation about keeping traffic low can be found in
[/doc/reduce-traffic.md](/doc/reduce-traffic.md).
Direct headers announcement (BIP 130)
-------------------------------------
Between compatible peers, [BIP 130]
(https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki)
direct headers announcement is used. This means that blocks are advertised by
announcing their headers directly, instead of just announcing the hash. In a
reorganization, all new headers are sent, instead of just the new tip. This
can often prevent an extra roundtrip before the actual block is downloaded.
With this change, pruning nodes are now able to relay new blocks to compatible
peers.
Memory pool limiting
--------------------
Previous versions of Bitcoin Core had their mempool limited by checking
a transaction's fees against the node's minimum relay fee. There was no
upper bound on the size of the mempool and attackers could send a large
number of transactions paying just slighly more than the default minimum
relay fee to crash nodes with relatively low RAM. A temporary workaround
for previous versions of Bitcoin Core was to raise the default minimum
relay fee.
Bitcoin Core 0.12 will have a strict maximum size on the mempool. The
default value is 300 MB and can be configured with the `-maxmempool`
parameter. Whenever a transaction would cause the mempool to exceed
its maximum size, the transaction that (along with in-mempool descendants) has
the lowest total feerate (as a package) will be evicted and the node's effective
minimum relay feerate will be increased to match this feerate plus the initial
minimum relay feerate. The initial minimum relay feerate is set to
1000 satoshis per kB.
Bitcoin Core 0.12 also introduces new default policy limits on the length and
size of unconfirmed transaction chains that are allowed in the mempool
(generally limiting the length of unconfirmed chains to 25 transactions, with a
total size of 101 KB). These limits can be overriden using command line
arguments; see the extended help (`--help -help-debug`) for more information.
Opt-in Replace-by-fee transactions
----------------------------------
It is now possible to replace transactions in the transaction memory pool of
Bitcoin Core 0.12 nodes. Bitcoin Core will only allow replacement of
transactions which have any of their inputs' `nSequence` number set to less
than `0xffffffff - 1`. Moreover, a replacement transaction may only be
accepted when it pays sufficient fee, as described in [BIP 125]
(https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki).
Transaction replacement can be disabled with a new command line option,
`-mempoolreplacement=0`. Transactions signaling replacement under BIP125 will
still be allowed into the mempool in this configuration, but replacements will
be rejected. This option is intended for miners who want to continue the
transaction selection behavior of previous releases.
The `-mempoolreplacement` option is *not recommended* for wallet users seeking
to avoid receipt of unconfirmed opt-in transactions, because this option does
not prevent transactions which are replaceable under BIP 125 from being accepted
(only subsequent replacements, which other nodes on the network that implement
BIP 125 are likely to relay and mine). Wallet users wishing to detect whether
a transaction is subject to replacement under BIP 125 should instead use the
updated RPC calls `gettransaction` and `listtransactions`, which now have an
additional field in the output indicating if a transaction is replaceable under
BIP125 ("bip125-replaceable").
Note that the wallet in Bitcoin Core 0.12 does not yet have support for
creating transactions that would be replaceable under BIP 125.
RPC: Random-cookie RPC authentication
-------------------------------------
When no `-rpcpassword` is specified, the daemon now uses a special 'cookie'
file for authentication. This file is generated with random content when the
daemon starts, and deleted when it exits. Its contents are used as
authentication token. Read access to this file controls who can access through
RPC. By default it is stored in the data directory but its location can be
overridden with the option `-rpccookiefile`.
This is similar to Tor's CookieAuthentication: see
https://www.torproject.org/docs/tor-manual.html.en
This allows running bitcoind without having to do any manual configuration.
Relay: Any sequence of pushdatas in OP_RETURN outputs now allowed
-----------------------------------------------------------------
Previously OP_RETURN outputs with a payload were only relayed and mined if they
had a single pushdata. This restriction has been lifted to allow any
combination of data pushes and numeric constant opcodes (OP_1 to OP_16) after
the OP_RETURN. The limit on OP_RETURN output size is now applied to the entire
serialized scriptPubKey, 83 bytes by default. (the previous 80 byte default plus
three bytes overhead)
Relay and Mining: Priority transactions
---------------------------------------
Bitcoin Core has a heuristic 'priority' based on coin value and age. This
calculation is used for relaying of transactions which do not pay the
minimum relay fee, and can be used as an alternative way of sorting
transactions for mined blocks. Bitcoin Core will relay transactions with
insufficient fees depending on the setting of `-limitfreerelay=<r>` (default:
`r=15` kB per minute) and `-blockprioritysize=<s>`.
In Bitcoin Core 0.12, when mempool limit has been reached a higher minimum
relay fee takes effect to limit memory usage. Transactions which do not meet
this higher effective minimum relay fee will not be relayed or mined even if
they rank highly according to the priority heuristic.
The mining of transactions based on their priority is also now disabled by
default. To re-enable it, simply set `-blockprioritysize=<n>` where is the size
in bytes of your blocks to reserve for these transactions. The old default was
50k, so to retain approximately the same policy, you would set
`-blockprioritysize=50000`.
Additionally, as a result of computational simplifications, the priority value
used for transactions received with unconfirmed inputs is lower than in prior
versions due to avoiding recomputing the amounts as input transactions confirm.
External miner policy set via the `prioritisetransaction` RPC to rank
transactions already in the mempool continues to work as it has previously.
Note, however, that if mining priority transactions is left disabled, the
priority delta will be ignored and only the fee metric will be effective.
This internal automatic prioritization handling is being considered for removal
entirely in Bitcoin Core 0.13, and it is at this time undecided whether the
more accurate priority calculation for chained unconfirmed transactions will be
restored. Community direction on this topic is particularly requested to help
set project priorities.
Automatically use Tor hidden services
-------------------------------------
Starting with Tor version 0.2.7.1 it is possible, through Tor's control socket
API, to create and destroy 'ephemeral' hidden services programmatically.
Bitcoin Core has been updated to make use of this.
This means that if Tor is running (and proper authorization is available),
Bitcoin Core automatically creates a hidden service to listen on, without
manual configuration. Bitcoin Core will also use Tor automatically to connect
to other .onion nodes if the control socket can be successfully opened. This
will positively affect the number of available .onion nodes and their usage.
This new feature is enabled by default if Bitcoin Core is listening, and
a connection to Tor can be made. It can be configured with the `-listenonion`,
`-torcontrol` and `-torpassword` settings. To show verbose debugging
information, pass `-debug=tor`.
Notifications through ZMQ
-------------------------
Bitcoind can now (optionally) asynchronously notify clients through a
ZMQ-based PUB socket of the arrival of new transactions and blocks.
This feature requires installation of the ZMQ C API library 4.x and
configuring its use through the command line or configuration file.
Please see [docs/zmq.md](/doc/zmq.md) for details of operation.
Wallet: Transaction fees
------------------------
Various improvements have been made to how the wallet calculates
transaction fees.
Users can decide to pay a predefined fee rate by setting `-paytxfee=<n>`
(or `settxfee <n>` rpc during runtime). A value of `n=0` signals Bitcoin
Core to use floating fees. By default, Bitcoin Core will use floating
fees.
Based on past transaction data, floating fees approximate the fees
required to get into the `m`th block from now. This is configurable
with `-txconfirmtarget=<m>` (default: `2`).
Sometimes, it is not possible to give good estimates, or an estimate
at all. Therefore, a fallback value can be set with `-fallbackfee=<f>`
(default: `0.0002` BTC/kB).
At all times, Bitcoin Core will cap fees at `-maxtxfee=<x>` (default:
0.10) BTC.
Furthermore, Bitcoin Core will never create transactions paying less than
the current minimum relay fee.
Finally, a user can set the minimum fee rate for all transactions with
`-mintxfee=<i>`, which defaults to 1000 satoshis per kB.
Wallet: Negative confirmations and conflict detection
-----------------------------------------------------
The wallet will now report a negative number for confirmations that indicates
how deep in the block chain the conflict is found. For example, if a transaction
A has 5 confirmations and spends the same input as a wallet transaction B, B
will be reported as having -5 confirmations. If another wallet transaction C
spends an output from B, it will also be reported as having -5 confirmations.
To detect conflicts with historical transactions in the chain a one-time
`-rescan` may be needed.
Unlike earlier versions, unconfirmed but non-conflicting transactions will never
get a negative confirmation count. They are not treated as spendable unless
they're coming from ourself (change) and accepted into our local mempool,
however. The new "trusted" field in the `listtransactions` RPC output
indicates whether outputs of an unconfirmed transaction are considered
spendable.
Wallet: Merkle branches removed
-------------------------------
Previously, every wallet transaction stored a Merkle branch to prove its
presence in blocks. This wasn't being used for more than an expensive
sanity check. Since 0.12, these are no longer stored. When loading a
0.12 wallet into an older version, it will automatically rescan to avoid
failed checks.
Wallet: Pruning
---------------
With 0.12 it is possible to use wallet functionality in pruned mode.
This can reduce the disk usage from currently around 60 GB to
around 2 GB.
However, rescans as well as the RPCs `importwallet`, `importaddress`,
`importprivkey` are disabled.
To enable block pruning set `prune=<N>` on the command line or in
`bitcoin.conf`, where `N` is the number of MiB to allot for
raw block & undo data.
A value of 0 disables pruning. The minimal value above 0 is 550. Your
wallet is as secure with high values as it is with low ones. Higher
values merely ensure that your node will not shut down upon blockchain
reorganizations of more than 2 days - which are unlikely to happen in
practice. In future releases, a higher value may also help the network
as a whole: stored blocks could be served to other nodes.
For further information about pruning, you may also consult the [release
notes of v0.11.0](https://github.com/bitcoin/bitcoin/blob/v0.11.0/doc/release-notes.md#block-file-pruning).
`NODE_BLOOM` service bit
------------------------
Support for the `NODE_BLOOM` service bit, as described in [BIP
111](https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki), has been
added to the P2P protocol code.
BIP 111 defines a service bit to allow peers to advertise that they support
bloom filters (such as used by SPV clients) explicitly. It also bumps the protocol
version to allow peers to identify old nodes which allow bloom filtering of the
connection despite lacking the new service bit.
In this version, it is only enforced for peers that send protocol versions
`>=70011`. For the next major version it is planned that this restriction will be
removed. It is recommended to update SPV clients to check for the `NODE_BLOOM`
service bit for nodes that report versions newer than 70011.
Option parsing behavior
-----------------------
Command line options are now parsed strictly in the order in which they are
specified. It used to be the case that `-X -noX` ends up, unintuitively, with X
set, as `-X` had precedence over `-noX`. This is no longer the case. Like for
other software, the last specified value for an option will hold.
RPC: Low-level API changes
--------------------------
- Monetary amounts can be provided as strings. This means that for example the
argument to sendtoaddress can be "0.0001" instead of 0.0001. This can be an
advantage if a JSON library insists on using a lossy floating point type for
numbers, which would be dangerous for monetary amounts.
* The `asm` property of each scriptSig now contains the decoded signature hash
type for each signature that provides a valid defined hash type.
* OP_NOP2 has been renamed to OP_CHECKLOCKTIMEVERIFY by [BIP 65](https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki)
The following items contain assembly representations of scriptSig signatures
and are affected by this change:
- RPC `getrawtransaction`
- RPC `decoderawtransaction`
- RPC `decodescript`
- REST `/rest/tx/` (JSON format)
- REST `/rest/block/` (JSON format when including extended tx details)
- `bitcoin-tx -json`
For example, the `scriptSig.asm` property of a transaction input that
previously showed an assembly representation of:
304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c509001 400000 OP_NOP2
now shows as:
304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090[ALL] 400000 OP_CHECKLOCKTIMEVERIFY
Note that the output of the RPC `decodescript` did not change because it is
configured specifically to process scriptPubKey and not scriptSig scripts.
RPC: SSL support dropped
------------------------
SSL support for RPC, previously enabled by the option `rpcssl` has been dropped
from both the client and the server. This was done in preparation for removing
the dependency on OpenSSL for the daemon completely.
Trying to use `rpcssl` will result in an error:
Error: SSL mode for RPC (-rpcssl) is no longer supported.
If you are one of the few people that relies on this feature, a flexible
migration path is to use `stunnel`. This is an utility that can tunnel
arbitrary TCP connections inside SSL. On e.g. Ubuntu it can be installed with:
sudo apt-get install stunnel4
Then, to tunnel a SSL connection on 28332 to a RPC server bound on localhost on port 18332 do:
stunnel -d 28332 -r 127.0.0.1:18332 -p stunnel.pem -P ''
It can also be set up system-wide in inetd style.
Another way to re-attain SSL would be to setup a httpd reverse proxy. This solution
would allow the use of different authentication, loadbalancing, on-the-fly compression and
caching. A sample config for apache2 could look like:
Listen 443
NameVirtualHost *:443
<VirtualHost *:443>
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/server.crt
SSLCertificateKeyFile /etc/apache2/ssl/server.key
<Location /bitcoinrpc>
ProxyPass http://127.0.0.1:8332/
ProxyPassReverse http://127.0.0.1:8332/
# optional enable digest auth
# AuthType Digest
# ...
# optional bypass bitcoind rpc basic auth
# RequestHeader set Authorization "Basic <hash>"
# get the <hash> from the shell with: base64 <<< bitcoinrpc:<password>
</Location>
# Or, balance the load:
# ProxyPass / balancer://balancer_cluster_name
</VirtualHost>
Mining Code Changes
-------------------
The mining code in 0.12 has been optimized to be significantly faster and use less
memory. As part of these changes, consensus critical calculations are cached on a
transaction's acceptance into the mempool and the mining code now relies on the
consistency of the mempool to assemble blocks. However all blocks are still tested
for validity after assembly.
Other P2P Changes
-----------------
The list of banned peers is now stored on disk rather than in memory.
Restarting bitcoind will no longer clear out the list of banned peers; instead
a new RPC call (`clearbanned`) can be used to manually clear the list. The new
`setban` RPC call can also be used to manually ban or unban a peer.
0.12.0 Change log
=================
Detailed release notes follow. This overview includes changes that affect
behavior, not code moves, refactors and string updates. For convenience in locating
the code changes and accompanying discussion, both the pull request and
git merge commit are mentioned.
### RPC and REST
- #6121 `466f0ea` Convert entire source tree from json_spirit to UniValue (Jonas Schnelli)
- #6234 `d38cd47` fix rpcmining/getblocktemplate univalue transition logic error (Jonas Schnelli)
- #6239 `643114f` Don't go through double in AmountFromValue and ValueFromAmount (Wladimir J. van der Laan)
- #6266 `ebab5d3` Fix univalue handling of \u0000 characters. (Daniel Kraft)
- #6276 `f3d4dbb` Fix getbalance * 0 (Tom Harding)
- #6257 `5ebe7db` Add `paytxfee` and `errors` JSON fields where appropriate (Stephen)
- #6271 `754aae5` New RPC command disconnectnode (Alex van der Peet)
- #6158 `0abfa8a` Add setban/listbanned RPC commands (Jonas Schnelli)
- #6307 `7ecdcd9` rpcban fixes (Jonas Schnelli)
- #6290 `5753988` rpc: make `gettxoutsettinfo` run lock-free (Wladimir J. van der Laan)
- #6262 `247b914` Return all available information via RPC call "validateaddress" (dexX7)
- #6339 `c3f0490` UniValue: don't escape solidus, keep espacing of reverse solidus (Jonas Schnelli)
- #6353 `6bcb0a2` Show softfork status in getblockchaininfo (Wladimir J. van der Laan)
- #6247 `726e286` Add getblockheader RPC call (Peter Todd)
- #6362 `d6db115` Fix null id in RPC response during startup (Forrest Voight)
- #5486 `943b322` [REST] JSON support for /rest/headers (Jonas Schnelli)
- #6379 `c52e8b3` rpc: Accept scientific notation for monetary amounts in JSON (Wladimir J. van der Laan)
- #6388 `fd5dfda` rpc: Implement random-cookie based authentication (Wladimir J. van der Laan)
- #6457 `3c923e8` Include pruned state in chaininfo.json (Simon Males)
- #6456 `bfd807f` rpc: Avoid unnecessary parsing roundtrip in number formatting, fix locale issue (Wladimir J. van der Laan)
- #6380 `240b30e` rpc: Accept strings in AmountFromValue (Wladimir J. van der Laan)
- #6346 `6bb2805` Add OP_RETURN support in createrawtransaction RPC call, add tests. (paveljanik)
- #6013 `6feeec1` [REST] Add memory pool API (paveljanik)
- #6576 `da9beb2` Stop parsing JSON after first finished construct. (Daniel Kraft)
- #5677 `9aa9099` libevent-based http server (Wladimir J. van der Laan)
- #6633 `bbc2b39` Report minimum ping time in getpeerinfo (Matt Corallo)
- #6648 `cd381d7` Simplify logic of REST request suffix parsing. (Daniel Kraft)
- #6695 `5e21388` libevent http fixes (Wladimir J. van der Laan)
- #5264 `48efbdb` show scriptSig signature hash types in transaction decodes. fixes #3166 (mruddy)
- #6719 `1a9f19a` Make HTTP server shutdown more graceful (Wladimir J. van der Laan)
- #6859 `0fbfc51` http: Restrict maximum size of http + headers (Wladimir J. van der Laan)
- #5936 `bf7c195` [RPC] Add optional locktime to createrawtransaction (Tom Harding)
- #6877 `26f5b34` rpc: Add maxmempool and effective min fee to getmempoolinfo (Wladimir J. van der Laan)
- #6970 `92701b3` Fix crash in validateaddress with -disablewallet (Wladimir J. van der Laan)
- #5574 `755b4ba` Expose GUI labels in RPC as comments (Luke-Jr)
- #6990 `dbd2c13` http: speed up shutdown (Wladimir J. van der Laan)
- #7013 `36baa9f` Remove LOCK(cs_main) from decodescript (Peter Todd)
- #6999 `972bf9c` add (max)uploadtarget infos to getnettotals RPC help (Jonas Schnelli)
- #7011 `31de241` Add mediantime to getblockchaininfo (Peter Todd)
- #7065 `f91e29f` http: add Boost 1.49 compatibility (Wladimir J. van der Laan)
- #7087 `be281d8` [Net]Add -enforcenodebloom option (Patrick Strateman)
- #7044 `438ee59` RPC: Added additional config option for multiple RPC users. (Gregory Sanders)
- #7072 `c143c49` [RPC] Add transaction size to JSON output (Nikita Zhavoronkov)
- #7022 `9afbd96` Change default block priority size to 0 (Alex Morcos)
- #7141 `c0c08c7` rpc: Don't translate warning messages (Wladimir J. van der Laan)
- #7312 `fd4bd50` Add RPC call abandontransaction (Alex Morcos)
- #7222 `e25b158` RPC: indicate which transactions are replaceable (Suhas Daftuar)
- #7472 `b2f2b85` rpc: Add WWW-Authenticate header to 401 response (Wladimir J. van der Laan)
- #7469 `9cb31e6` net.h fix spelling: misbeha{b,v}ing (Matt)
### Configuration and command-line options
- #6164 `8d05ec7` Allow user to use -debug=1 to enable all debugging (lpescher)
- #5288 `4452205` Added `-whiteconnections=<n>` option (Josh Lehan)
- #6284 `10ac38e` Fix argument parsing oddity with -noX (Wladimir J. van der Laan)
- #6489 `c9c017a` Give a better error message if system clock is bad (Casey Rodarmor)
- #6462 `c384800` implement uacomment config parameter which can add comments to user agent as per BIP-0014 (Pavol Rusnak)
- #6647 `a3babc8` Sanitize uacomment (MarcoFalke)
- #6742 `3b2d37c` Changed logging to make -logtimestamps to work also for -printtoconsole (arnuschky)
- #6846 `2cd020d` alias -h for -help (Daniel Cousens)
- #6622 `7939164` Introduce -maxuploadtarget (Jonas Schnelli)
- #6881 `2b62551` Debug: Add option for microsecond precision in debug.log (Suhas Daftuar)
- #6776 `e06c14f` Support -checkmempool=N, which runs checks once every N transactions (Pieter Wuille)
- #6896 `d482c0a` Make -checkmempool=1 not fail through int32 overflow (Pieter Wuille)
- #6993 `b632145` Add -blocksonly option (Patrick Strateman)
- #7323 `a344880` 0.12: Backport -bytespersigop option (Luke-Jr)
- #7386 `da83ecd` Add option `-permitrbf` to set transaction replacement policy (Wladimir J. van der Laan)
- #7290 `b16b5bc` Add missing options help (MarcoFalke)
- #7440 `c76bfff` Rename permitrbf to mempoolreplacement and provide minimal string-list forward compatibility (Luke-Jr)
### Block and transaction handling
- #6203 `f00b623` Remove P2SH coinbase flag, no longer interesting (Luke-Jr)
- #6222 `9c93ee5` Explicitly set tx.nVersion for the genesis block and mining tests (Mark Friedenbach)
- #5985 `3a1d3e8` Fix removing of orphan transactions (Alex Morcos)
- #6221 `dd8fe82` Prune: Support noncontiguous block files (Adam Weiss)
- #6124 `41076aa` Mempool only CHECKLOCKTIMEVERIFY (BIP65) verification, unparameterized version (Peter Todd)
- #6329 `d0a10c1` acceptnonstdtxn option to skip (most) "non-standard transaction" checks, for testnet/regtest only (Luke-Jr)
- #6410 `7cdefb9` Implement accurate memory accounting for mempool (Pieter Wuille)
- #6444 `24ce77d` Exempt unspendable transaction outputs from dust checks (dexX7)
- #5913 `a0625b8` Add absurdly high fee message to validation state (Shaul Kfir)
- #6177 `2f746c6` Prevent block.nTime from decreasing (Mark Friedenbach)
- #6377 `e545371` Handle no chain tip available in InvalidChainFound() (Ross Nicoll)
- #6551 `39ddaeb` Handle leveldb::DestroyDB() errors on wipe failure (Adam Weiss)
- #6654 `b0ce450` Mempool package tracking (Suhas Daftuar)
- #6715 `82d2aef` Fix mempool packages (Suhas Daftuar)
- #6680 `4f44530` use CBlockIndex instead of uint256 for UpdatedBlockTip signal (Jonas Schnelli)
- #6650 `4fac576` Obfuscate chainstate (James O'Beirne)
- #6777 `9caaf6e` Unobfuscate chainstate data in CCoinsViewDB::GetStats (James O'Beirne)
- #6722 `3b20e23` Limit mempool by throwing away the cheapest txn and setting min relay fee to it (Matt Corallo)
- #6889 `38369dd` fix locking issue with new mempool limiting (Jonas Schnelli)
- #6464 `8f3b3cd` Always clean up manual transaction prioritization (Casey Rodarmor)
- #6865 `d0badb9` Fix chainstate serialized_size computation (Pieter Wuille)
- #6566 `ff057f4` BIP-113: Mempool-only median time-past as endpoint for lock-time calculations (Mark Friedenbach)
- #6934 `3038eb6` Restores mempool only BIP113 enforcement (Gregory Maxwell)
- #6965 `de7d459` Benchmark sanity checks and fork checks in ConnectBlock (Matt Corallo)
- #6918 `eb6172a` Make sigcache faster, more efficient, larger (Pieter Wuille)
- #6771 `38ed190` Policy: Lower default limits for tx chains (Alex Morcos)
- #6932 `73fa5e6` ModifyNewCoins saves database lookups (Alex Morcos)
- #5967 `05d5918` Alter assumptions in CCoinsViewCache::BatchWrite (Alex Morcos)
- #6871 `0e93586` nSequence-based Full-RBF opt-in (Peter Todd)
- #7008 `eb77416` Lower bound priority (Alex Morcos)
- #6915 `2ef5ffa` [Mempool] Improve removal of invalid transactions after reorgs (Suhas Daftuar)
- #6898 `4077ad2` Rewrite CreateNewBlock (Alex Morcos)
- #6872 `bdda4d5` Remove UTXO cache entries when the tx they were added for is removed/does not enter mempool (Matt Corallo)
- #7062 `12c469b` [Mempool] Fix mempool limiting and replace-by-fee for PrioritiseTransaction (Suhas Daftuar)
- #7276 `76de36f` Report non-mandatory script failures correctly (Pieter Wuille)
- #7217 `e08b7cb` Mark blocks with too many sigops as failed (Suhas Daftuar)
- #7387 `f4b2ce8` Get rid of inaccurate ScriptSigArgsExpected (Pieter Wuille)
### P2P protocol and network code
- #6172 `88a7ead` Ignore getheaders requests when not synced (Suhas Daftuar)
- #5875 `9d60602` Be stricter in processing unrequested blocks (Suhas Daftuar)
- #6256 `8ccc07c` Use best header chain timestamps to detect partitioning (Gavin Andresen)
- #6283 `a903ad7` make CAddrMan::size() return the correct type of size_t (Diapolo)
- #6272 `40400d5` Improve proxy initialization (continues #4871) (Wladimir J. van der Laan, Diapolo)
- #6310 `66e5465` banlist.dat: store banlist on disk (Jonas Schnelli)
- #6412 `1a2de32` Test whether created sockets are select()able (Pieter Wuille)
- #6498 `219b916` Keep track of recently rejected transactions with a rolling bloom filter (cont'd) (Peter Todd)
- #6556 `70ec975` Fix masking of irrelevant bits in address groups. (Alex Morcos)
- #6530 `ea19c2b` Improve addrman Select() performance when buckets are nearly empty (Pieter Wuille)
- #6583 `af9305a` add support for miniupnpc api version 14 (Pavel Vasin)
- #6374 `69dc5b5` Connection slot exhaustion DoS mitigation (Patrick Strateman)
- #6636 `536207f` net: correctly initialize nMinPingUsecTime (Wladimir J. van der Laan)
- #6579 `0c27795` Add NODE_BLOOM service bit and bump protocol version (Matt Corallo)
- #6148 `999c8be` Relay blocks when pruning (Suhas Daftuar)
- #6588 `cf9bb11` In (strCommand == "tx"), return if AlreadyHave() (Tom Harding)
- #6974 `2f71b07` Always allow getheaders from whitelisted peers (Wladimir J. van der Laan)
- #6639 `bd629d7` net: Automatically create hidden service, listen on Tor (Wladimir J. van der Laan)
- #6984 `9ffc687` don't enforce maxuploadtarget's disconnect for whitelisted peers (Jonas Schnelli)
- #7046 `c322652` Net: Improve blocks only mode. (Patrick Strateman)
- #7090 `d6454f6` Connect to Tor hidden services by default (when listening on Tor) (Peter Todd)
- #7106 `c894fbb` Fix and improve relay from whitelisted peers (Pieter Wuille)
- #7129 `5d5ef3a` Direct headers announcement (rebase of #6494) (Pieter Wuille)
- #7079 `1b5118b` Prevent peer flooding inv request queue (redux) (redux) (Gregory Maxwell)
- #7166 `6ba25d2` Disconnect on mempool requests from peers when over the upload limit. (Gregory Maxwell)
- #7133 `f31955d` Replace setInventoryKnown with a rolling bloom filter (rebase of #7100) (Pieter Wuille)
- #7174 `82aff88` Don't do mempool lookups for "mempool" command without a filter (Matt Corallo)
- #7179 `44fef99` net: Fix sent reject messages for blocks and transactions (Wladimir J. van der Laan)
- #7181 `8fc174a` net: Add and document network messages in protocol.h (Wladimir J. van der Laan)
- #7125 `10b88be` Replace global trickle node with random delays (Pieter Wuille)
- #7415 `cb83beb` net: Hardcoded seeds update January 2016 (Wladimir J. van der Laan)
- #7438 `e2d9a58` Do not absolutely protect local peers; decide group ties based on time (Gregory Maxwell)
- #7439 `86755bc` Add whitelistforcerelay to control forced relaying. [#7099 redux] (Gregory Maxwell)
- #7482 `e16f5b4` Ensure headers count is correct (Suhas Daftuar)
### Validation
- #5927 `8d9f0a6` Reduce checkpoints' effect on consensus. (Pieter Wuille)
- #6299 `24f2489` Bugfix: Don't check the genesis block header before accepting it (Jorge Timón)
- #6361 `d7ada03` Use real number of cores for default -par, ignore virtual cores (Wladimir J. van der Laan)
- #6519 `87f37e2` Make logging for validation optional (Wladimir J. van der Laan)
- #6351 `2a1090d` CHECKLOCKTIMEVERIFY (BIP65) IsSuperMajority() soft-fork (Peter Todd)
- #6931 `54e8bfe` Skip BIP 30 verification where not necessary (Alex Morcos)
- #6954 `e54ebbf` Switch to libsecp256k1-based ECDSA validation (Pieter Wuille)
- #6508 `61457c2` Switch to a constant-space Merkle root/branch algorithm. (Pieter Wuille)
- #6914 `327291a` Add pre-allocated vector type and use it for CScript (Pieter Wuille)
- #7500 `889e5b3` Correctly report high-S violations (Pieter Wuille)
### Build system
- #6210 `0e4f2a0` build: disable optional use of gmp in internal secp256k1 build (Wladimir J. van der Laan)
- #6214 `87406aa` [OSX] revert renaming of Bitcoin-Qt.app and use CFBundleDisplayName (partial revert of #6116) (Jonas Schnelli)
- #6218 `9d67b10` build/gitian misc updates (Cory Fields)
- #6269 `d4565b6` gitian: Use the new bitcoin-detached-sigs git repo for OSX signatures (Cory Fields)
- #6418 `d4a910c` Add autogen.sh to source tarball. (randy-waterhouse)
- #6373 `1ae3196` depends: non-qt bumps for 0.12 (Cory Fields)
- #6434 `059b352` Preserve user-passed CXXFLAGS with --enable-debug (Gavin Andresen)
- #6501 `fee6554` Misc build fixes (Cory Fields)
- #6600 `ef4945f` Include bitcoin-tx binary on Debian/Ubuntu (Zak Wilcox)
- #6619 `4862708` depends: bump miniupnpc and ccache (Michael Ford)
- #6801 `ae69a75` [depends] Latest config.guess and config.sub (Michael Ford)
- #6938 `193f7b5` build: If both Qt4 and Qt5 are installed, use Qt5 (Wladimir J. van der Laan)
- #7092 `348b281` build: Set osx permissions in the dmg to make Gatekeeper happy (Cory Fields)
- #6980 `eccd671` [Depends] Bump Boost, miniupnpc, ccache & zeromq (Michael Ford)
- #7424 `aa26ee0` Add security/export checks to gitian and fix current failures (Cory Fields)
### Wallet
- #6183 `87550ee` Fix off-by-one error w/ nLockTime in the wallet (Peter Todd)
- #6057 `ac5476e` re-enable wallet in autoprune (Jonas Schnelli)
- #6356 `9e6c33b` Delay initial pruning until after wallet init (Adam Weiss)
- #6088 `91389e5` fundrawtransaction (Matt Corallo)
- #6415 `ddd8d80` Implement watchonly support in fundrawtransaction (Matt Corallo)
- #6567 `0f0f323` Fix crash when mining with empty keypool. (Daniel Kraft)
- #6688 `4939eab` Fix locking in GetTransaction. (Alex Morcos)
- #6645 `4dbd43e` Enable wallet key imports without rescan in pruned mode. (Gregory Maxwell)
- #6550 `5b77244` Do not store Merkle branches in the wallet. (Pieter Wuille)
- #5924 `12a7712` Clean up change computation in CreateTransaction. (Daniel Kraft)
- #6906 `48b5b84` Reject invalid pubkeys when reading ckey items from the wallet. (Gregory Maxwell)
- #7010 `e0a5ef8` Fix fundrawtransaction handling of includeWatching (Peter Todd)
- #6851 `616d61b` Optimisation: Store transaction list order in memory rather than compute it every need (Luke-Jr)
- #6134 `e92377f` Improve usage of fee estimation code (Alex Morcos)
- #7103 `a775182` [wallet, rpc tests] Fix settxfee, paytxfee (MarcoFalke)
- #7105 `30c2d8c` Keep track of explicit wallet conflicts instead of using mempool (Pieter Wuille)
- #7096 `9490bd7` [Wallet] Improve minimum absolute fee GUI options (Jonas Schnelli)
- #6216 `83f06ca` Take the training wheels off anti-fee-sniping (Peter Todd)
- #4906 `96e8d12` Issue#1643: Coinselection prunes extraneous inputs from ApproximateBestSubset (Murch)
- #7200 `06c6a58` Checks for null data transaction before issuing error to debug.log (Andy Craze)
- #7296 `a36d79b` Add sane fallback for fee estimation (Alex Morcos)
- #7293 `ff9b610` Add regression test for vValue sort order (MarcoFalke)
- #7306 `4707797` Make sure conflicted wallet tx's update balances (Alex Morcos)
- #7381 `621bbd8` [walletdb] Fix syntax error in key parser (MarcoFalke)
- #7491 `00ec73e` wallet: Ignore MarkConflict if block hash is not known (Wladimir J. van der Laan)
- #7502 `1329963` Update the wallet best block marker before pruning (Pieter Wuille)
### GUI
- #6217 `c57e12a` disconnect peers from peers tab via context menu (Diapolo)
- #6209 `ab0ec67` extend rpc console peers tab (Diapolo)
- #6484 `1369d69` use CHashWriter also in SignVerifyMessageDialog (Pavel Vasin)
- #6487 `9848d42` Introduce PlatformStyle (Wladimir J. van der Laan)
- #6505 `100c9d3` cleanup icons (MarcoFalke)
- #4587 `0c465f5` allow users to set -onion via GUI (Diapolo)
- #6529 `c0f66ce` show client user agent in debug window (Diapolo)
- #6594 `878ea69` Disallow duplicate windows. (Casey Rodarmor)
- #5665 `6f55cdd` add verifySize() function to PaymentServer (Diapolo)
- #6317 `ca5e2a1` minor optimisations in peertablemodel (Diapolo)
- #6315 `e59d2a8` allow banning and unbanning over UI->peers table (Jonas Schnelli)
- #6653 `e04b2fa` Pop debug window in foreground when opened twice (MarcoFalke)
- #6864 `c702521` Use monospace font (MarcoFalke)
- #6887 `3694b74` Update coin control and smartfee labels (MarcoFalke)
- #7000 `814697c` add shortcurts for debug-/console-window (Jonas Schnelli)
- #6951 `03403d8` Use maxTxFee instead of 10000000 (MarcoFalke)
- #7051 `a190777` ui: Add "Copy raw transaction data" to transaction list context menu (Wladimir J. van der Laan)
- #6979 `776848a` simple mempool info in debug window (Jonas Schnelli)
- #7006 `26af1ac` add startup option to reset Qt settings (Jonas Schnelli)
- #6780 `2a94cd6` Call init's parameter interaction before we create the UI options model (Jonas Schnelli)
- #7112 `96b8025` reduce cs_main locks during tip update, more fluently update UI (Jonas Schnelli)
- #7206 `f43c2f9` Add "NODE_BLOOM" to guiutil so that peers don't get UNKNOWN[4] (Matt Corallo)
- #7282 `5cadf3e` fix coincontrol update issue when deleting a send coins entry (Jonas Schnelli)
- #7319 `1320300` Intro: Display required space (MarcoFalke)
- #7318 `9265e89` quickfix for RPC timer interface problem (Jonas Schnelli)
- #7327 `b16b5bc` [Wallet] Transaction View: LastMonth calculation fixed (crowning-)
- #7364 `7726c48` [qt] Windows: Make rpcconsole monospace font larger (MarcoFalke)
- #7384 `294f432` [qt] Peertable: Increase SUBVERSION_COLUMN_WIDTH (MarcoFalke)
### Tests and QA
- #6305 `9005c91` build: comparison tool swap (Cory Fields)
- #6318 `e307e13` build: comparison tool NPE fix (Cory Fields)
- #6337 `0564c5b` Testing infrastructure: mocktime fixes (Gavin Andresen)
- #6350 `60abba1` add unit tests for the decodescript rpc (mruddy)
- #5881 `3203a08` Fix and improve txn_doublespend.py test (Tom Harding)
- #6390 `6a73d66` tests: Fix bitcoin-tx signing test case (Wladimir J. van der Laan)
- #6368 `7fc25c2` CLTV: Add more tests to improve coverage (Esteban Ordano)
- #6414 `5121c68` Fix intermittent test failure, reduce test time (Tom Harding)
- #6417 `44fa82d` [QA] fix possible reorg issue in (fund)rawtransaction(s).py RPC test (Jonas Schnelli)
- #6398 `3d9362d` rpc: Remove chain-specific RequireRPCPassword (Wladimir J. van der Laan)
- #6428 `bb59e78` tests: Remove old sh-based test framework (Wladimir J. van der Laan)
- #5515 `d946e9a` RFC: Assert on probable deadlocks if the second lock isnt try_lock (Matt Corallo)
- #6287 `d2464df` Clang lock debug (Cory Fields)
- #6465 `410fd74` Don't share objects between TestInstances (Casey Rodarmor)
- #6534 `6c1c7fd` Fix test locking issues and un-revert the probable-deadlines assertions commit (Cory Fields)
- #6509 `bb4faee` Fix race condition on test node shutdown (Casey Rodarmor)
- #6523 `561f8af` Add p2p-fullblocktest.py (Casey Rodarmor)
- #6590 `981fd92` Fix stale socket rebinding and re-enable python tests for Windows (Cory Fields)
- #6730 `cb4d6d0` build: Remove dependency of bitcoin-cli on secp256k1 (Wladimir J. van der Laan)
- #6616 `5ab5dca` Regression Tests: Migrated rpc-tests.sh to all Python rpc-tests.py (Peter Tschipper)
- #6720 `d479311` Creates unittests for addrman, makes addrman more testable. (Ethan Heilman)
- #6853 `c834f56` Added fPowNoRetargeting field to Consensus::Params (Eric Lombrozo)
- #6827 `87e5539` [rpc-tests] Check return code (MarcoFalke)
- #6848 `f2c869a` Add DERSIG transaction test cases (Ross Nicoll)
- #6813 `5242bb3` Support gathering code coverage data for RPC tests with lcov (dexX7)
- #6888 `c8322ff` Clear strMiscWarning before running PartitionAlert (Eric Lombrozo)
- #6894 `2675276` [Tests] Fix BIP65 p2p test (Suhas Daftuar)
- #6863 `725539e` [Test Suite] Fix test for null tx input (Daniel Kraft)
- #6926 `a6d0d62` tests: Initialize networking on windows (Wladimir J. van der Laan)
- #6822 `9fa54a1` [tests] Be more strict checking dust (MarcoFalke)
- #6804 `5fcc14e` [tests] Add basic coverage reporting for RPC tests (James O'Beirne)
- #7045 `72dccfc` Bugfix: Use unique autostart filenames on Linux for testnet/regtest (Luke-Jr)
- #7095 `d8368a0` Replace scriptnum_test's normative ScriptNum implementation (Wladimir J. van der Laan)
- #7063 `6abf6eb` [Tests] Add prioritisetransaction RPC test (Suhas Daftuar)
- #7137 `16f4a6e` Tests: Explicitly set chain limits in replace-by-fee test (Suhas Daftuar)
- #7216 `9572e49` Removed offline testnet DNSSeed 'alexykot.me'. (tnull)
- #7209 `f3ad812` test: don't override BITCOIND and BITCOINCLI if they're set (Wladimir J. van der Laan)
- #7226 `301f16a` Tests: Add more tests to p2p-fullblocktest (Suhas Daftuar)
- #7153 `9ef7c54` [Tests] Add mempool_limit.py test (Jonas Schnelli)
- #7170 `453c567` tests: Disable Tor interaction (Wladimir J. van der Laan)
- #7229 `1ed938b` [qa] wallet: Check if maintenance changes the balance (MarcoFalke)
- #7308 `d513405` [Tests] Eliminate intermittent failures in sendheaders.py (Suhas Daftuar)
- #7468 `947c4ff` [rpc-tests] Change solve() to use rehash (Brad Andrews)
### Miscellaneous
- #6213 `e54ff2f` [init] add -blockversion help and extend -upnp help (Diapolo)
- #5975 `1fea667` Consensus: Decouple ContextualCheckBlockHeader from checkpoints (Jorge Timón)
- #6061 `eba2f06` Separate Consensus::CheckTxInputs and GetSpendHeight in CheckInputs (Jorge Timón)
- #5994 `786ed11` detach wallet from miner (Jonas Schnelli)
- #6387 `11576a5` [bitcoin-cli] improve error output (Jonas Schnelli)
- #6401 `6db53b4` Add BITCOIND_SIGTERM_TIMEOUT to OpenRC init scripts (Florian Schmaus)
- #6430 `b01981e` doc: add documentation for shared library libbitcoinconsensus (Braydon Fuller)
- #6372 `dcc495e` Update Linearize tool to support Windows paths; fix variable scope; update README and example configuration (Paul Georgiou)
- #6453 `8fe5cce` Separate core memory usage computation in core_memusage.h (Pieter Wuille)
- #6149 `633fe10` Buffer log messages and explicitly open logs (Adam Weiss)
- #6488 `7cbed7f` Avoid leaking file descriptors in RegisterLoad (Casey Rodarmor)
- #6497 `a2bf40d` Make sure LogPrintf strings are line-terminated (Wladimir J. van der Laan)
- #6504 `b6fee6b` Rationalize currency unit to "BTC" (Ross Nicoll)
- #6507 `9bb4dd8` Removed contrib/bitrpc (Casey Rodarmor)
- #6527 `41d650f` Use unique name for AlertNotify tempfile (Casey Rodarmor)
- #6561 `e08a7d9` limitedmap fixes and tests (Casey Rodarmor)
- #6565 `a6f2aff` Make sure we re-acquire lock if a task throws (Casey Rodarmor)
- #6599 `f4d88c4` Make sure LogPrint strings are line-terminated (Ross Nicoll)
- #6630 `195942d` Replace boost::reverse_lock with our own (Casey Rodarmor)
- #6103 `13b8282` Add ZeroMQ notifications (João Barbosa)
- #6692 `d5d1d2e` devtools: don't push if signing fails in github-merge (Wladimir J. van der Laan)
- #6728 `2b0567b` timedata: Prevent warning overkill (Wladimir J. van der Laan)
- #6713 `f6ce59c` SanitizeString: Allow hypen char (MarcoFalke)
- #5987 `4899a04` Bugfix: Fix testnet-in-a-box use case (Luke-Jr)
- #6733 `b7d78fd` Simple benchmarking framework (Gavin Andresen)
- #6854 `a092970` devtools: Add security-check.py (Wladimir J. van der Laan)
- #6790 `fa1d252` devtools: add clang-format.py (MarcoFalke)
- #7114 `f3d0fdd` util: Don't set strMiscWarning on every exception (Wladimir J. van der Laan)
- #7078 `93e0514` uint256::GetCheapHash bigendian compatibility (arowser)
- #7094 `34e02e0` Assert now > 0 in GetTime GetTimeMillis GetTimeMicros (Patrick Strateman)
Credits
=======
Thanks to everyone who directly contributed to this release:
- accraze
- Adam Weiss
- Alex Morcos
- Alex van der Peet
- AlSzacrel
- Altoidnerd
- Andriy Voskoboinyk
- antonio-fr
- Arne Brutschy
- Ashley Holman
- Bob McElrath
- Braydon Fuller
- BtcDrak
- Casey Rodarmor
- centaur1
- Chris Kleeschulte
- Christian Decker
- Cory Fields
- crowning-
- daniel
- Daniel Cousens
- Daniel Kraft
- David Hill
- dexX7
- Diego Viola
- Elias Rohrer
- Eric Lombrozo
- Erik Mossberg
- Esteban Ordano
- EthanHeilman
- Florian Schmaus
- Forrest Voight
- Gavin Andresen
- Gregory Maxwell
- Gregory Sanders / instagibbs
- Ian T
- Irving Ruan
- Jacob Welsh
- James O'Beirne
- Jeff Garzik
- Johnathan Corgan
- Jonas Schnelli
- Jonathan Cross
- João Barbosa
- Jorge Timón
- Josh Lehan
- J Ross Nicoll
- kazcw
- Kevin Cooper
- lpescher
- Luke Dashjr
- MarcoFalke
- Mark Friedenbach
- Matt
- Matt Bogosian
- Matt Corallo
- Matt Quinn
- Micha
- Michael
- Michael Ford / fanquake
- Midnight Magic
- Mitchell Cash
- mrbandrews
- mruddy
- Nick
- Patrick Strateman
- Paul Georgiou
- Paul Rabahy
- Pavel Janík / paveljanik
- Pavel Vasin
- Pavol Rusnak
- Peter Josling
- Peter Todd
- Philip Kaufmann
- Pieter Wuille
- ptschip
- randy-waterhouse
- rion
- Ross Nicoll
- Ryan Havar
- Shaul Kfir
- Simon Males
- Stephen
- Suhas Daftuar
- tailsjoin
- Thomas Kerin
- Tom Harding
- tulip
- unsystemizer
- Veres Lajos
- Wladimir J. van der Laan
- xor-freenet
- Zak Wilcox
- zathras-crypto
As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).

View File

@@ -0,0 +1,198 @@
Bitcoin Core version 0.12.1 is now available from:
<https://bitcoin.org/bin/bitcoin-core-0.12.1/>
This is a new minor version release, including the BIP9, BIP68 and BIP112
softfork, various bugfixes and updated translations.
Please report bugs using the issue tracker at github:
<https://github.com/bitcoin/bitcoin/issues>
Upgrading and downgrading
=========================
How to Upgrade
--------------
If you are running an older version, shut it down. Wait until it has completely
shut down (which might take a few minutes for older versions), then run the
installer (on Windows) or just copy over /Applications/Bitcoin-Qt (on Mac) or
bitcoind/bitcoin-qt (on Linux).
Downgrade warning
-----------------
### Downgrade to a version < 0.12.0
Because release 0.12.0 and later will obfuscate the chainstate on every
fresh sync or reindex, the chainstate is not backwards-compatible with
pre-0.12 versions of Bitcoin Core or other software.
If you want to downgrade after you have done a reindex with 0.12.0 or later,
you will need to reindex when you first start Bitcoin Core version 0.11 or
earlier.
Notable changes
===============
First version bits BIP9 softfork deployment
-------------------------------------------
This release includes a soft fork deployment to enforce [BIP68][],
[BIP112][] and [BIP113][] using the [BIP9][] deployment mechanism.
The deployment sets the block version number to 0x20000001 between
midnight 1st May 2016 and midnight 1st May 2017 to signal readiness for
deployment. The version number consists of 0x20000000 to indicate version
bits together with setting bit 0 to indicate support for this combined
deployment, shown as "csv" in the `getblockchaininfo` RPC call.
For more information about the soft forking change, please see
<https://github.com/bitcoin/bitcoin/pull/7648>
This specific backport pull-request can be viewed at
<https://github.com/bitcoin/bitcoin/pull/7543>
[BIP9]: https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki
[BIP68]: https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki
[BIP112]: https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki
[BIP113]: https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki
BIP68 soft fork to enforce sequence locks for relative locktime
---------------------------------------------------------------
[BIP68][] introduces relative lock-time consensus-enforced semantics of
the sequence number field to enable a signed transaction input to remain
invalid for a defined period of time after confirmation of its corresponding
outpoint.
For more information about the implementation, see
<https://github.com/bitcoin/bitcoin/pull/7184>
BIP112 soft fork to enforce OP_CHECKSEQUENCEVERIFY
--------------------------------------------------
[BIP112][] redefines the existing OP_NOP3 as OP_CHECKSEQUENCEVERIFY (CSV)
for a new opcode in the Bitcoin scripting system that in combination with
[BIP68][] allows execution pathways of a script to be restricted based
on the age of the output being spent.
For more information about the implementation, see
<https://github.com/bitcoin/bitcoin/pull/7524>
BIP113 locktime enforcement soft fork
-------------------------------------
Bitcoin Core 0.11.2 previously introduced mempool-only locktime
enforcement using GetMedianTimePast(). This release seeks to
consensus enforce the rule.
Bitcoin transactions currently may specify a locktime indicating when
they may be added to a valid block. Current consensus rules require
that blocks have a block header time greater than the locktime specified
in any transaction in that block.
Miners get to choose what time they use for their header time, with the
consensus rule being that no node will accept a block whose time is more
than two hours in the future. This creates a incentive for miners to
set their header times to future values in order to include locktimed
transactions which weren't supposed to be included for up to two more
hours.
The consensus rules also specify that valid blocks may have a header
time greater than that of the median of the 11 previous blocks. This
GetMedianTimePast() time has a key feature we generally associate with
time: it can't go backwards.
[BIP113][] specifies a soft fork enforced in this release that
weakens this perverse incentive for individual miners to use a future
time by requiring that valid blocks have a computed GetMedianTimePast()
greater than the locktime specified in any transaction in that block.
Mempool inclusion rules currently require transactions to be valid for
immediate inclusion in a block in order to be accepted into the mempool.
This release begins applying the BIP113 rule to received transactions,
so transaction whose time is greater than the GetMedianTimePast() will
no longer be accepted into the mempool.
**Implication for miners:** you will begin rejecting transactions that
would not be valid under BIP113, which will prevent you from producing
invalid blocks when BIP113 is enforced on the network. Any
transactions which are valid under the current rules but not yet valid
under the BIP113 rules will either be mined by other miners or delayed
until they are valid under BIP113. Note, however, that time-based
locktime transactions are more or less unseen on the network currently.
**Implication for users:** GetMedianTimePast() always trails behind the
current time, so a transaction locktime set to the present time will be
rejected by nodes running this release until the median time moves
forward. To compensate, subtract one hour (3,600 seconds) from your
locktimes to allow those transactions to be included in mempools at
approximately the expected time.
For more information about the implementation, see
<https://github.com/bitcoin/bitcoin/pull/6566>
Miscellaneous
-------------
The p2p alert system is off by default. To turn on, use `-alert` with
startup configuration.
0.12.1 Change log
=================
Detailed release notes follow. This overview includes changes that affect
behavior, not code moves, refactors and string updates. For convenience in locating
the code changes and accompanying discussion, both the pull request and
git merge commit are mentioned.
### RPC and other APIs
- #7739 `7ffc2bd` Add abandoned status to listtransactions (jonasschnelli)
### Block and transaction handling
- #7543 `834aaef` Backport BIP9, BIP68 and BIP112 with softfork (btcdrak)
### P2P protocol and network code
- #7804 `90f1d24` Track block download times per individual block (sipa)
- #7832 `4c3a00d` Reduce block timeout to 10 minutes (laanwj)
### Validation
- #7821 `4226aac` init: allow shutdown during 'Activating best chain...' (laanwj)
- #7835 `46898e7` Version 2 transactions remain non-standard until CSV activates (sdaftuar)
### Build system
- #7487 `00d57b4` Workaround Travis-side CI issues (luke-jr)
- #7606 `a10da9a` No need to set -L and --location for curl (MarcoFalke)
- #7614 `ca8f160` Add curl to packages (now needed for depends) (luke-jr)
- #7776 `a784675` Remove unnecessary executables from gitian release (laanwj)
### Wallet
- #7715 `19866c1` Fix calculation of balances and available coins. (morcos)
### Miscellaneous
- #7617 `f04f4fd` Fix markdown syntax and line terminate LogPrint (MarcoFalke)
- #7747 `4d035bc` added depends cross compile info (accraze)
- #7741 `a0cea89` Mark p2p alert system as deprecated (btcdrak)
- #7780 `c5f94f6` Disable bad-chain alert (btcdrak)
Credits
=======
Thanks to everyone who directly contributed to this release:
- accraze
- Alex Morcos
- BtcDrak
- Jonas Schnelli
- Luke Dashjr
- MarcoFalke
- Mark Friedenbach
- NicolasDorier
- Pieter Wuille
- Suhas Daftuar
- Wladimir J. van der Laan
As well as everyone that helped translating on [Transifex](https://www.transifex.com/projects/p/bitcoin/).

View File

@@ -3,6 +3,7 @@ Release Process
* Update translations (ping wumpus, Diapolo or tcatm on IRC) see [translation_process.md](https://github.com/bitcoin/bitcoin/blob/master/doc/translation_process.md#syncing-with-transifex)
* Update [bips.md](bips.md) to account for changes since the last release.
* Update hardcoded [seeds](/contrib/seeds)
* * *
@@ -19,8 +20,10 @@ Check out the source code in the following directory hierarchy.
pushd ./bitcoin
contrib/verifysfbinaries/verify.sh
configure.ac
doc/README*
share/setup.nsi
doc/Doxyfile
contrib/gitian-descriptors/*.yml
src/clientversion.h (change CLIENT_VERSION_IS_RELEASE to true)
# tag version in git
@@ -41,6 +44,7 @@ Check out the source code in the following directory hierarchy.
pushd ./bitcoin
export SIGNER=(your Gitian key, ie bluematt, sipa, etc)
export VERSION=(new version, e.g. 0.8.0)
git fetch
git checkout v${VERSION}
popd
@@ -83,25 +87,21 @@ NOTE: Offline builds must use the --url flag to ensure Gitian fetches only from
```
The gbuild invocations below <b>DO NOT DO THIS</b> by default.
###Build (and optionally verify) Bitcoin Core for Linux, Windows, and OS X:
###Build and sign Bitcoin Core for Linux, Windows, and OS X:
./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
./bin/gsign --signer $SIGNER --release ${VERSION}-linux --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-linux ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../
mv build/out/bitcoin-*.tar.gz build/out/src/bitcoin-*.tar.gz ../
./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-win.yml
./bin/gsign --signer $SIGNER --release ${VERSION}-win-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-win.yml
./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-win.yml
mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz
mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../
mv build/out/bitcoin-*-win-unsigned.tar.gz inputs/bitcoin-win-unsigned.tar.gz
mv build/out/bitcoin-*.zip build/out/bitcoin-*.exe ../
./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml
./bin/gsign --signer $SIGNER --release ${VERSION}-osx-unsigned --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml
./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml
mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz
mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../
popd
mv build/out/bitcoin-*-osx-unsigned.tar.gz inputs/bitcoin-osx-unsigned.tar.gz
mv build/out/bitcoin-*.tar.gz build/out/bitcoin-*.dmg ../
Build output expected:
@@ -111,6 +111,20 @@ The gbuild invocations below <b>DO NOT DO THIS</b> by default.
4. OS X unsigned installer and dist tarball (bitcoin-${VERSION}-osx-unsigned.dmg, bitcoin-${VERSION}-osx64.tar.gz)
5. Gitian signatures (in gitian.sigs/${VERSION}-<linux|{win,osx}-unsigned>/(your Gitian key)/
###Verify other gitian builders signatures to your own. (Optional)
Add other gitian builders keys to your gpg keyring
gpg --import ../bitcoin/contrib/gitian-downloader/*.pgp
Verify the signatures
./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-linux ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml
./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-win-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-win.yml
./bin/gverify -v -d ../gitian.sigs/ -r ${VERSION}-osx-unsigned ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml
popd
###Next steps:
Commit your signature to gitian.sigs:
@@ -124,7 +138,6 @@ Commit your signature to gitian.sigs:
popd
Wait for Windows/OS X detached signatures:
Once the Windows/OS X builds each have 3 matching signatures, they will be signed with their respective release keys.
Detached signatures will then be committed to the [bitcoin-detached-sigs](https://github.com/bitcoin/bitcoin-detached-sigs) repository, which can be combined with the unsigned apps to create signed binaries.
@@ -197,7 +210,7 @@ Note: check that SHA256SUMS itself doesn't end up in SHA256SUMS, which is a spur
- Optionally reddit /r/Bitcoin, ... but this will usually sort out itself
- Notify BlueMatt so that he can start building [https://launchpad.net/~bitcoin/+archive/ubuntu/bitcoin](the PPAs)
- Notify BlueMatt so that he can start building [the PPAs](https://launchpad.net/~bitcoin/+archive/ubuntu/bitcoin)
- Add release notes for the new version to the directory `doc/release-notes` in git master

View File

@@ -52,7 +52,7 @@ your bitcoind's P2P listen port (8333 by default).
this option, and this can be a .onion address. Given the above
configuration, you can find your onion address in
/var/lib/tor/bitcoin-service/hostname. Onion addresses are given
preference for your node to advertize itself with, for connections
preference for your node to advertise itself with, for connections
coming from unroutable addresses (such as 127.0.0.1, where the
Tor proxy typically runs).

View File

@@ -38,7 +38,7 @@ newer. Typically, it is packaged by distributions as something like
*libzmq3-dev*. The C++ wrapper for ZeroMQ is *not* needed.
In order to run the example Python client scripts in contrib/ one must
also install *python-zmq*, though this is not necessary for daemon
also install *python3-zmq*, though this is not necessary for daemon
operation.
## Enabling

View File

@@ -5,6 +5,17 @@ Every pull request to the bitcoin repository is built and run through
the regression test suite. You can also run all or only individual
tests locally.
Test dependencies
=================
Before running the tests, the following must be installed.
Unix
----
The python3-zmq library is required. On Ubuntu or Debian it can be installed via:
```
sudo apt-get install python3-zmq
```
Running tests
=============

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -32,13 +32,13 @@ import re
from tests_config import *
#If imported values are not defined then set to zero (or disabled)
if not vars().has_key('ENABLE_WALLET'):
if 'ENABLE_WALLET' not in vars():
ENABLE_WALLET=0
if not vars().has_key('ENABLE_BITCOIND'):
if 'ENABLE_BITCOIND' not in vars():
ENABLE_BITCOIND=0
if not vars().has_key('ENABLE_UTILS'):
if 'ENABLE_UTILS' not in vars():
ENABLE_UTILS=0
if not vars().has_key('ENABLE_ZMQ'):
if 'ENABLE_ZMQ' not in vars():
ENABLE_ZMQ=0
ENABLE_COVERAGE=0
@@ -62,16 +62,33 @@ for arg in sys.argv[1:]:
#Set env vars
buildDir = BUILDDIR
os.environ["BITCOIND"] = buildDir + '/src/bitcoind' + EXEEXT
os.environ["BITCOINCLI"] = buildDir + '/src/bitcoin-cli' + EXEEXT
if "BITCOIND" not in os.environ:
os.environ["BITCOIND"] = buildDir + '/src/bitcoind' + EXEEXT
if "BITCOINCLI" not in os.environ:
os.environ["BITCOINCLI"] = buildDir + '/src/bitcoin-cli' + EXEEXT
#Disable Windows tests by default
if EXEEXT == ".exe" and "-win" not in opts:
print "Win tests currently disabled. Use -win option to enable"
# https://github.com/bitcoin/bitcoin/commit/d52802551752140cf41f0d9a225a43e84404d3e9
# https://github.com/bitcoin/bitcoin/pull/5677#issuecomment-136646964
print("Win tests currently disabled by default. Use -win option to enable")
sys.exit(0)
if not (ENABLE_WALLET == 1 and ENABLE_UTILS == 1 and ENABLE_BITCOIND == 1):
print("No rpc tests to run. Wallet, utils, and bitcoind must all be enabled")
sys.exit(0)
# python3-zmq may not be installed. Handle this gracefully and with some helpful info
if ENABLE_ZMQ:
try:
import zmq
except ImportError as e:
print("ERROR: \"import zmq\" failed. Set ENABLE_ZMQ=0 or " \
"to run zmq tests, see dependency info in /qa/README.md.")
raise e
#Tests
testScripts = [
'bip68-112-113-p2p.py',
'wallet.py',
'listtransactions.py',
'receivedby.py',
@@ -83,6 +100,7 @@ testScripts = [
'rest.py',
'mempool_spendcoinbase.py',
'mempool_reorg.py',
'mempool_limit.py',
'httpbasics.py',
'multi_rpc.py',
'zapwallettxes.py',
@@ -100,10 +118,19 @@ testScripts = [
'sendheaders.py',
'keypool.py',
'prioritise_transaction.py',
'invalidblockrequest.py',
'invalidtxrequest.py',
'abandonconflict.py',
'p2p-versionbits-warning.py',
]
if ENABLE_ZMQ:
testScripts.append('zmq_test.py')
testScriptsExt = [
'bip9-softforks.py',
'bip65-cltv.py',
'bip65-cltv-p2p.py',
'bip68-sequence.py',
'bipdersig-p2p.py',
'bipdersig.py',
'getblocktemplate_longpoll.py',
@@ -116,18 +143,12 @@ testScriptsExt = [
# 'rpcbind_test.py', #temporary, bug in libevent, see #6655
'smartfees.py',
'maxblocksinflight.py',
'invalidblockrequest.py',
'p2p-acceptblock.py',
'mempool_packages.py',
'maxuploadtarget.py',
'replace-by-fee.py',
]
#Enable ZMQ tests
if ENABLE_ZMQ == 1:
testScripts.append('zmq_test.py')
def runtests():
coverage = None
@@ -135,53 +156,49 @@ def runtests():
coverage = RPCCoverage()
print("Initializing coverage directory at %s\n" % coverage.dir)
if(ENABLE_WALLET == 1 and ENABLE_UTILS == 1 and ENABLE_BITCOIND == 1):
rpcTestDir = buildDir + '/qa/rpc-tests/'
run_extended = '-extended' in opts
cov_flag = coverage.flag if coverage else ''
flags = " --srcdir %s/src %s %s" % (buildDir, cov_flag, passOn)
rpcTestDir = buildDir + '/qa/rpc-tests/'
run_extended = '-extended' in opts
cov_flag = coverage.flag if coverage else ''
flags = " --srcdir %s/src %s %s" % (buildDir, cov_flag, passOn)
#Run Tests
for i in range(len(testScripts)):
if (len(opts) == 0
or (len(opts) == 1 and "-win" in opts )
or run_extended
or testScripts[i] in opts
or re.sub(".py$", "", testScripts[i]) in opts ):
#Run Tests
for i in range(len(testScripts)):
if (len(opts) == 0
or (len(opts) == 1 and "-win" in opts )
or run_extended
or testScripts[i] in opts
or re.sub(".py$", "", testScripts[i]) in opts ):
print("Running testscript %s%s%s ..." % (bold[1], testScripts[i], bold[0]))
time0 = time.time()
subprocess.check_call(
rpcTestDir + testScripts[i] + flags, shell=True)
print("Duration: %s s\n" % (int(time.time() - time0)))
print("Running testscript %s%s%s ..." % (bold[1], testScripts[i], bold[0]))
time0 = time.time()
subprocess.check_call(
rpcTestDir + testScripts[i] + flags, shell=True)
print("Duration: %s s\n" % (int(time.time() - time0)))
# exit if help is called so we print just one set of
# instructions
p = re.compile(" -h| --help")
if p.match(passOn):
sys.exit(0)
# exit if help is called so we print just one set of
# instructions
p = re.compile(" -h| --help")
if p.match(passOn):
sys.exit(0)
# Run Extended Tests
for i in range(len(testScriptsExt)):
if (run_extended or testScriptsExt[i] in opts
or re.sub(".py$", "", testScriptsExt[i]) in opts):
# Run Extended Tests
for i in range(len(testScriptsExt)):
if (run_extended or testScriptsExt[i] in opts
or re.sub(".py$", "", testScriptsExt[i]) in opts):
print(
"Running 2nd level testscript "
+ "%s%s%s ..." % (bold[1], testScriptsExt[i], bold[0]))
time0 = time.time()
subprocess.check_call(
rpcTestDir + testScriptsExt[i] + flags, shell=True)
print("Duration: %s s\n" % (int(time.time() - time0)))
print(
"Running 2nd level testscript "
+ "%s%s%s ..." % (bold[1], testScriptsExt[i], bold[0]))
time0 = time.time()
subprocess.check_call(
rpcTestDir + testScriptsExt[i] + flags, shell=True)
print("Duration: %s s\n" % (int(time.time() - time0)))
if coverage:
coverage.report_rpc_coverage()
if coverage:
coverage.report_rpc_coverage()
print("Cleaning up coverage data")
coverage.cleanup()
else:
print "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled"
print("Cleaning up coverage data")
coverage.cleanup()
class RPCCoverage(object):

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2013-2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2013-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -11,5 +11,3 @@ EXEEXT="@EXEEXT@"
@BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=1
@BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=1
@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=1

View File

@@ -47,10 +47,7 @@ implements the test logic.
* ```NodeConn``` is the class used to connect to a bitcoind. If you implement
a callback class that derives from ```NodeConnCB``` and pass that to the
```NodeConn``` object, your code will receive the appropriate callbacks when
events of interest arrive. NOTE: be sure to call
```self.create_callback_map()``` in your derived classes' ```__init__```
function, so that the correct mappings are set up between p2p messages and your
callback functions.
events of interest arrive.
* You can pass the same handler to multiple ```NodeConn```'s if you like, or pass
different ones to each -- whatever makes the most sense for your test.

156
qa/rpc-tests/abandonconflict.py Executable file
View File

@@ -0,0 +1,156 @@
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import urllib.parse
class AbandonConflictTest(BitcoinTestFramework):
def setup_network(self):
self.nodes = []
self.nodes.append(start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.00001"]))
self.nodes.append(start_node(1, self.options.tmpdir, ["-debug","-logtimemicros"]))
connect_nodes(self.nodes[0], 1)
def run_test(self):
self.nodes[1].generate(100)
sync_blocks(self.nodes)
balance = self.nodes[0].getbalance()
txA = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("10"))
txB = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("10"))
txC = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), Decimal("10"))
sync_mempools(self.nodes)
self.nodes[1].generate(1)
sync_blocks(self.nodes)
newbalance = self.nodes[0].getbalance()
assert(balance - newbalance < Decimal("0.001")) #no more than fees lost
balance = newbalance
url = urllib.parse.urlparse(self.nodes[1].url)
self.nodes[0].disconnectnode(url.hostname+":"+str(p2p_port(1)))
# Identify the 10btc outputs
nA = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txA, 1)["vout"]) if vout["value"] == Decimal("10"))
nB = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txB, 1)["vout"]) if vout["value"] == Decimal("10"))
nC = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txC, 1)["vout"]) if vout["value"] == Decimal("10"))
inputs =[]
# spend 10btc outputs from txA and txB
inputs.append({"txid":txA, "vout":nA})
inputs.append({"txid":txB, "vout":nB})
outputs = {}
outputs[self.nodes[0].getnewaddress()] = Decimal("14.99998")
outputs[self.nodes[1].getnewaddress()] = Decimal("5")
signed = self.nodes[0].signrawtransaction(self.nodes[0].createrawtransaction(inputs, outputs))
txAB1 = self.nodes[0].sendrawtransaction(signed["hex"])
# Identify the 14.99998btc output
nAB = next(i for i, vout in enumerate(self.nodes[0].getrawtransaction(txAB1, 1)["vout"]) if vout["value"] == Decimal("14.99998"))
#Create a child tx spending AB1 and C
inputs = []
inputs.append({"txid":txAB1, "vout":nAB})
inputs.append({"txid":txC, "vout":nC})
outputs = {}
outputs[self.nodes[0].getnewaddress()] = Decimal("24.9996")
signed2 = self.nodes[0].signrawtransaction(self.nodes[0].createrawtransaction(inputs, outputs))
txABC2 = self.nodes[0].sendrawtransaction(signed2["hex"])
# In mempool txs from self should increase balance from change
newbalance = self.nodes[0].getbalance()
assert(newbalance == balance - Decimal("30") + Decimal("24.9996"))
balance = newbalance
# Restart the node with a higher min relay fee so the parent tx is no longer in mempool
# TODO: redo with eviction
# Note had to make sure tx did not have AllowFree priority
stop_node(self.nodes[0],0)
self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.0001"])
# Verify txs no longer in mempool
assert(len(self.nodes[0].getrawmempool()) == 0)
# Not in mempool txs from self should only reduce balance
# inputs are still spent, but change not received
newbalance = self.nodes[0].getbalance()
assert(newbalance == balance - Decimal("24.9996"))
# Unconfirmed received funds that are not in mempool, also shouldn't show
# up in unconfirmed balance
unconfbalance = self.nodes[0].getunconfirmedbalance() + self.nodes[0].getbalance()
assert(unconfbalance == newbalance)
# Also shouldn't show up in listunspent
assert(not txABC2 in [utxo["txid"] for utxo in self.nodes[0].listunspent(0)])
balance = newbalance
# Abandon original transaction and verify inputs are available again
# including that the child tx was also abandoned
self.nodes[0].abandontransaction(txAB1)
newbalance = self.nodes[0].getbalance()
assert(newbalance == balance + Decimal("30"))
balance = newbalance
# Verify that even with a low min relay fee, the tx is not reaccepted from wallet on startup once abandoned
stop_node(self.nodes[0],0)
self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.00001"])
assert(len(self.nodes[0].getrawmempool()) == 0)
assert(self.nodes[0].getbalance() == balance)
# But if its received again then it is unabandoned
# And since now in mempool, the change is available
# But its child tx remains abandoned
self.nodes[0].sendrawtransaction(signed["hex"])
newbalance = self.nodes[0].getbalance()
assert(newbalance == balance - Decimal("20") + Decimal("14.99998"))
balance = newbalance
# Send child tx again so its unabandoned
self.nodes[0].sendrawtransaction(signed2["hex"])
newbalance = self.nodes[0].getbalance()
assert(newbalance == balance - Decimal("10") - Decimal("14.99998") + Decimal("24.9996"))
balance = newbalance
# Remove using high relay fee again
stop_node(self.nodes[0],0)
self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.0001"])
assert(len(self.nodes[0].getrawmempool()) == 0)
newbalance = self.nodes[0].getbalance()
assert(newbalance == balance - Decimal("24.9996"))
balance = newbalance
# Create a double spend of AB1 by spending again from only A's 10 output
# Mine double spend from node 1
inputs =[]
inputs.append({"txid":txA, "vout":nA})
outputs = {}
outputs[self.nodes[1].getnewaddress()] = Decimal("9.9999")
tx = self.nodes[0].createrawtransaction(inputs, outputs)
signed = self.nodes[0].signrawtransaction(tx)
self.nodes[1].sendrawtransaction(signed["hex"])
self.nodes[1].generate(1)
connect_nodes(self.nodes[0], 1)
sync_blocks(self.nodes)
# Verify that B and C's 10 BTC outputs are available for spending again because AB1 is now conflicted
newbalance = self.nodes[0].getbalance()
assert(newbalance == balance + Decimal("20"))
balance = newbalance
# There is currently a minor bug around this and so this test doesn't work. See Issue #7315
# Invalidate the block with the double spend and B's 10 BTC output should no longer be available
# Don't think C's should either
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
newbalance = self.nodes[0].getbalance()
#assert(newbalance == balance - Decimal("10"))
print("If balance has not declined after invalidateblock then out of mempool wallet tx which is no longer")
print("conflicted has not resumed causing its inputs to be seen as spent. See Issue #7315")
print(str(balance) + " -> " + str(newbalance) + " ?")
if __name__ == '__main__':
AbandonConflictTest().main()

View File

@@ -1,17 +1,15 @@
#!/usr/bin/env python2
#
# Distributed under the MIT/X11 software license, see the accompanying
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
from test_framework.test_framework import ComparisonTestFramework
from test_framework.util import *
from test_framework.mininode import CTransaction, NetworkThread
from test_framework.blocktools import create_coinbase, create_block
from test_framework.comptool import TestInstance, TestManager
from test_framework.script import CScript, OP_1NEGATE, OP_NOP2, OP_DROP
from binascii import hexlify, unhexlify
import cStringIO
from test_framework.script import CScript, OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP
from io import BytesIO
import time
def cltv_invalidate(tx):
@@ -19,7 +17,7 @@ def cltv_invalidate(tx):
Prepends -1 CLTV DROP in the scriptSig itself.
'''
tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_NOP2, OP_DROP] +
tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_CHECKLOCKTIMEVERIFY, OP_DROP] +
list(CScript(tx.vin[0].scriptSig)))
'''
@@ -60,7 +58,7 @@ class BIP65Test(ComparisonTestFramework):
rawtx = node.createrawtransaction(inputs, outputs)
signresult = node.signrawtransaction(rawtx)
tx = CTransaction()
f = cStringIO.StringIO(unhexlify(signresult['hex']))
f = BytesIO(hex_str_to_bytes(signresult['hex']))
tx.deserialize(f)
return tx
@@ -68,13 +66,13 @@ class BIP65Test(ComparisonTestFramework):
self.coinbase_blocks = self.nodes[0].generate(2)
height = 3 # height of the next block to build
self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0)
self.nodeaddress = self.nodes[0].getnewaddress()
self.last_block_time = time.time()
self.last_block_time = int(time.time())
''' 98 more version 3 blocks '''
test_blocks = []
for i in xrange(98):
for i in range(98):
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 3
block.rehash()
@@ -87,7 +85,7 @@ class BIP65Test(ComparisonTestFramework):
''' Mine 749 version 4 blocks '''
test_blocks = []
for i in xrange(749):
for i in range(749):
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 4
block.rehash()
@@ -139,7 +137,7 @@ class BIP65Test(ComparisonTestFramework):
''' Mine 199 new version blocks on last valid tip '''
test_blocks = []
for i in xrange(199):
for i in range(199):
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 4
block.rehash()

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2015 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -9,8 +9,6 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import os
import shutil
class BIP65Test(BitcoinTestFramework):
@@ -34,7 +32,7 @@ class BIP65Test(BitcoinTestFramework):
raise AssertionError("Failed to mine 100 version=3 blocks")
# Mine 750 new-version blocks
for i in xrange(15):
for i in range(15):
self.nodes[2].generate(50)
self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 850):
@@ -46,12 +44,12 @@ class BIP65Test(BitcoinTestFramework):
self.nodes[2].generate(1)
self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 851):
raise AssertionFailure("Failed to mine a version=4 blocks")
raise AssertionError("Failed to mine a version=4 blocks")
# TODO: check that new CHECKLOCKTIMEVERIFY rules are enforced
# Mine 198 new-version blocks
for i in xrange(2):
for i in range(2):
self.nodes[2].generate(99)
self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 1049):

538
qa/rpc-tests/bip68-112-113-p2p.py Executable file
View File

@@ -0,0 +1,538 @@
#!/usr/bin/env python3
# Copyright (c) 2015 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.test_framework import ComparisonTestFramework
from test_framework.util import *
from test_framework.mininode import ToHex, CTransaction, NetworkThread
from test_framework.blocktools import create_coinbase, create_block
from test_framework.comptool import TestInstance, TestManager
from test_framework.script import *
from io import BytesIO
import time
'''
This test is meant to exercise activation of the first version bits soft fork
This soft fork will activate the following BIPS:
BIP 68 - nSequence relative lock times
BIP 112 - CHECKSEQUENCEVERIFY
BIP 113 - MedianTimePast semantics for nLockTime
regtest lock-in with 108/144 block signalling
activation after a further 144 blocks
mine 82 blocks whose coinbases will be used to generate inputs for our tests
mine 61 blocks to transition from DEFINED to STARTED
mine 144 blocks only 100 of which are signaling readiness in order to fail to change state this period
mine 144 blocks with 108 signaling and verify STARTED->LOCKED_IN
mine 140 blocks and seed block chain with the 82 inputs will use for our tests at height 572
mine 3 blocks and verify still at LOCKED_IN and test that enforcement has not triggered
mine 1 block and test that enforcement has triggered (which triggers ACTIVE)
Test BIP 113 is enforced
Mine 4 blocks so next height is 580 and test BIP 68 is enforced for time and height
Mine 1 block so next height is 581 and test BIP 68 now passes time but not height
Mine 1 block so next height is 582 and test BIP 68 now passes time and height
Test that BIP 112 is enforced
Various transactions will be used to test that the BIPs rules are not enforced before the soft fork activates
And that after the soft fork activates transactions pass and fail as they should according to the rules.
For each BIP, transactions of versions 1 and 2 will be tested.
----------------
BIP 113:
bip113tx - modify the nLocktime variable
BIP 68:
bip68txs - 16 txs with nSequence relative locktime of 10 with various bits set as per the relative_locktimes below
BIP 112:
bip112txs_vary_nSequence - 16 txs with nSequence relative_locktimes of 10 evaluated against 10 OP_CSV OP_DROP
bip112txs_vary_nSequence_9 - 16 txs with nSequence relative_locktimes of 9 evaluated against 10 OP_CSV OP_DROP
bip112txs_vary_OP_CSV - 16 txs with nSequence = 10 evaluated against varying {relative_locktimes of 10} OP_CSV OP_DROP
bip112txs_vary_OP_CSV_9 - 16 txs with nSequence = 9 evaluated against varying {relative_locktimes of 10} OP_CSV OP_DROP
bip112tx_special - test negative argument to OP_CSV
'''
base_relative_locktime = 10
seq_disable_flag = 1<<31
seq_random_high_bit = 1<<25
seq_type_flag = 1<<22
seq_random_low_bit = 1<<18
# b31,b25,b22,b18 represent the 31st, 25th, 22nd and 18th bits respectively in the nSequence field
# relative_locktimes[b31][b25][b22][b18] is a base_relative_locktime with the indicated bits set if their indices are 1
relative_locktimes = []
for b31 in range(2):
b25times = []
for b25 in range(2):
b22times = []
for b22 in range(2):
b18times = []
for b18 in range(2):
rlt = base_relative_locktime
if (b31):
rlt = rlt | seq_disable_flag
if (b25):
rlt = rlt | seq_random_high_bit
if (b22):
rlt = rlt | seq_type_flag
if (b18):
rlt = rlt | seq_random_low_bit
b18times.append(rlt)
b22times.append(b18times)
b25times.append(b22times)
relative_locktimes.append(b25times)
def all_rlt_txs(txarray):
txs = []
for b31 in range(2):
for b25 in range(2):
for b22 in range(2):
for b18 in range(2):
txs.append(txarray[b31][b25][b22][b18])
return txs
class BIP68_112_113Test(ComparisonTestFramework):
def __init__(self):
self.num_nodes = 1
def setup_network(self):
# Must set the blockversion for this test
self.nodes = start_nodes(1, self.options.tmpdir,
extra_args=[['-debug', '-whitelist=127.0.0.1', '-blockversion=4']],
binary=[self.options.testbinary])
def run_test(self):
test = TestManager(self, self.options.tmpdir)
test.add_all_connections(self.nodes)
NetworkThread().start() # Start up network handling in another thread
test.run()
def send_generic_input_tx(self, node, coinbases):
amount = Decimal("49.99")
return node.sendrawtransaction(ToHex(self.sign_transaction(node, self.create_transaction(node, node.getblock(coinbases.pop())['tx'][0], self.nodeaddress, amount))))
def create_transaction(self, node, txid, to_address, amount):
inputs = [{ "txid" : txid, "vout" : 0}]
outputs = { to_address : amount }
rawtx = node.createrawtransaction(inputs, outputs)
tx = CTransaction()
f = BytesIO(hex_str_to_bytes(rawtx))
tx.deserialize(f)
return tx
def sign_transaction(self, node, unsignedtx):
rawtx = ToHex(unsignedtx)
signresult = node.signrawtransaction(rawtx)
tx = CTransaction()
f = BytesIO(hex_str_to_bytes(signresult['hex']))
tx.deserialize(f)
return tx
def generate_blocks(self, number, version, test_blocks = []):
for i in range(number):
block = self.create_test_block([], version)
test_blocks.append([block, True])
self.last_block_time += 600
self.tip = block.sha256
self.tipheight += 1
return test_blocks
def create_test_block(self, txs, version = 536870912):
block = create_block(self.tip, create_coinbase(self.tipheight + 1), self.last_block_time + 600)
block.nVersion = version
block.vtx.extend(txs)
block.hashMerkleRoot = block.calc_merkle_root()
block.rehash()
block.solve()
return block
def create_bip68txs(self, bip68inputs, txversion, locktime_delta = 0):
txs = []
assert(len(bip68inputs) >= 16)
i = 0
for b31 in range(2):
b25txs = []
for b25 in range(2):
b22txs = []
for b22 in range(2):
b18txs = []
for b18 in range(2):
tx = self.create_transaction(self.nodes[0], bip68inputs[i], self.nodeaddress, Decimal("49.98"))
i += 1
tx.nVersion = txversion
tx.vin[0].nSequence = relative_locktimes[b31][b25][b22][b18] + locktime_delta
b18txs.append(self.sign_transaction(self.nodes[0], tx))
b22txs.append(b18txs)
b25txs.append(b22txs)
txs.append(b25txs)
return txs
def create_bip112special(self, input, txversion):
tx = self.create_transaction(self.nodes[0], input, self.nodeaddress, Decimal("49.98"))
tx.nVersion = txversion
signtx = self.sign_transaction(self.nodes[0], tx)
signtx.vin[0].scriptSig = CScript([-1, OP_CHECKSEQUENCEVERIFY, OP_DROP] + list(CScript(signtx.vin[0].scriptSig)))
return signtx
def create_bip112txs(self, bip112inputs, varyOP_CSV, txversion, locktime_delta = 0):
txs = []
assert(len(bip112inputs) >= 16)
i = 0
for b31 in range(2):
b25txs = []
for b25 in range(2):
b22txs = []
for b22 in range(2):
b18txs = []
for b18 in range(2):
tx = self.create_transaction(self.nodes[0], bip112inputs[i], self.nodeaddress, Decimal("49.98"))
i += 1
if (varyOP_CSV): # if varying OP_CSV, nSequence is fixed
tx.vin[0].nSequence = base_relative_locktime + locktime_delta
else: # vary nSequence instead, OP_CSV is fixed
tx.vin[0].nSequence = relative_locktimes[b31][b25][b22][b18] + locktime_delta
tx.nVersion = txversion
signtx = self.sign_transaction(self.nodes[0], tx)
if (varyOP_CSV):
signtx.vin[0].scriptSig = CScript([relative_locktimes[b31][b25][b22][b18], OP_CHECKSEQUENCEVERIFY, OP_DROP] + list(CScript(signtx.vin[0].scriptSig)))
else:
signtx.vin[0].scriptSig = CScript([base_relative_locktime, OP_CHECKSEQUENCEVERIFY, OP_DROP] + list(CScript(signtx.vin[0].scriptSig)))
b18txs.append(signtx)
b22txs.append(b18txs)
b25txs.append(b22txs)
txs.append(b25txs)
return txs
def get_tests(self):
long_past_time = int(time.time()) - 600 * 1000 # enough to build up to 1000 blocks 10 minutes apart without worrying about getting into the future
self.nodes[0].setmocktime(long_past_time - 100) # enough so that the generated blocks will still all be before long_past_time
self.coinbase_blocks = self.nodes[0].generate(1 + 16 + 2*32 + 1) # 82 blocks generated for inputs
self.nodes[0].setmocktime(0) # set time back to present so yielded blocks aren't in the future as we advance last_block_time
self.tipheight = 82 # height of the next block to build
self.last_block_time = long_past_time
self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0)
self.nodeaddress = self.nodes[0].getnewaddress()
assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'defined')
test_blocks = self.generate_blocks(61, 4)
yield TestInstance(test_blocks, sync_every_block=False) # 1
# Advanced from DEFINED to STARTED, height = 143
assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'started')
# Fail to achieve LOCKED_IN 100 out of 144 signal bit 0
# using a variety of bits to simulate multiple parallel softforks
test_blocks = self.generate_blocks(50, 536870913) # 0x20000001 (signalling ready)
test_blocks = self.generate_blocks(20, 4, test_blocks) # 0x00000004 (signalling not)
test_blocks = self.generate_blocks(50, 536871169, test_blocks) # 0x20000101 (signalling ready)
test_blocks = self.generate_blocks(24, 536936448, test_blocks) # 0x20010000 (signalling not)
yield TestInstance(test_blocks, sync_every_block=False) # 2
# Failed to advance past STARTED, height = 287
assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'started')
# 108 out of 144 signal bit 0 to achieve lock-in
# using a variety of bits to simulate multiple parallel softforks
test_blocks = self.generate_blocks(58, 536870913) # 0x20000001 (signalling ready)
test_blocks = self.generate_blocks(26, 4, test_blocks) # 0x00000004 (signalling not)
test_blocks = self.generate_blocks(50, 536871169, test_blocks) # 0x20000101 (signalling ready)
test_blocks = self.generate_blocks(10, 536936448, test_blocks) # 0x20010000 (signalling not)
yield TestInstance(test_blocks, sync_every_block=False) # 3
# Advanced from STARTED to LOCKED_IN, height = 431
assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'locked_in')
# 140 more version 4 blocks
test_blocks = self.generate_blocks(140, 4)
yield TestInstance(test_blocks, sync_every_block=False) # 4
### Inputs at height = 572
# Put inputs for all tests in the chain at height 572 (tip now = 571) (time increases by 600s per block)
# Note we reuse inputs for v1 and v2 txs so must test these separately
# 16 normal inputs
bip68inputs = []
for i in range(16):
bip68inputs.append(self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks))
# 2 sets of 16 inputs with 10 OP_CSV OP_DROP (actually will be prepended to spending scriptSig)
bip112basicinputs = []
for j in range(2):
inputs = []
for i in range(16):
inputs.append(self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks))
bip112basicinputs.append(inputs)
# 2 sets of 16 varied inputs with (relative_lock_time) OP_CSV OP_DROP (actually will be prepended to spending scriptSig)
bip112diverseinputs = []
for j in range(2):
inputs = []
for i in range(16):
inputs.append(self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks))
bip112diverseinputs.append(inputs)
# 1 special input with -1 OP_CSV OP_DROP (actually will be prepended to spending scriptSig)
bip112specialinput = self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks)
# 1 normal input
bip113input = self.send_generic_input_tx(self.nodes[0], self.coinbase_blocks)
self.nodes[0].setmocktime(self.last_block_time + 600)
inputblockhash = self.nodes[0].generate(1)[0] # 1 block generated for inputs to be in chain at height 572
self.nodes[0].setmocktime(0)
self.tip = int("0x" + inputblockhash, 0)
self.tipheight += 1
self.last_block_time += 600
assert_equal(len(self.nodes[0].getblock(inputblockhash,True)["tx"]), 82+1)
# 2 more version 4 blocks
test_blocks = self.generate_blocks(2, 4)
yield TestInstance(test_blocks, sync_every_block=False) # 5
# Not yet advanced to ACTIVE, height = 574 (will activate for block 576, not 575)
assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'locked_in')
# Test both version 1 and version 2 transactions for all tests
# BIP113 test transaction will be modified before each use to put in appropriate block time
bip113tx_v1 = self.create_transaction(self.nodes[0], bip113input, self.nodeaddress, Decimal("49.98"))
bip113tx_v1.vin[0].nSequence = 0xFFFFFFFE
bip113tx_v2 = self.create_transaction(self.nodes[0], bip113input, self.nodeaddress, Decimal("49.98"))
bip113tx_v2.vin[0].nSequence = 0xFFFFFFFE
bip113tx_v2.nVersion = 2
# For BIP68 test all 16 relative sequence locktimes
bip68txs_v1 = self.create_bip68txs(bip68inputs, 1)
bip68txs_v2 = self.create_bip68txs(bip68inputs, 2)
# For BIP112 test:
# 16 relative sequence locktimes of 10 against 10 OP_CSV OP_DROP inputs
bip112txs_vary_nSequence_v1 = self.create_bip112txs(bip112basicinputs[0], False, 1)
bip112txs_vary_nSequence_v2 = self.create_bip112txs(bip112basicinputs[0], False, 2)
# 16 relative sequence locktimes of 9 against 10 OP_CSV OP_DROP inputs
bip112txs_vary_nSequence_9_v1 = self.create_bip112txs(bip112basicinputs[1], False, 1, -1)
bip112txs_vary_nSequence_9_v2 = self.create_bip112txs(bip112basicinputs[1], False, 2, -1)
# sequence lock time of 10 against 16 (relative_lock_time) OP_CSV OP_DROP inputs
bip112txs_vary_OP_CSV_v1 = self.create_bip112txs(bip112diverseinputs[0], True, 1)
bip112txs_vary_OP_CSV_v2 = self.create_bip112txs(bip112diverseinputs[0], True, 2)
# sequence lock time of 9 against 16 (relative_lock_time) OP_CSV OP_DROP inputs
bip112txs_vary_OP_CSV_9_v1 = self.create_bip112txs(bip112diverseinputs[1], True, 1, -1)
bip112txs_vary_OP_CSV_9_v2 = self.create_bip112txs(bip112diverseinputs[1], True, 2, -1)
# -1 OP_CSV OP_DROP input
bip112tx_special_v1 = self.create_bip112special(bip112specialinput, 1)
bip112tx_special_v2 = self.create_bip112special(bip112specialinput, 2)
### TESTING ###
##################################
### Before Soft Forks Activate ###
##################################
# All txs should pass
### Version 1 txs ###
success_txs = []
# add BIP113 tx and -1 CSV tx
bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 # = MTP of prior block (not <) but < time put on current block
bip113signed1 = self.sign_transaction(self.nodes[0], bip113tx_v1)
success_txs.append(bip113signed1)
success_txs.append(bip112tx_special_v1)
# add BIP 68 txs
success_txs.extend(all_rlt_txs(bip68txs_v1))
# add BIP 112 with seq=10 txs
success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_v1))
success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_v1))
# try BIP 112 with seq=9 txs
success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v1))
success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_9_v1))
yield TestInstance([[self.create_test_block(success_txs), True]]) # 6
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
### Version 2 txs ###
success_txs = []
# add BIP113 tx and -1 CSV tx
bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 # = MTP of prior block (not <) but < time put on current block
bip113signed2 = self.sign_transaction(self.nodes[0], bip113tx_v2)
success_txs.append(bip113signed2)
success_txs.append(bip112tx_special_v2)
# add BIP 68 txs
success_txs.extend(all_rlt_txs(bip68txs_v2))
# add BIP 112 with seq=10 txs
success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_v2))
success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_v2))
# try BIP 112 with seq=9 txs
success_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v2))
success_txs.extend(all_rlt_txs(bip112txs_vary_OP_CSV_9_v2))
yield TestInstance([[self.create_test_block(success_txs), True]]) # 7
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
# 1 more version 4 block to get us to height 575 so the fork should now be active for the next block
test_blocks = self.generate_blocks(1, 4)
yield TestInstance(test_blocks, sync_every_block=False) # 8
assert_equal(get_bip9_status(self.nodes[0], 'csv')['status'], 'active')
#################################
### After Soft Forks Activate ###
#################################
### BIP 113 ###
# BIP 113 tests should now fail regardless of version number if nLockTime isn't satisfied by new rules
bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 # = MTP of prior block (not <) but < time put on current block
bip113signed1 = self.sign_transaction(self.nodes[0], bip113tx_v1)
bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 # = MTP of prior block (not <) but < time put on current block
bip113signed2 = self.sign_transaction(self.nodes[0], bip113tx_v2)
for bip113tx in [bip113signed1, bip113signed2]:
yield TestInstance([[self.create_test_block([bip113tx]), False]]) # 9,10
# BIP 113 tests should now pass if the locktime is < MTP
bip113tx_v1.nLockTime = self.last_block_time - 600 * 5 - 1 # < MTP of prior block
bip113signed1 = self.sign_transaction(self.nodes[0], bip113tx_v1)
bip113tx_v2.nLockTime = self.last_block_time - 600 * 5 - 1 # < MTP of prior block
bip113signed2 = self.sign_transaction(self.nodes[0], bip113tx_v2)
for bip113tx in [bip113signed1, bip113signed2]:
yield TestInstance([[self.create_test_block([bip113tx]), True]]) # 11,12
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
# Next block height = 580 after 4 blocks of random version
test_blocks = self.generate_blocks(4, 1234)
yield TestInstance(test_blocks, sync_every_block=False) # 13
### BIP 68 ###
### Version 1 txs ###
# All still pass
success_txs = []
success_txs.extend(all_rlt_txs(bip68txs_v1))
yield TestInstance([[self.create_test_block(success_txs), True]]) # 14
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
### Version 2 txs ###
bip68success_txs = []
# All txs with SEQUENCE_LOCKTIME_DISABLE_FLAG set pass
for b25 in range(2):
for b22 in range(2):
for b18 in range(2):
bip68success_txs.append(bip68txs_v2[1][b25][b22][b18])
yield TestInstance([[self.create_test_block(bip68success_txs), True]]) # 15
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
# All txs without flag fail as we are at delta height = 8 < 10 and delta time = 8 * 600 < 10 * 512
bip68timetxs = []
for b25 in range(2):
for b18 in range(2):
bip68timetxs.append(bip68txs_v2[0][b25][1][b18])
for tx in bip68timetxs:
yield TestInstance([[self.create_test_block([tx]), False]]) # 16 - 19
bip68heighttxs = []
for b25 in range(2):
for b18 in range(2):
bip68heighttxs.append(bip68txs_v2[0][b25][0][b18])
for tx in bip68heighttxs:
yield TestInstance([[self.create_test_block([tx]), False]]) # 20 - 23
# Advance one block to 581
test_blocks = self.generate_blocks(1, 1234)
yield TestInstance(test_blocks, sync_every_block=False) # 24
# Height txs should fail and time txs should now pass 9 * 600 > 10 * 512
bip68success_txs.extend(bip68timetxs)
yield TestInstance([[self.create_test_block(bip68success_txs), True]]) # 25
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
for tx in bip68heighttxs:
yield TestInstance([[self.create_test_block([tx]), False]]) # 26 - 29
# Advance one block to 582
test_blocks = self.generate_blocks(1, 1234)
yield TestInstance(test_blocks, sync_every_block=False) # 30
# All BIP 68 txs should pass
bip68success_txs.extend(bip68heighttxs)
yield TestInstance([[self.create_test_block(bip68success_txs), True]]) # 31
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
### BIP 112 ###
### Version 1 txs ###
# -1 OP_CSV tx should fail
yield TestInstance([[self.create_test_block([bip112tx_special_v1]), False]]) #32
# If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in argument to OP_CSV, version 1 txs should still pass
success_txs = []
for b25 in range(2):
for b22 in range(2):
for b18 in range(2):
success_txs.append(bip112txs_vary_OP_CSV_v1[1][b25][b22][b18])
success_txs.append(bip112txs_vary_OP_CSV_9_v1[1][b25][b22][b18])
yield TestInstance([[self.create_test_block(success_txs), True]]) # 33
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
# If SEQUENCE_LOCKTIME_DISABLE_FLAG is unset in argument to OP_CSV, version 1 txs should now fail
fail_txs = []
fail_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_v1))
fail_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v1))
for b25 in range(2):
for b22 in range(2):
for b18 in range(2):
fail_txs.append(bip112txs_vary_OP_CSV_v1[0][b25][b22][b18])
fail_txs.append(bip112txs_vary_OP_CSV_9_v1[0][b25][b22][b18])
for tx in fail_txs:
yield TestInstance([[self.create_test_block([tx]), False]]) # 34 - 81
### Version 2 txs ###
# -1 OP_CSV tx should fail
yield TestInstance([[self.create_test_block([bip112tx_special_v2]), False]]) #82
# If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in argument to OP_CSV, version 2 txs should pass (all sequence locks are met)
success_txs = []
for b25 in range(2):
for b22 in range(2):
for b18 in range(2):
success_txs.append(bip112txs_vary_OP_CSV_v2[1][b25][b22][b18]) # 8/16 of vary_OP_CSV
success_txs.append(bip112txs_vary_OP_CSV_9_v2[1][b25][b22][b18]) # 8/16 of vary_OP_CSV_9
yield TestInstance([[self.create_test_block(success_txs), True]]) # 83
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
## SEQUENCE_LOCKTIME_DISABLE_FLAG is unset in argument to OP_CSV for all remaining txs ##
# All txs with nSequence 9 should fail either due to earlier mismatch or failing the CSV check
fail_txs = []
fail_txs.extend(all_rlt_txs(bip112txs_vary_nSequence_9_v2)) # 16/16 of vary_nSequence_9
for b25 in range(2):
for b22 in range(2):
for b18 in range(2):
fail_txs.append(bip112txs_vary_OP_CSV_9_v2[0][b25][b22][b18]) # 16/16 of vary_OP_CSV_9
for tx in fail_txs:
yield TestInstance([[self.create_test_block([tx]), False]]) # 84 - 107
# If SEQUENCE_LOCKTIME_DISABLE_FLAG is set in nSequence, tx should fail
fail_txs = []
for b25 in range(2):
for b22 in range(2):
for b18 in range(2):
fail_txs.append(bip112txs_vary_nSequence_v2[1][b25][b22][b18]) # 8/16 of vary_nSequence
for tx in fail_txs:
yield TestInstance([[self.create_test_block([tx]), False]]) # 108-115
# If sequencelock types mismatch, tx should fail
fail_txs = []
for b25 in range(2):
for b18 in range(2):
fail_txs.append(bip112txs_vary_nSequence_v2[0][b25][1][b18]) # 12/16 of vary_nSequence
fail_txs.append(bip112txs_vary_OP_CSV_v2[0][b25][1][b18]) # 12/16 of vary_OP_CSV
for tx in fail_txs:
yield TestInstance([[self.create_test_block([tx]), False]]) # 116-123
# Remaining txs should pass, just test masking works properly
success_txs = []
for b25 in range(2):
for b18 in range(2):
success_txs.append(bip112txs_vary_nSequence_v2[0][b25][0][b18]) # 16/16 of vary_nSequence
success_txs.append(bip112txs_vary_OP_CSV_v2[0][b25][0][b18]) # 16/16 of vary_OP_CSV
yield TestInstance([[self.create_test_block(success_txs), True]]) # 124
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
# Additional test, of checking that comparison of two time types works properly
time_txs = []
for b25 in range(2):
for b18 in range(2):
tx = bip112txs_vary_OP_CSV_v2[0][b25][1][b18]
tx.vin[0].nSequence = base_relative_locktime | seq_type_flag
signtx = self.sign_transaction(self.nodes[0], tx)
time_txs.append(signtx)
yield TestInstance([[self.create_test_block(time_txs), True]]) # 125
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
### Missing aspects of test
## Testing empty stack fails
if __name__ == '__main__':
BIP68_112_113Test().main()

424
qa/rpc-tests/bip68-sequence.py Executable file
View File

@@ -0,0 +1,424 @@
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
# Test BIP68 implementation
#
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from test_framework.script import *
from test_framework.mininode import *
from test_framework.blocktools import *
SEQUENCE_LOCKTIME_DISABLE_FLAG = (1<<31)
SEQUENCE_LOCKTIME_TYPE_FLAG = (1<<22) # this means use time (0 means height)
SEQUENCE_LOCKTIME_GRANULARITY = 9 # this is a bit-shift
SEQUENCE_LOCKTIME_MASK = 0x0000ffff
# RPC error for non-BIP68 final transactions
NOT_FINAL_ERROR = "64: non-BIP68-final"
class BIP68Test(BitcoinTestFramework):
def setup_network(self):
self.nodes = []
self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-blockprioritysize=0"]))
self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-blockprioritysize=0", "-acceptnonstdtxn=0"]))
self.is_network_split = False
self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"]
connect_nodes(self.nodes[0], 1)
def run_test(self):
# Generate some coins
self.nodes[0].generate(110)
print("Running test disable flag")
self.test_disable_flag()
print("Running test sequence-lock-confirmed-inputs")
self.test_sequence_lock_confirmed_inputs()
print("Running test sequence-lock-unconfirmed-inputs")
self.test_sequence_lock_unconfirmed_inputs()
print("Running test BIP68 not consensus before versionbits activation")
self.test_bip68_not_consensus()
print("Verifying nVersion=2 transactions aren't standard")
self.test_version2_relay(before_activation=True)
print("Activating BIP68 (and 112/113)")
self.activateCSV()
print("Verifying nVersion=2 transactions are now standard")
self.test_version2_relay(before_activation=False)
print("Passed\n")
# Test that BIP68 is not in effect if tx version is 1, or if
# the first sequence bit is set.
def test_disable_flag(self):
# Create some unconfirmed inputs
new_addr = self.nodes[0].getnewaddress()
self.nodes[0].sendtoaddress(new_addr, 2) # send 2 BTC
utxos = self.nodes[0].listunspent(0, 0)
assert(len(utxos) > 0)
utxo = utxos[0]
tx1 = CTransaction()
value = int(satoshi_round(utxo["amount"] - self.relayfee)*COIN)
# Check that the disable flag disables relative locktime.
# If sequence locks were used, this would require 1 block for the
# input to mature.
sequence_value = SEQUENCE_LOCKTIME_DISABLE_FLAG | 1
tx1.vin = [CTxIn(COutPoint(int(utxo["txid"], 16), utxo["vout"]), nSequence=sequence_value)]
tx1.vout = [CTxOut(value, CScript([b'a']))]
tx1_signed = self.nodes[0].signrawtransaction(ToHex(tx1))["hex"]
tx1_id = self.nodes[0].sendrawtransaction(tx1_signed)
tx1_id = int(tx1_id, 16)
# This transaction will enable sequence-locks, so this transaction should
# fail
tx2 = CTransaction()
tx2.nVersion = 2
sequence_value = sequence_value & 0x7fffffff
tx2.vin = [CTxIn(COutPoint(tx1_id, 0), nSequence=sequence_value)]
tx2.vout = [CTxOut(int(value-self.relayfee*COIN), CScript([b'a']))]
tx2.rehash()
try:
self.nodes[0].sendrawtransaction(ToHex(tx2))
except JSONRPCException as exp:
assert_equal(exp.error["message"], NOT_FINAL_ERROR)
else:
assert(False)
# Setting the version back down to 1 should disable the sequence lock,
# so this should be accepted.
tx2.nVersion = 1
self.nodes[0].sendrawtransaction(ToHex(tx2))
# Calculate the median time past of a prior block ("confirmations" before
# the current tip).
def get_median_time_past(self, confirmations):
block_hash = self.nodes[0].getblockhash(self.nodes[0].getblockcount()-confirmations)
return self.nodes[0].getblockheader(block_hash)["mediantime"]
# Test that sequence locks are respected for transactions spending confirmed inputs.
def test_sequence_lock_confirmed_inputs(self):
# Create lots of confirmed utxos, and use them to generate lots of random
# transactions.
max_outputs = 50
addresses = []
while len(addresses) < max_outputs:
addresses.append(self.nodes[0].getnewaddress())
while len(self.nodes[0].listunspent()) < 200:
import random
random.shuffle(addresses)
num_outputs = random.randint(1, max_outputs)
outputs = {}
for i in range(num_outputs):
outputs[addresses[i]] = random.randint(1, 20)*0.01
self.nodes[0].sendmany("", outputs)
self.nodes[0].generate(1)
utxos = self.nodes[0].listunspent()
# Try creating a lot of random transactions.
# Each time, choose a random number of inputs, and randomly set
# some of those inputs to be sequence locked (and randomly choose
# between height/time locking). Small random chance of making the locks
# all pass.
for i in range(400):
# Randomly choose up to 10 inputs
num_inputs = random.randint(1, 10)
random.shuffle(utxos)
# Track whether any sequence locks used should fail
should_pass = True
# Track whether this transaction was built with sequence locks
using_sequence_locks = False
tx = CTransaction()
tx.nVersion = 2
value = 0
for j in range(num_inputs):
sequence_value = 0xfffffffe # this disables sequence locks
# 50% chance we enable sequence locks
if random.randint(0,1):
using_sequence_locks = True
# 10% of the time, make the input sequence value pass
input_will_pass = (random.randint(1,10) == 1)
sequence_value = utxos[j]["confirmations"]
if not input_will_pass:
sequence_value += 1
should_pass = False
# Figure out what the median-time-past was for the confirmed input
# Note that if an input has N confirmations, we're going back N blocks
# from the tip so that we're looking up MTP of the block
# PRIOR to the one the input appears in, as per the BIP68 spec.
orig_time = self.get_median_time_past(utxos[j]["confirmations"])
cur_time = self.get_median_time_past(0) # MTP of the tip
# can only timelock this input if it's not too old -- otherwise use height
can_time_lock = True
if ((cur_time - orig_time) >> SEQUENCE_LOCKTIME_GRANULARITY) >= SEQUENCE_LOCKTIME_MASK:
can_time_lock = False
# if time-lockable, then 50% chance we make this a time lock
if random.randint(0,1) and can_time_lock:
# Find first time-lock value that fails, or latest one that succeeds
time_delta = sequence_value << SEQUENCE_LOCKTIME_GRANULARITY
if input_will_pass and time_delta > cur_time - orig_time:
sequence_value = ((cur_time - orig_time) >> SEQUENCE_LOCKTIME_GRANULARITY)
elif (not input_will_pass and time_delta <= cur_time - orig_time):
sequence_value = ((cur_time - orig_time) >> SEQUENCE_LOCKTIME_GRANULARITY)+1
sequence_value |= SEQUENCE_LOCKTIME_TYPE_FLAG
tx.vin.append(CTxIn(COutPoint(int(utxos[j]["txid"], 16), utxos[j]["vout"]), nSequence=sequence_value))
value += utxos[j]["amount"]*COIN
# Overestimate the size of the tx - signatures should be less than 120 bytes, and leave 50 for the output
tx_size = len(ToHex(tx))//2 + 120*num_inputs + 50
tx.vout.append(CTxOut(int(value-self.relayfee*tx_size*COIN/1000), CScript([b'a'])))
rawtx = self.nodes[0].signrawtransaction(ToHex(tx))["hex"]
try:
self.nodes[0].sendrawtransaction(rawtx)
except JSONRPCException as exp:
assert(not should_pass and using_sequence_locks)
assert_equal(exp.error["message"], NOT_FINAL_ERROR)
else:
assert(should_pass or not using_sequence_locks)
# Recalculate utxos if we successfully sent the transaction
utxos = self.nodes[0].listunspent()
# Test that sequence locks on unconfirmed inputs must have nSequence
# height or time of 0 to be accepted.
# Then test that BIP68-invalid transactions are removed from the mempool
# after a reorg.
def test_sequence_lock_unconfirmed_inputs(self):
# Store height so we can easily reset the chain at the end of the test
cur_height = self.nodes[0].getblockcount()
# Create a mempool tx.
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 2)
tx1 = FromHex(CTransaction(), self.nodes[0].getrawtransaction(txid))
tx1.rehash()
# Anyone-can-spend mempool tx.
# Sequence lock of 0 should pass.
tx2 = CTransaction()
tx2.nVersion = 2
tx2.vin = [CTxIn(COutPoint(tx1.sha256, 0), nSequence=0)]
tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))]
tx2_raw = self.nodes[0].signrawtransaction(ToHex(tx2))["hex"]
tx2 = FromHex(tx2, tx2_raw)
tx2.rehash()
self.nodes[0].sendrawtransaction(tx2_raw)
# Create a spend of the 0th output of orig_tx with a sequence lock
# of 1, and test what happens when submitting.
# orig_tx.vout[0] must be an anyone-can-spend output
def test_nonzero_locks(orig_tx, node, relayfee, use_height_lock):
sequence_value = 1
if not use_height_lock:
sequence_value |= SEQUENCE_LOCKTIME_TYPE_FLAG
tx = CTransaction()
tx.nVersion = 2
tx.vin = [CTxIn(COutPoint(orig_tx.sha256, 0), nSequence=sequence_value)]
tx.vout = [CTxOut(int(orig_tx.vout[0].nValue - relayfee*COIN), CScript([b'a']))]
tx.rehash()
try:
node.sendrawtransaction(ToHex(tx))
except JSONRPCException as exp:
assert_equal(exp.error["message"], NOT_FINAL_ERROR)
assert(orig_tx.hash in node.getrawmempool())
else:
# orig_tx must not be in mempool
assert(orig_tx.hash not in node.getrawmempool())
return tx
test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=True)
test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=False)
# Now mine some blocks, but make sure tx2 doesn't get mined.
# Use prioritisetransaction to lower the effective feerate to 0
self.nodes[0].prioritisetransaction(tx2.hash, -1e15, int(-self.relayfee*COIN))
cur_time = int(time.time())
for i in range(10):
self.nodes[0].setmocktime(cur_time + 600)
self.nodes[0].generate(1)
cur_time += 600
assert(tx2.hash in self.nodes[0].getrawmempool())
test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=True)
test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=False)
# Mine tx2, and then try again
self.nodes[0].prioritisetransaction(tx2.hash, 1e15, int(self.relayfee*COIN))
# Advance the time on the node so that we can test timelocks
self.nodes[0].setmocktime(cur_time+600)
self.nodes[0].generate(1)
assert(tx2.hash not in self.nodes[0].getrawmempool())
# Now that tx2 is not in the mempool, a sequence locked spend should
# succeed
tx3 = test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=False)
assert(tx3.hash in self.nodes[0].getrawmempool())
self.nodes[0].generate(1)
assert(tx3.hash not in self.nodes[0].getrawmempool())
# One more test, this time using height locks
tx4 = test_nonzero_locks(tx3, self.nodes[0], self.relayfee, use_height_lock=True)
assert(tx4.hash in self.nodes[0].getrawmempool())
# Now try combining confirmed and unconfirmed inputs
tx5 = test_nonzero_locks(tx4, self.nodes[0], self.relayfee, use_height_lock=True)
assert(tx5.hash not in self.nodes[0].getrawmempool())
utxos = self.nodes[0].listunspent()
tx5.vin.append(CTxIn(COutPoint(int(utxos[0]["txid"], 16), utxos[0]["vout"]), nSequence=1))
tx5.vout[0].nValue += int(utxos[0]["amount"]*COIN)
raw_tx5 = self.nodes[0].signrawtransaction(ToHex(tx5))["hex"]
try:
self.nodes[0].sendrawtransaction(raw_tx5)
except JSONRPCException as exp:
assert_equal(exp.error["message"], NOT_FINAL_ERROR)
else:
assert(False)
# Test mempool-BIP68 consistency after reorg
#
# State of the transactions in the last blocks:
# ... -> [ tx2 ] -> [ tx3 ]
# tip-1 tip
# And currently tx4 is in the mempool.
#
# If we invalidate the tip, tx3 should get added to the mempool, causing
# tx4 to be removed (fails sequence-lock).
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
assert(tx4.hash not in self.nodes[0].getrawmempool())
assert(tx3.hash in self.nodes[0].getrawmempool())
# Now mine 2 empty blocks to reorg out the current tip (labeled tip-1 in
# diagram above).
# This would cause tx2 to be added back to the mempool, which in turn causes
# tx3 to be removed.
tip = int(self.nodes[0].getblockhash(self.nodes[0].getblockcount()-1), 16)
height = self.nodes[0].getblockcount()
for i in range(2):
block = create_block(tip, create_coinbase(height), cur_time)
block.nVersion = 3
block.rehash()
block.solve()
tip = block.sha256
height += 1
self.nodes[0].submitblock(ToHex(block))
cur_time += 1
mempool = self.nodes[0].getrawmempool()
assert(tx3.hash not in mempool)
assert(tx2.hash in mempool)
# Reset the chain and get rid of the mocktimed-blocks
self.nodes[0].setmocktime(0)
self.nodes[0].invalidateblock(self.nodes[0].getblockhash(cur_height+1))
self.nodes[0].generate(10)
# Make sure that BIP68 isn't being used to validate blocks, prior to
# versionbits activation. If more blocks are mined prior to this test
# being run, then it's possible the test has activated the soft fork, and
# this test should be moved to run earlier, or deleted.
def test_bip68_not_consensus(self):
assert(get_bip9_status(self.nodes[0], 'csv')['status'] != 'active')
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 2)
tx1 = FromHex(CTransaction(), self.nodes[0].getrawtransaction(txid))
tx1.rehash()
# Make an anyone-can-spend transaction
tx2 = CTransaction()
tx2.nVersion = 1
tx2.vin = [CTxIn(COutPoint(tx1.sha256, 0), nSequence=0)]
tx2.vout = [CTxOut(int(tx1.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))]
# sign tx2
tx2_raw = self.nodes[0].signrawtransaction(ToHex(tx2))["hex"]
tx2 = FromHex(tx2, tx2_raw)
tx2.rehash()
self.nodes[0].sendrawtransaction(ToHex(tx2))
# Now make an invalid spend of tx2 according to BIP68
sequence_value = 100 # 100 block relative locktime
tx3 = CTransaction()
tx3.nVersion = 2
tx3.vin = [CTxIn(COutPoint(tx2.sha256, 0), nSequence=sequence_value)]
tx3.vout = [CTxOut(int(tx2.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))]
tx3.rehash()
try:
self.nodes[0].sendrawtransaction(ToHex(tx3))
except JSONRPCException as exp:
assert_equal(exp.error["message"], NOT_FINAL_ERROR)
else:
assert(False)
# make a block that violates bip68; ensure that the tip updates
tip = int(self.nodes[0].getbestblockhash(), 16)
block = create_block(tip, create_coinbase(self.nodes[0].getblockcount()+1))
block.nVersion = 3
block.vtx.extend([tx1, tx2, tx3])
block.hashMerkleRoot = block.calc_merkle_root()
block.rehash()
block.solve()
self.nodes[0].submitblock(ToHex(block))
assert_equal(self.nodes[0].getbestblockhash(), block.hash)
def activateCSV(self):
# activation should happen at block height 432 (3 periods)
min_activation_height = 432
height = self.nodes[0].getblockcount()
assert(height < 432)
self.nodes[0].generate(432-height)
assert(get_bip9_status(self.nodes[0], 'csv')['status'] == 'active')
sync_blocks(self.nodes)
# Use self.nodes[1] to test standardness relay policy
def test_version2_relay(self, before_activation):
inputs = [ ]
outputs = { self.nodes[1].getnewaddress() : 1.0 }
rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
rawtxfund = self.nodes[1].fundrawtransaction(rawtx)['hex']
tx = FromHex(CTransaction(), rawtxfund)
tx.nVersion = 2
tx_signed = self.nodes[1].signrawtransaction(ToHex(tx))["hex"]
try:
tx_id = self.nodes[1].sendrawtransaction(tx_signed)
assert(before_activation == False)
except:
assert(before_activation)
if __name__ == '__main__':
BIP68Test().main()

240
qa/rpc-tests/bip9-softforks.py Executable file
View File

@@ -0,0 +1,240 @@
#!/usr/bin/env python3
# Copyright (c) 2015 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.test_framework import ComparisonTestFramework
from test_framework.util import *
from test_framework.mininode import CTransaction, NetworkThread
from test_framework.blocktools import create_coinbase, create_block
from test_framework.comptool import TestInstance, TestManager
from test_framework.script import CScript, OP_1NEGATE, OP_CHECKSEQUENCEVERIFY, OP_DROP
from io import BytesIO
import time
import itertools
'''
This test is meant to exercise BIP forks
Connect to a single node.
regtest lock-in with 108/144 block signalling
activation after a further 144 blocks
mine 2 block and save coinbases for later use
mine 141 blocks to transition from DEFINED to STARTED
mine 100 blocks signalling readiness and 44 not in order to fail to change state this period
mine 108 blocks signalling readiness and 36 blocks not signalling readiness (STARTED->LOCKED_IN)
mine a further 143 blocks (LOCKED_IN)
test that enforcement has not triggered (which triggers ACTIVE)
test that enforcement has triggered
'''
class BIP9SoftForksTest(ComparisonTestFramework):
def __init__(self):
self.num_nodes = 1
def setup_network(self):
self.nodes = start_nodes(1, self.options.tmpdir,
extra_args=[['-debug', '-whitelist=127.0.0.1']],
binary=[self.options.testbinary])
def run_test(self):
self.test = TestManager(self, self.options.tmpdir)
self.test.add_all_connections(self.nodes)
NetworkThread().start() # Start up network handling in another thread
self.test.run()
def create_transaction(self, node, coinbase, to_address, amount):
from_txid = node.getblock(coinbase)['tx'][0]
inputs = [{ "txid" : from_txid, "vout" : 0}]
outputs = { to_address : amount }
rawtx = node.createrawtransaction(inputs, outputs)
tx = CTransaction()
f = BytesIO(hex_str_to_bytes(rawtx))
tx.deserialize(f)
tx.nVersion = 2
return tx
def sign_transaction(self, node, tx):
signresult = node.signrawtransaction(bytes_to_hex_str(tx.serialize()))
tx = CTransaction()
f = BytesIO(hex_str_to_bytes(signresult['hex']))
tx.deserialize(f)
return tx
def generate_blocks(self, number, version, test_blocks = []):
for i in range(number):
block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1)
block.nVersion = version
block.rehash()
block.solve()
test_blocks.append([block, True])
self.last_block_time += 1
self.tip = block.sha256
self.height += 1
return test_blocks
def get_bip9_status(self, key):
info = self.nodes[0].getblockchaininfo()
for row in info['bip9_softforks']:
if row['id'] == key:
return row
raise IndexError ('key:"%s" not found' % key)
def test_BIP(self, bipName, activated_version, invalidate, invalidatePostSignature, bitno):
# generate some coins for later
self.coinbase_blocks = self.nodes[0].generate(2)
self.height = 3 # height of the next block to build
self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0)
self.nodeaddress = self.nodes[0].getnewaddress()
self.last_block_time = int(time.time())
assert_equal(self.get_bip9_status(bipName)['status'], 'defined')
tmpl = self.nodes[0].getblocktemplate({})
assert(bipName not in tmpl['rules'])
assert(bipName not in tmpl['vbavailable'])
assert_equal(tmpl['vbrequired'], 0)
assert_equal(tmpl['version'], 0x20000000)
# Test 1
# Advance from DEFINED to STARTED
test_blocks = self.generate_blocks(141, 4)
yield TestInstance(test_blocks, sync_every_block=False)
assert_equal(self.get_bip9_status(bipName)['status'], 'started')
tmpl = self.nodes[0].getblocktemplate({})
assert(bipName not in tmpl['rules'])
assert_equal(tmpl['vbavailable'][bipName], bitno)
assert_equal(tmpl['vbrequired'], 0)
assert(tmpl['version'] & activated_version)
# Test 2
# Fail to achieve LOCKED_IN 100 out of 144 signal bit 1
# using a variety of bits to simulate multiple parallel softforks
test_blocks = self.generate_blocks(50, activated_version) # 0x20000001 (signalling ready)
test_blocks = self.generate_blocks(20, 4, test_blocks) # 0x00000004 (signalling not)
test_blocks = self.generate_blocks(50, activated_version, test_blocks) # 0x20000101 (signalling ready)
test_blocks = self.generate_blocks(24, 4, test_blocks) # 0x20010000 (signalling not)
yield TestInstance(test_blocks, sync_every_block=False)
assert_equal(self.get_bip9_status(bipName)['status'], 'started')
tmpl = self.nodes[0].getblocktemplate({})
assert(bipName not in tmpl['rules'])
assert_equal(tmpl['vbavailable'][bipName], bitno)
assert_equal(tmpl['vbrequired'], 0)
assert(tmpl['version'] & activated_version)
# Test 3
# 108 out of 144 signal bit 1 to achieve LOCKED_IN
# using a variety of bits to simulate multiple parallel softforks
test_blocks = self.generate_blocks(58, activated_version) # 0x20000001 (signalling ready)
test_blocks = self.generate_blocks(26, 4, test_blocks) # 0x00000004 (signalling not)
test_blocks = self.generate_blocks(50, activated_version, test_blocks) # 0x20000101 (signalling ready)
test_blocks = self.generate_blocks(10, 4, test_blocks) # 0x20010000 (signalling not)
yield TestInstance(test_blocks, sync_every_block=False)
assert_equal(self.get_bip9_status(bipName)['status'], 'locked_in')
tmpl = self.nodes[0].getblocktemplate({})
assert(bipName not in tmpl['rules'])
# Test 4
# 143 more version 536870913 blocks (waiting period-1)
test_blocks = self.generate_blocks(143, 4)
yield TestInstance(test_blocks, sync_every_block=False)
assert_equal(self.get_bip9_status(bipName)['status'], 'locked_in')
tmpl = self.nodes[0].getblocktemplate({})
assert(bipName not in tmpl['rules'])
# Test 5
# Check that the new rule is enforced
spendtx = self.create_transaction(self.nodes[0],
self.coinbase_blocks[0], self.nodeaddress, 1.0)
invalidate(spendtx)
spendtx = self.sign_transaction(self.nodes[0], spendtx)
spendtx.rehash()
invalidatePostSignature(spendtx)
spendtx.rehash()
block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1)
block.nVersion = activated_version
block.vtx.append(spendtx)
block.hashMerkleRoot = block.calc_merkle_root()
block.rehash()
block.solve()
self.last_block_time += 1
self.tip = block.sha256
self.height += 1
yield TestInstance([[block, True]])
assert_equal(self.get_bip9_status(bipName)['status'], 'active')
tmpl = self.nodes[0].getblocktemplate({})
assert(bipName in tmpl['rules'])
assert(bipName not in tmpl['vbavailable'])
assert_equal(tmpl['vbrequired'], 0)
assert(not (tmpl['version'] & (1 << bitno)))
# Test 6
# Check that the new sequence lock rules are enforced
spendtx = self.create_transaction(self.nodes[0],
self.coinbase_blocks[1], self.nodeaddress, 1.0)
invalidate(spendtx)
spendtx = self.sign_transaction(self.nodes[0], spendtx)
spendtx.rehash()
invalidatePostSignature(spendtx)
spendtx.rehash()
block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1)
block.nVersion = 5
block.vtx.append(spendtx)
block.hashMerkleRoot = block.calc_merkle_root()
block.rehash()
block.solve()
self.last_block_time += 1
yield TestInstance([[block, False]])
# Restart all
stop_nodes(self.nodes)
wait_bitcoinds()
shutil.rmtree(self.options.tmpdir)
self.setup_chain()
self.setup_network()
self.test.clear_all_connections()
self.test.add_all_connections(self.nodes)
NetworkThread().start() # Start up network handling in another thread
def get_tests(self):
for test in itertools.chain(
self.test_BIP('csv', 0x20000001, self.sequence_lock_invalidate, self.donothing, 0),
self.test_BIP('csv', 0x20000001, self.mtp_invalidate, self.donothing, 0),
self.test_BIP('csv', 0x20000001, self.donothing, self.csv_invalidate, 0)
):
yield test
def donothing(self, tx):
return
def csv_invalidate(self, tx):
'''Modify the signature in vin 0 of the tx to fail CSV
Prepends -1 CSV DROP in the scriptSig itself.
'''
tx.vin[0].scriptSig = CScript([OP_1NEGATE, OP_CHECKSEQUENCEVERIFY, OP_DROP] +
list(CScript(tx.vin[0].scriptSig)))
def sequence_lock_invalidate(self, tx):
'''Modify the nSequence to make it fails once sequence lock rule is activated (high timespan)
'''
tx.vin[0].nSequence = 0x00FFFFFF
tx.nLockTime = 0
def mtp_invalidate(self, tx):
'''Modify the nLockTime to make it fails once MTP rule is activated
'''
# Disable Sequence lock, Activate nLockTime
tx.vin[0].nSequence = 0x90FFFFFF
tx.nLockTime = self.last_block_time
if __name__ == '__main__':
BIP9SoftForksTest().main()

View File

@@ -1,8 +1,7 @@
#!/usr/bin/env python2
#
# Distributed under the MIT/X11 software license, see the accompanying
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
from test_framework.test_framework import ComparisonTestFramework
from test_framework.util import *
@@ -10,8 +9,7 @@ from test_framework.mininode import CTransaction, NetworkThread
from test_framework.blocktools import create_coinbase, create_block
from test_framework.comptool import TestInstance, TestManager
from test_framework.script import CScript
from binascii import hexlify, unhexlify
import cStringIO
from io import BytesIO
import time
# A canonical signature consists of:
@@ -25,7 +23,7 @@ def unDERify(tx):
newscript = []
for i in scriptSig:
if (len(newscript) == 0):
newscript.append(i[0:-1] + '\0' + i[-1])
newscript.append(i[0:-1] + b'\0' + i[-1:])
else:
newscript.append(i)
tx.vin[0].scriptSig = CScript(newscript)
@@ -68,7 +66,7 @@ class BIP66Test(ComparisonTestFramework):
rawtx = node.createrawtransaction(inputs, outputs)
signresult = node.signrawtransaction(rawtx)
tx = CTransaction()
f = cStringIO.StringIO(unhexlify(signresult['hex']))
f = BytesIO(hex_str_to_bytes(signresult['hex']))
tx.deserialize(f)
return tx
@@ -76,13 +74,13 @@ class BIP66Test(ComparisonTestFramework):
self.coinbase_blocks = self.nodes[0].generate(2)
height = 3 # height of the next block to build
self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0)
self.nodeaddress = self.nodes[0].getnewaddress()
self.last_block_time = time.time()
self.last_block_time = int(time.time())
''' 98 more version 2 blocks '''
test_blocks = []
for i in xrange(98):
for i in range(98):
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 2
block.rehash()
@@ -95,7 +93,7 @@ class BIP66Test(ComparisonTestFramework):
''' Mine 749 version 3 blocks '''
test_blocks = []
for i in xrange(749):
for i in range(749):
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 3
block.rehash()
@@ -147,7 +145,7 @@ class BIP66Test(ComparisonTestFramework):
''' Mine 199 new version blocks on last valid tip '''
test_blocks = []
for i in xrange(199):
for i in range(199):
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 3
block.rehash()

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -9,8 +9,6 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import os
import shutil
class BIP66Test(BitcoinTestFramework):
@@ -34,7 +32,7 @@ class BIP66Test(BitcoinTestFramework):
raise AssertionError("Failed to mine 100 version=2 blocks")
# Mine 750 new-version blocks
for i in xrange(15):
for i in range(15):
self.nodes[2].generate(50)
self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 850):
@@ -46,12 +44,12 @@ class BIP66Test(BitcoinTestFramework):
self.nodes[2].generate(1)
self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 851):
raise AssertionFailure("Failed to mine a version=3 blocks")
raise AssertionError("Failed to mine a version=3 blocks")
# TODO: check that new DERSIG rules are enforced
# Mine 198 new-version blocks
for i in xrange(2):
for i in range(2):
self.nodes[2].generate(99)
self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 1049):

View File

@@ -1,27 +1,34 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
# Test RPC calls related to blockchain state.
# Test RPC calls related to blockchain state. Tests correspond to code in
# rpcblockchain.cpp.
#
import decimal
from decimal import Decimal
from test_framework.test_framework import BitcoinTestFramework
from test_framework.authproxy import JSONRPCException
from test_framework.util import (
initialize_chain,
assert_equal,
assert_raises,
assert_is_hex_string,
assert_is_hash_string,
start_nodes,
connect_nodes_bi,
)
class BlockchainTest(BitcoinTestFramework):
"""
Test blockchain-related RPC calls:
- gettxoutsetinfo
- verifychain
"""
@@ -36,17 +43,46 @@ class BlockchainTest(BitcoinTestFramework):
self.sync_all()
def run_test(self):
self._test_gettxoutsetinfo()
self._test_getblockheader()
self.nodes[0].verifychain(4, 0)
def _test_gettxoutsetinfo(self):
node = self.nodes[0]
res = node.gettxoutsetinfo()
assert_equal(res[u'total_amount'], decimal.Decimal('8725.00000000'))
assert_equal(res[u'transactions'], 200)
assert_equal(res[u'height'], 200)
assert_equal(res[u'txouts'], 200)
assert_equal(res[u'bytes_serialized'], 13924),
assert_equal(len(res[u'bestblock']), 64)
assert_equal(len(res[u'hash_serialized']), 64)
assert_equal(res['total_amount'], Decimal('8725.00000000'))
assert_equal(res['transactions'], 200)
assert_equal(res['height'], 200)
assert_equal(res['txouts'], 200)
assert_equal(res['bytes_serialized'], 13924),
assert_equal(len(res['bestblock']), 64)
assert_equal(len(res['hash_serialized']), 64)
def _test_getblockheader(self):
node = self.nodes[0]
assert_raises(
JSONRPCException, lambda: node.getblockheader('nonsense'))
besthash = node.getbestblockhash()
secondbesthash = node.getblockhash(199)
header = node.getblockheader(besthash)
assert_equal(header['hash'], besthash)
assert_equal(header['height'], 200)
assert_equal(header['confirmations'], 1)
assert_equal(header['previousblockhash'], secondbesthash)
assert_is_hex_string(header['chainwork'])
assert_is_hash_string(header['hash'])
assert_is_hash_string(header['previousblockhash'])
assert_is_hash_string(header['merkleroot'])
assert_is_hash_string(header['bits'], length=None)
assert isinstance(header['time'], int)
assert isinstance(header['mediantime'], int)
assert isinstance(header['nonce'], int)
assert isinstance(header['version'], int)
assert isinstance(header['difficulty'], Decimal)
if __name__ == '__main__':
BlockchainTest().main()

View File

@@ -1,13 +1,12 @@
#!/usr/bin/env python2
# Copyright (c) 2015 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from test_framework.mininode import *
from binascii import hexlify, unhexlify
from cStringIO import StringIO
from io import BytesIO
class DecodeScriptTest(BitcoinTestFramework):
"""Tests decoding scripts via RPC command "decodescript"."""
@@ -102,13 +101,13 @@ class DecodeScriptTest(BitcoinTestFramework):
# OP_IF
# <receiver-pubkey> OP_CHECKSIGVERIFY
# OP_ELSE
# <lock-until> OP_NOP2 OP_DROP
# <lock-until> OP_CHECKLOCKTIMEVERIFY OP_DROP
# OP_ENDIF
# <sender-pubkey> OP_CHECKSIG
#
# lock until block 500,000
rpc_result = self.nodes[0].decodescript('63' + push_public_key + 'ad670320a107b17568' + push_public_key + 'ac')
assert_equal('OP_IF ' + public_key + ' OP_CHECKSIGVERIFY OP_ELSE 500000 OP_NOP2 OP_DROP OP_ENDIF ' + public_key + ' OP_CHECKSIG', rpc_result['asm'])
assert_equal('OP_IF ' + public_key + ' OP_CHECKSIGVERIFY OP_ELSE 500000 OP_CHECKLOCKTIMEVERIFY OP_DROP OP_ENDIF ' + public_key + ' OP_CHECKSIG', rpc_result['asm'])
def decoderawtransaction_asm_sighashtype(self):
"""Tests decoding scripts via RPC command "decoderawtransaction".
@@ -131,7 +130,7 @@ class DecodeScriptTest(BitcoinTestFramework):
assert_equal('OP_DUP OP_HASH160 dc863734a218bfe83ef770ee9d41a27f824a6e56 OP_EQUALVERIFY OP_CHECKSIG', rpc_result['vout'][0]['scriptPubKey']['asm'])
assert_equal('OP_HASH160 2a5edea39971049a540474c6a99edf0aa4074c58 OP_EQUAL', rpc_result['vout'][1]['scriptPubKey']['asm'])
txSave = CTransaction()
txSave.deserialize(StringIO(unhexlify(tx)))
txSave.deserialize(BytesIO(hex_str_to_bytes(tx)))
# make sure that a specifically crafted op_return value will not pass all the IsDERSignature checks and then get decoded as a sighash type
tx = '01000000015ded05872fdbda629c7d3d02b194763ce3b9b1535ea884e3c8e765d42e316724020000006b48304502204c10d4064885c42638cbff3585915b322de33762598321145ba033fc796971e2022100bb153ad3baa8b757e30a2175bd32852d2e1cb9080f84d7e32fcdfd667934ef1b012103163c0ff73511ea1743fb5b98384a2ff09dd06949488028fd819f4d83f56264efffffffff0200000000000000000b6a0930060201000201000180380100000000001976a9141cabd296e753837c086da7a45a6c2fe0d49d7b7b88ac00000000'
@@ -147,7 +146,7 @@ class DecodeScriptTest(BitcoinTestFramework):
# some more full transaction tests of varying specific scriptSigs. used instead of
# tests in decodescript_script_sig because the decodescript RPC is specifically
# for working on scriptPubKeys (argh!).
push_signature = hexlify(txSave.vin[0].scriptSig)[2:(0x48*2+4)]
push_signature = bytes_to_hex_str(txSave.vin[0].scriptSig)[2:(0x48*2+4)]
signature = push_signature[2:]
der_signature = signature[:-2]
signature_sighash_decoded = der_signature + '[ALL]'
@@ -156,25 +155,24 @@ class DecodeScriptTest(BitcoinTestFramework):
signature_2_sighash_decoded = der_signature + '[NONE|ANYONECANPAY]'
# 1) P2PK scriptSig
txSave.vin[0].scriptSig = unhexlify(push_signature)
rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize()))
txSave.vin[0].scriptSig = hex_str_to_bytes(push_signature)
rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize()))
assert_equal(signature_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm'])
# make sure that the sighash decodes come out correctly for a more complex / lesser used case.
txSave.vin[0].scriptSig = unhexlify(push_signature_2)
rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize()))
txSave.vin[0].scriptSig = hex_str_to_bytes(push_signature_2)
rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize()))
assert_equal(signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm'])
# 2) multisig scriptSig
txSave.vin[0].scriptSig = unhexlify('00' + push_signature + push_signature_2)
rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize()))
txSave.vin[0].scriptSig = hex_str_to_bytes('00' + push_signature + push_signature_2)
rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize()))
assert_equal('0 ' + signature_sighash_decoded + ' ' + signature_2_sighash_decoded, rpc_result['vin'][0]['scriptSig']['asm'])
# 3) test a scriptSig that contains more than push operations.
# in fact, it contains an OP_RETURN with data specially crafted to cause improper decode if the code does not catch it.
txSave.vin[0].scriptSig = unhexlify('6a143011020701010101010101020601010101010101')
rpc_result = self.nodes[0].decoderawtransaction(hexlify(txSave.serialize()))
print(hexlify('636174'))
txSave.vin[0].scriptSig = hex_str_to_bytes('6a143011020701010101010101020601010101010101')
rpc_result = self.nodes[0].decoderawtransaction(bytes_to_hex_str(txSave.serialize()))
assert_equal('OP_RETURN 3011020701010101010101020601010101010101', rpc_result['vin'][0]['scriptSig']['asm'])
def run_test(self):

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -10,6 +10,7 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
class DisableWalletTest (BitcoinTestFramework):
def setup_chain(self):

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -9,8 +9,6 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import os
import shutil
class ForkNotifyTest(BitcoinTestFramework):

View File

@@ -1,18 +1,16 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from pprint import pprint
from time import sleep
# Create one-input, one-output, no-fee transaction:
class RawTransactionsTest(BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
print(("Initializing test directory "+self.options.tmpdir))
initialize_chain_clean(self.options.tmpdir, 4)
def setup_network(self, split=False):
@@ -27,9 +25,14 @@ class RawTransactionsTest(BitcoinTestFramework):
self.sync_all()
def run_test(self):
print "Mining blocks..."
print("Mining blocks...")
min_relay_tx_fee = self.nodes[0].getnetworkinfo()['relayfee']
# This test is not meant to test fee estimation and we'd like
# to be sure all txs are sent at a consistent desired feerate
for node in self.nodes:
node.settxfee(min_relay_tx_fee)
# if the fee's positive delta is higher than this value tests will fail,
# neg. delta always fail the tests.
# The size of the signature of every input may be at most 2 bytes larger
@@ -45,14 +48,14 @@ class RawTransactionsTest(BitcoinTestFramework):
watchonly_address = self.nodes[0].getnewaddress()
watchonly_pubkey = self.nodes[0].validateaddress(watchonly_address)["pubkey"]
watchonly_amount = 200
watchonly_amount = Decimal(200)
self.nodes[3].importpubkey(watchonly_pubkey, "", True)
watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount)
self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10);
self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5);
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0);
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0);
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.5)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 5.0)
self.sync_all()
self.nodes[0].generate(1)
@@ -68,7 +71,7 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
fee = rawtxfund['fee']
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
assert_equal(len(dec_tx['vin']) > 0, True) #test if we have enought inputs
assert(len(dec_tx['vin']) > 0) #test if we have enought inputs
##############################
# simple test with two coins #
@@ -81,7 +84,7 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
fee = rawtxfund['fee']
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
assert_equal(len(dec_tx['vin']) > 0, True) #test if we have enough inputs
assert(len(dec_tx['vin']) > 0) #test if we have enough inputs
##############################
# simple test with two coins #
@@ -94,7 +97,7 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
fee = rawtxfund['fee']
dec_tx = self.nodes[2].decoderawtransaction(rawtxfund['hex'])
assert_equal(len(dec_tx['vin']) > 0, True)
assert(len(dec_tx['vin']) > 0)
assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '')
@@ -113,7 +116,7 @@ class RawTransactionsTest(BitcoinTestFramework):
for out in dec_tx['vout']:
totalOut += out['value']
assert_equal(len(dec_tx['vin']) > 0, True)
assert(len(dec_tx['vin']) > 0)
assert_equal(dec_tx['vin'][0]['scriptSig']['hex'], '')
@@ -125,9 +128,9 @@ class RawTransactionsTest(BitcoinTestFramework):
for aUtx in listunspent:
if aUtx['amount'] == 5.0:
utx = aUtx
break;
break
assert_equal(utx!=False, True)
assert(utx!=False)
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
outputs = { self.nodes[0].getnewaddress() : 1.0 }
@@ -145,7 +148,6 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee
#####################################################################
# test a fundrawtransaction with which will not get a change output #
#####################################################################
@@ -154,9 +156,9 @@ class RawTransactionsTest(BitcoinTestFramework):
for aUtx in listunspent:
if aUtx['amount'] == 5.0:
utx = aUtx
break;
break
assert_equal(utx!=False, True)
assert(utx!=False)
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
outputs = { self.nodes[0].getnewaddress() : Decimal(5.0) - fee - feeTolerance }
@@ -175,7 +177,6 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(fee + totalOut, utx['amount']) #compare vin total and totalout+fee
#########################################################################
# test a fundrawtransaction with a VIN smaller than the required amount #
#########################################################################
@@ -184,9 +185,9 @@ class RawTransactionsTest(BitcoinTestFramework):
for aUtx in listunspent:
if aUtx['amount'] == 1.0:
utx = aUtx
break;
break
assert_equal(utx!=False, True)
assert(utx!=False)
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
outputs = { self.nodes[0].getnewaddress() : 1.0 }
@@ -206,7 +207,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0
for i, out in enumerate(dec_tx['vout']):
totalOut += out['value']
if outputs.has_key(out['scriptPubKey']['addresses'][0]):
if out['scriptPubKey']['addresses'][0] in outputs:
matchingOuts+=1
else:
assert_equal(i, rawtxfund['changepos'])
@@ -231,7 +232,7 @@ class RawTransactionsTest(BitcoinTestFramework):
utx2 = aUtx
assert_equal(utx!=False, True)
assert(utx!=False)
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ]
outputs = { self.nodes[0].getnewaddress() : 6.0 }
@@ -246,7 +247,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0
for out in dec_tx['vout']:
totalOut += out['value']
if outputs.has_key(out['scriptPubKey']['addresses'][0]):
if out['scriptPubKey']['addresses'][0] in outputs:
matchingOuts+=1
assert_equal(matchingOuts, 1)
@@ -273,7 +274,7 @@ class RawTransactionsTest(BitcoinTestFramework):
utx2 = aUtx
assert_equal(utx!=False, True)
assert(utx!=False)
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ]
outputs = { self.nodes[0].getnewaddress() : 6.0, self.nodes[0].getnewaddress() : 1.0 }
@@ -288,7 +289,7 @@ class RawTransactionsTest(BitcoinTestFramework):
matchingOuts = 0
for out in dec_tx['vout']:
totalOut += out['value']
if outputs.has_key(out['scriptPubKey']['addresses'][0]):
if out['scriptPubKey']['addresses'][0] in outputs:
matchingOuts+=1
assert_equal(matchingOuts, 2)
@@ -303,14 +304,11 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
errorString = ""
try:
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
except JSONRPCException,e:
errorString = e.error['message']
assert_equal("Insufficient" in errorString, True);
raise AssertionError("Spent more than available")
except JSONRPCException as e:
assert("Insufficient" in e.error['message'])
############################################################
@@ -321,11 +319,11 @@ class RawTransactionsTest(BitcoinTestFramework):
fundedTx = self.nodes[0].fundrawtransaction(rawTx)
#create same transaction over sendtoaddress
txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1.1);
txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1.1)
signedFee = self.nodes[0].getrawmempool(True)[txId]['fee']
#compare fee
feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee);
feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee)
assert(feeDelta >= 0 and feeDelta <= feeTolerance)
############################################################
@@ -336,11 +334,11 @@ class RawTransactionsTest(BitcoinTestFramework):
rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
fundedTx = self.nodes[0].fundrawtransaction(rawTx)
#create same transaction over sendtoaddress
txId = self.nodes[0].sendmany("", outputs);
txId = self.nodes[0].sendmany("", outputs)
signedFee = self.nodes[0].getrawmempool(True)[txId]['fee']
#compare fee
feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee);
feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee)
assert(feeDelta >= 0 and feeDelta <= feeTolerance)
############################################################
@@ -363,11 +361,11 @@ class RawTransactionsTest(BitcoinTestFramework):
fundedTx = self.nodes[0].fundrawtransaction(rawTx)
#create same transaction over sendtoaddress
txId = self.nodes[0].sendtoaddress(mSigObj, 1.1);
txId = self.nodes[0].sendtoaddress(mSigObj, 1.1)
signedFee = self.nodes[0].getrawmempool(True)[txId]['fee']
#compare fee
feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee);
feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee)
assert(feeDelta >= 0 and feeDelta <= feeTolerance)
############################################################
@@ -396,11 +394,11 @@ class RawTransactionsTest(BitcoinTestFramework):
fundedTx = self.nodes[0].fundrawtransaction(rawTx)
#create same transaction over sendtoaddress
txId = self.nodes[0].sendtoaddress(mSigObj, 1.1);
txId = self.nodes[0].sendtoaddress(mSigObj, 1.1)
signedFee = self.nodes[0].getrawmempool(True)[txId]['fee']
#compare fee
feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee);
feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee)
assert(feeDelta >= 0 and feeDelta <= feeTolerance)
############################################################
@@ -419,7 +417,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# send 1.2 BTC to msig addr
txId = self.nodes[0].sendtoaddress(mSigObj, 1.2);
txId = self.nodes[0].sendtoaddress(mSigObj, 1.2)
self.sync_all()
self.nodes[1].generate(1)
self.sync_all()
@@ -447,6 +445,10 @@ class RawTransactionsTest(BitcoinTestFramework):
wait_bitcoinds()
self.nodes = start_nodes(4, self.options.tmpdir)
# This test is not meant to test fee estimation and we'd like
# to be sure all txs are sent at a consistent desired feerate
for node in self.nodes:
node.settxfee(min_relay_tx_fee)
connect_nodes_bi(self.nodes,0,1)
connect_nodes_bi(self.nodes,1,2)
@@ -455,12 +457,28 @@ class RawTransactionsTest(BitcoinTestFramework):
self.is_network_split=False
self.sync_all()
error = False
# drain the keypool
self.nodes[1].getnewaddress()
inputs = []
outputs = {self.nodes[0].getnewaddress():1.1}
rawTx = self.nodes[1].createrawtransaction(inputs, outputs)
# fund a transaction that requires a new key for the change output
# creating the key must be impossible because the wallet is locked
try:
self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.2);
except:
error = True
assert(error)
fundedTx = self.nodes[1].fundrawtransaction(rawTx)
raise AssertionError("Wallet unlocked without passphrase")
except JSONRPCException as e:
assert('Keypool ran out' in e.error['message'])
#refill the keypool
self.nodes[1].walletpassphrase("test", 100)
self.nodes[1].walletlock()
try:
self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1.2)
raise AssertionError("Wallet unlocked without passphrase")
except JSONRPCException as e:
assert('walletpassphrase' in e.error['message'])
oldBalance = self.nodes[0].getbalance()
@@ -481,19 +499,18 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(oldBalance+Decimal('51.10000000'), self.nodes[0].getbalance())
###############################################
# multiple (~19) inputs tx test | Compare fee #
###############################################
#empty node1, send some small coins from node0 to node1
self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True);
self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True)
self.sync_all()
self.nodes[0].generate(1)
self.sync_all()
for i in range(0,20):
self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01);
self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01)
self.sync_all()
self.nodes[0].generate(1)
self.sync_all()
@@ -505,11 +522,11 @@ class RawTransactionsTest(BitcoinTestFramework):
fundedTx = self.nodes[1].fundrawtransaction(rawTx)
#create same transaction over sendtoaddress
txId = self.nodes[1].sendmany("", outputs);
txId = self.nodes[1].sendmany("", outputs)
signedFee = self.nodes[1].getrawmempool(True)[txId]['fee']
#compare fee
feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee);
feeDelta = Decimal(fundedTx['fee']) - Decimal(signedFee)
assert(feeDelta >= 0 and feeDelta <= feeTolerance*19) #~19 inputs
@@ -518,13 +535,13 @@ class RawTransactionsTest(BitcoinTestFramework):
#############################################
#again, empty node1, send some small coins from node0 to node1
self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True);
self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), self.nodes[1].getbalance(), "", "", True)
self.sync_all()
self.nodes[0].generate(1)
self.sync_all()
for i in range(0,20):
self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01);
self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01)
self.sync_all()
self.nodes[0].generate(1)
self.sync_all()
@@ -573,7 +590,7 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(len(res_dec["vin"]), 1)
assert_equal(res_dec["vin"][0]["txid"], watchonly_txid)
assert_equal("fee" in result.keys(), True)
assert("fee" in result.keys())
assert_greater_than(result["changepos"], -1)
###############################################################

View File

@@ -1,33 +1,11 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
def check_array_result(object_array, to_match, expected):
"""
Pass in array of JSON objects, a dictionary with key/value pairs
to match against, and another dictionary with expected key/value
pairs.
"""
num_matched = 0
for item in object_array:
all_match = True
for key,value in to_match.items():
if item[key] != value:
all_match = False
if not all_match:
continue
for key,value in expected.items():
if item[key] != value:
raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
num_matched = num_matched+1
if num_matched == 0:
raise AssertionError("No objects matched %s"%(str(to_match)))
import threading
class LongpollThread(threading.Thread):
@@ -49,7 +27,7 @@ class GetBlockTemplateLPTest(BitcoinTestFramework):
'''
def run_test(self):
print "Warning: this test will take about 70 seconds in the best case. Be patient."
print("Warning: this test will take about 70 seconds in the best case. Be patient.")
self.nodes[0].generate(10)
templat = self.nodes[0].getblocktemplate()
longpollid = templat['longpollid']

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -10,28 +10,6 @@ from binascii import a2b_hex, b2a_hex
from hashlib import sha256
from struct import pack
def check_array_result(object_array, to_match, expected):
"""
Pass in array of JSON objects, a dictionary with key/value pairs
to match against, and another dictionary with expected key/value
pairs.
"""
num_matched = 0
for item in object_array:
all_match = True
for key,value in to_match.items():
if item[key] != value:
all_match = False
if not all_match:
continue
for key,value in expected.items():
if item[key] != value:
raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
num_matched = num_matched+1
if num_matched == 0:
raise AssertionError("No objects matched %s"%(str(to_match)))
def b2x(b):
return b2a_hex(b).decode('ascii')
@@ -68,7 +46,7 @@ def genmrklroot(leaflist):
cur = n
return cur[0]
def template_to_bytes(tmpl, txlist):
def template_to_bytearray(tmpl, txlist):
blkver = pack('<L', tmpl['version'])
mrklroot = genmrklroot(list(dblsha(a) for a in txlist))
timestamp = pack('<L', tmpl['curtime'])
@@ -77,10 +55,10 @@ def template_to_bytes(tmpl, txlist):
blk += varlenEncode(len(txlist))
for tx in txlist:
blk += tx
return blk
return bytearray(blk)
def template_to_hex(tmpl, txlist):
return b2x(template_to_bytes(tmpl, txlist))
return b2x(template_to_bytearray(tmpl, txlist))
def assert_template(node, tmpl, txlist, expect):
rsp = node.getblocktemplate({'data':template_to_hex(tmpl, txlist),'mode':'proposal'})
@@ -120,10 +98,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
# Test 3: Truncated final tx
lastbyte = txlist[-1].pop()
try:
assert_template(node, tmpl, txlist, 'n/a')
except JSONRPCException:
pass # Expected
assert_raises(JSONRPCException, assert_template, node, tmpl, txlist, 'n/a')
txlist[-1].append(lastbyte)
# Test 4: Add an invalid tx to the end (duplicate of gen tx)
@@ -133,7 +108,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
# Test 5: Add an invalid tx to the end (non-duplicate)
txlist.append(bytearray(txlist[0]))
txlist[-1][4+1] = b'\xff'
txlist[-1][4+1] = 0xff
assert_template(node, tmpl, txlist, 'bad-txns-inputs-missingorspent')
txlist.pop()
@@ -144,10 +119,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
# Test 7: Bad tx count
txlist.append(b'')
try:
assert_template(node, tmpl, txlist, 'n/a')
except JSONRPCException:
pass # Expected
assert_raises(JSONRPCException, assert_template, node, tmpl, txlist, 'n/a')
txlist.pop()
# Test 8: Bad bits
@@ -157,7 +129,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
tmpl['bits'] = realbits
# Test 9: Bad merkle root
rawtmpl = template_to_bytes(tmpl, txlist)
rawtmpl = template_to_bytearray(tmpl, txlist)
rawtmpl[4+32] = (rawtmpl[4+32] + 1) % 0x100
rsp = node.getblocktemplate({'data':b2x(rawtmpl),'mode':'proposal'})
if rsp != 'bad-txnmrklroot':

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -23,8 +23,8 @@ class GetChainTipsTest (BitcoinTestFramework):
# Split the network and build two chains of different lengths.
self.split_network ()
self.nodes[0].generate(10);
self.nodes[2].generate(20);
self.nodes[0].generate(10)
self.nodes[2].generate(20)
self.sync_all ()
tips = self.nodes[1].getchaintips ()

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -9,16 +9,9 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import base64
try:
import http.client as httplib
except ImportError:
import httplib
try:
import urllib.parse as urlparse
except ImportError:
import urlparse
import http.client
import urllib.parse
class HTTPBasicsTest (BitcoinTestFramework):
def setup_nodes(self):
@@ -29,86 +22,86 @@ class HTTPBasicsTest (BitcoinTestFramework):
#################################################
# lowlevel check for http persistent connection #
#################################################
url = urlparse.urlparse(self.nodes[0].url)
url = urllib.parse.urlparse(self.nodes[0].url)
authpair = url.username + ':' + url.password
headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
headers = {"Authorization": "Basic " + str_to_b64str(authpair)}
conn = httplib.HTTPConnection(url.hostname, url.port)
conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read();
assert_equal('"error":null' in out1, True)
assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
out1 = conn.getresponse().read()
assert(b'"error":null' in out1)
assert(conn.sock!=None) #according to http/1.1 connection must still be open!
#send 2nd request without closing connection
conn.request('POST', '/', '{"method": "getchaintips"}', headers)
out2 = conn.getresponse().read();
assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message
assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
out1 = conn.getresponse().read()
assert(b'"error":null' in out1) #must also response with a correct json-rpc message
assert(conn.sock!=None) #according to http/1.1 connection must still be open!
conn.close()
#same should be if we add keep-alive because this should be the std. behaviour
headers = {"Authorization": "Basic " + base64.b64encode(authpair), "Connection": "keep-alive"}
headers = {"Authorization": "Basic " + str_to_b64str(authpair), "Connection": "keep-alive"}
conn = httplib.HTTPConnection(url.hostname, url.port)
conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read();
assert_equal('"error":null' in out1, True)
assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
out1 = conn.getresponse().read()
assert(b'"error":null' in out1)
assert(conn.sock!=None) #according to http/1.1 connection must still be open!
#send 2nd request without closing connection
conn.request('POST', '/', '{"method": "getchaintips"}', headers)
out2 = conn.getresponse().read();
assert_equal('"error":null' in out1, True) #must also response with a correct json-rpc message
assert_equal(conn.sock!=None, True) #according to http/1.1 connection must still be open!
out1 = conn.getresponse().read()
assert(b'"error":null' in out1) #must also response with a correct json-rpc message
assert(conn.sock!=None) #according to http/1.1 connection must still be open!
conn.close()
#now do the same with "Connection: close"
headers = {"Authorization": "Basic " + base64.b64encode(authpair), "Connection":"close"}
headers = {"Authorization": "Basic " + str_to_b64str(authpair), "Connection":"close"}
conn = httplib.HTTPConnection(url.hostname, url.port)
conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read();
assert_equal('"error":null' in out1, True)
assert_equal(conn.sock!=None, False) #now the connection must be closed after the response
out1 = conn.getresponse().read()
assert(b'"error":null' in out1)
assert(conn.sock==None) #now the connection must be closed after the response
#node1 (2nd node) is running with disabled keep-alive option
urlNode1 = urlparse.urlparse(self.nodes[1].url)
urlNode1 = urllib.parse.urlparse(self.nodes[1].url)
authpair = urlNode1.username + ':' + urlNode1.password
headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
headers = {"Authorization": "Basic " + str_to_b64str(authpair)}
conn = httplib.HTTPConnection(urlNode1.hostname, urlNode1.port)
conn = http.client.HTTPConnection(urlNode1.hostname, urlNode1.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read();
assert_equal('"error":null' in out1, True)
out1 = conn.getresponse().read()
assert(b'"error":null' in out1)
#node2 (third node) is running with standard keep-alive parameters which means keep-alive is on
urlNode2 = urlparse.urlparse(self.nodes[2].url)
urlNode2 = urllib.parse.urlparse(self.nodes[2].url)
authpair = urlNode2.username + ':' + urlNode2.password
headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
headers = {"Authorization": "Basic " + str_to_b64str(authpair)}
conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port)
conn = http.client.HTTPConnection(urlNode2.hostname, urlNode2.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read();
assert_equal('"error":null' in out1, True)
assert_equal(conn.sock!=None, True) #connection must be closed because bitcoind should use keep-alive by default
out1 = conn.getresponse().read()
assert(b'"error":null' in out1)
assert(conn.sock!=None) #connection must be closed because bitcoind should use keep-alive by default
# Check excessive request size
conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port)
conn = http.client.HTTPConnection(urlNode2.hostname, urlNode2.port)
conn.connect()
conn.request('GET', '/' + ('x'*1000), '', headers)
out1 = conn.getresponse()
assert_equal(out1.status, httplib.NOT_FOUND)
assert_equal(out1.status, http.client.NOT_FOUND)
conn = httplib.HTTPConnection(urlNode2.hostname, urlNode2.port)
conn = http.client.HTTPConnection(urlNode2.hostname, urlNode2.port)
conn.connect()
conn.request('GET', '/' + ('x'*10000), '', headers)
out1 = conn.getresponse()
assert_equal(out1.status, httplib.BAD_REQUEST)
assert_equal(out1.status, http.client.BAD_REQUEST)
if __name__ == '__main__':

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -25,46 +25,46 @@ class InvalidateTest(BitcoinTestFramework):
self.nodes.append(start_node(2, self.options.tmpdir, ["-debug"]))
def run_test(self):
print "Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:"
print "Mine 4 blocks on Node 0"
print("Make sure we repopulate setBlockIndexCandidates after InvalidateBlock:")
print("Mine 4 blocks on Node 0")
self.nodes[0].generate(4)
assert(self.nodes[0].getblockcount() == 4)
besthash = self.nodes[0].getbestblockhash()
print "Mine competing 6 blocks on Node 1"
print("Mine competing 6 blocks on Node 1")
self.nodes[1].generate(6)
assert(self.nodes[1].getblockcount() == 6)
print "Connect nodes to force a reorg"
print("Connect nodes to force a reorg")
connect_nodes_bi(self.nodes,0,1)
sync_blocks(self.nodes[0:2])
assert(self.nodes[0].getblockcount() == 6)
badhash = self.nodes[1].getblockhash(2)
print "Invalidate block 2 on node 0 and verify we reorg to node 0's original chain"
print("Invalidate block 2 on node 0 and verify we reorg to node 0's original chain")
self.nodes[0].invalidateblock(badhash)
newheight = self.nodes[0].getblockcount()
newhash = self.nodes[0].getbestblockhash()
if (newheight != 4 or newhash != besthash):
raise AssertionError("Wrong tip for node0, hash %s, height %d"%(newhash,newheight))
print "\nMake sure we won't reorg to a lower work chain:"
print("\nMake sure we won't reorg to a lower work chain:")
connect_nodes_bi(self.nodes,1,2)
print "Sync node 2 to node 1 so both have 6 blocks"
print("Sync node 2 to node 1 so both have 6 blocks")
sync_blocks(self.nodes[1:3])
assert(self.nodes[2].getblockcount() == 6)
print "Invalidate block 5 on node 1 so its tip is now at 4"
print("Invalidate block 5 on node 1 so its tip is now at 4")
self.nodes[1].invalidateblock(self.nodes[1].getblockhash(5))
assert(self.nodes[1].getblockcount() == 4)
print "Invalidate block 3 on node 2, so its tip is now 2"
print("Invalidate block 3 on node 2, so its tip is now 2")
self.nodes[2].invalidateblock(self.nodes[2].getblockhash(3))
assert(self.nodes[2].getblockcount() == 2)
print "..and then mine a block"
print("..and then mine a block")
self.nodes[2].generate(1)
print "Verify all nodes are at the right height"
print("Verify all nodes are at the right height")
time.sleep(5)
for i in xrange(3):
print i,self.nodes[i].getblockcount()
for i in range(3):
print(i,self.nodes[i].getblockcount())
assert(self.nodes[2].getblockcount() == 3)
assert(self.nodes[0].getblockcount() == 4)
node1height = self.nodes[1].getblockcount()

View File

@@ -1,15 +1,12 @@
#!/usr/bin/env python2
#
# Distributed under the MIT/X11 software license, see the accompanying
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
from test_framework.test_framework import ComparisonTestFramework
from test_framework.util import *
from test_framework.comptool import TestManager, TestInstance
from test_framework.mininode import *
from test_framework.comptool import TestManager, TestInstance, RejectResult
from test_framework.blocktools import *
import logging
import copy
import time
@@ -40,7 +37,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework):
def get_tests(self):
if self.tip is None:
self.tip = int ("0x" + self.nodes[0].getbestblockhash() + "L", 0)
self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0)
self.block_time = int(time.time())+1
'''
@@ -60,7 +57,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework):
Now we need that block to mature so we can spend the coinbase.
'''
test = TestInstance(sync_every_block=False)
for i in xrange(100):
for i in range(100):
block = create_block(self.tip, create_coinbase(height), self.block_time)
block.solve()
self.tip = block.sha256
@@ -79,9 +76,9 @@ class InvalidBlockRequestTest(ComparisonTestFramework):
block2 = create_block(self.tip, create_coinbase(height), self.block_time)
self.block_time += 1
# chr(81) is OP_TRUE
tx1 = create_transaction(self.block1.vtx[0], 0, chr(81), 50*100000000)
tx2 = create_transaction(tx1, 0, chr(81), 50*100000000)
# b'0x51' is OP_TRUE
tx1 = create_transaction(self.block1.vtx[0], 0, b'\x51', 50 * COIN)
tx2 = create_transaction(tx1, 0, b'\x51', 50 * COIN)
block2.vtx.extend([tx1, tx2])
block2.hashMerkleRoot = block2.calc_merkle_root()
@@ -97,7 +94,7 @@ class InvalidBlockRequestTest(ComparisonTestFramework):
assert(block2_orig.vtx != block2.vtx)
self.tip = block2.sha256
yield TestInstance([[block2, False], [block2_orig, True]])
yield TestInstance([[block2, RejectResult(16, b'bad-txns-duplicate')], [block2_orig, True]])
height += 1
'''
@@ -105,14 +102,14 @@ class InvalidBlockRequestTest(ComparisonTestFramework):
'''
block3 = create_block(self.tip, create_coinbase(height), self.block_time)
self.block_time += 1
block3.vtx[0].vout[0].nValue = 100*100000000 # Too high!
block3.vtx[0].vout[0].nValue = 100 * COIN # Too high!
block3.vtx[0].sha256=None
block3.vtx[0].calc_sha256()
block3.hashMerkleRoot = block3.calc_merkle_root()
block3.rehash()
block3.solve()
yield TestInstance([[block3, False]])
yield TestInstance([[block3, RejectResult(16, b'bad-cb-amount')]])
if __name__ == '__main__':

View File

@@ -0,0 +1,71 @@
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.test_framework import ComparisonTestFramework
from test_framework.comptool import TestManager, TestInstance, RejectResult
from test_framework.blocktools import *
import time
'''
In this test we connect to one node over p2p, and test tx requests.
'''
# Use the ComparisonTestFramework with 1 node: only use --testbinary.
class InvalidTxRequestTest(ComparisonTestFramework):
''' Can either run this test as 1 node with expected answers, or two and compare them.
Change the "outcome" variable from each TestInstance object to only do the comparison. '''
def __init__(self):
self.num_nodes = 1
def run_test(self):
test = TestManager(self, self.options.tmpdir)
test.add_all_connections(self.nodes)
self.tip = None
self.block_time = None
NetworkThread().start() # Start up network handling in another thread
test.run()
def get_tests(self):
if self.tip is None:
self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0)
self.block_time = int(time.time())+1
'''
Create a new block with an anyone-can-spend coinbase
'''
height = 1
block = create_block(self.tip, create_coinbase(height), self.block_time)
self.block_time += 1
block.solve()
# Save the coinbase for later
self.block1 = block
self.tip = block.sha256
height += 1
yield TestInstance([[block, True]])
'''
Now we need that block to mature so we can spend the coinbase.
'''
test = TestInstance(sync_every_block=False)
for i in range(100):
block = create_block(self.tip, create_coinbase(height), self.block_time)
block.solve()
self.tip = block.sha256
self.block_time += 1
test.blocks_and_transactions.append([block, True])
height += 1
yield test
# b'\x64' is OP_NOTIF
# Transaction will be rejected with code 16 (REJECT_INVALID)
tx1 = create_transaction(self.block1.vtx[0], 0, b'\x64', 50 * COIN)
yield TestInstance([[tx1, RejectResult(16, b'mandatory-script-verify-flag-failed')]])
# TODO: test further transactions...
if __name__ == '__main__':
InvalidTxRequestTest().main()

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -10,28 +10,6 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
def check_array_result(object_array, to_match, expected):
"""
Pass in array of JSON objects, a dictionary with key/value pairs
to match against, and another dictionary with expected key/value
pairs.
"""
num_matched = 0
for item in object_array:
all_match = True
for key,value in to_match.items():
if item[key] != value:
all_match = False
if not all_match:
continue
for key,value in expected.items():
if item[key] != value:
raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
num_matched = num_matched+1
if num_matched == 0:
raise AssertionError("No objects matched %s"%(str(to_match)))
class KeyPoolTest(BitcoinTestFramework):
def run_test(self):
@@ -46,7 +24,7 @@ class KeyPoolTest(BitcoinTestFramework):
try:
addr = nodes[0].getnewaddress()
raise AssertionError('Keypool should be exhausted after one address')
except JSONRPCException,e:
except JSONRPCException as e:
assert(e.error['code']==-12)
# put three new keys in the keypool
@@ -66,13 +44,15 @@ class KeyPoolTest(BitcoinTestFramework):
try:
addr = nodes[0].getrawchangeaddress()
raise AssertionError('Keypool should be exhausted after three addresses')
except JSONRPCException,e:
except JSONRPCException as e:
assert(e.error['code']==-12)
# refill keypool with three new addresses
nodes[0].walletpassphrase('test', 12000)
nodes[0].walletpassphrase('test', 1)
nodes[0].keypoolrefill(3)
nodes[0].walletlock()
# test walletpassphrase timeout
time.sleep(1.1)
assert_equal(nodes[0].getwalletinfo()["unlocked_until"], 0)
# drain them by mining
nodes[0].generate(1)
@@ -82,7 +62,7 @@ class KeyPoolTest(BitcoinTestFramework):
try:
nodes[0].generate(1)
raise AssertionError('Keypool should be exhausted after three addesses')
except JSONRPCException,e:
except JSONRPCException as e:
assert(e.error['code']==-12)
def setup_chain(self):

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -7,57 +7,48 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from test_framework.mininode import CTransaction, COIN
from io import BytesIO
def check_array_result(object_array, to_match, expected):
"""
Pass in array of JSON objects, a dictionary with key/value pairs
to match against, and another dictionary with expected key/value
pairs.
"""
num_matched = 0
for item in object_array:
all_match = True
for key,value in to_match.items():
if item[key] != value:
all_match = False
if not all_match:
continue
for key,value in expected.items():
if item[key] != value:
raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
num_matched = num_matched+1
if num_matched == 0:
raise AssertionError("No objects matched %s"%(str(to_match)))
def txFromHex(hexstring):
tx = CTransaction()
f = BytesIO(hex_str_to_bytes(hexstring))
tx.deserialize(f)
return tx
class ListTransactionsTest(BitcoinTestFramework):
def setup_nodes(self):
#This test requires mocktime
enable_mocktime()
return start_nodes(4, self.options.tmpdir)
def run_test(self):
# Simple send, 0 to 1:
txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
self.sync_all()
check_array_result(self.nodes[0].listtransactions(),
assert_array_result(self.nodes[0].listtransactions(),
{"txid":txid},
{"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":0})
check_array_result(self.nodes[1].listtransactions(),
assert_array_result(self.nodes[1].listtransactions(),
{"txid":txid},
{"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":0})
# mine a block, confirmations should change:
self.nodes[0].generate(1)
self.sync_all()
check_array_result(self.nodes[0].listtransactions(),
assert_array_result(self.nodes[0].listtransactions(),
{"txid":txid},
{"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":1})
check_array_result(self.nodes[1].listtransactions(),
assert_array_result(self.nodes[1].listtransactions(),
{"txid":txid},
{"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":1})
# send-to-self:
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 0.2)
check_array_result(self.nodes[0].listtransactions(),
assert_array_result(self.nodes[0].listtransactions(),
{"txid":txid, "category":"send"},
{"amount":Decimal("-0.2")})
check_array_result(self.nodes[0].listtransactions(),
assert_array_result(self.nodes[0].listtransactions(),
{"txid":txid, "category":"receive"},
{"amount":Decimal("0.2")})
@@ -68,28 +59,28 @@ class ListTransactionsTest(BitcoinTestFramework):
self.nodes[1].getaccountaddress("toself") : 0.44 }
txid = self.nodes[1].sendmany("", send_to)
self.sync_all()
check_array_result(self.nodes[1].listtransactions(),
assert_array_result(self.nodes[1].listtransactions(),
{"category":"send","amount":Decimal("-0.11")},
{"txid":txid} )
check_array_result(self.nodes[0].listtransactions(),
assert_array_result(self.nodes[0].listtransactions(),
{"category":"receive","amount":Decimal("0.11")},
{"txid":txid} )
check_array_result(self.nodes[1].listtransactions(),
assert_array_result(self.nodes[1].listtransactions(),
{"category":"send","amount":Decimal("-0.22")},
{"txid":txid} )
check_array_result(self.nodes[1].listtransactions(),
assert_array_result(self.nodes[1].listtransactions(),
{"category":"receive","amount":Decimal("0.22")},
{"txid":txid} )
check_array_result(self.nodes[1].listtransactions(),
assert_array_result(self.nodes[1].listtransactions(),
{"category":"send","amount":Decimal("-0.33")},
{"txid":txid} )
check_array_result(self.nodes[0].listtransactions(),
assert_array_result(self.nodes[0].listtransactions(),
{"category":"receive","amount":Decimal("0.33")},
{"txid":txid, "account" : "from1"} )
check_array_result(self.nodes[1].listtransactions(),
assert_array_result(self.nodes[1].listtransactions(),
{"category":"send","amount":Decimal("-0.44")},
{"txid":txid, "account" : ""} )
check_array_result(self.nodes[1].listtransactions(),
assert_array_result(self.nodes[1].listtransactions(),
{"category":"receive","amount":Decimal("0.44")},
{"txid":txid, "account" : "toself"} )
@@ -99,10 +90,111 @@ class ListTransactionsTest(BitcoinTestFramework):
self.nodes[1].generate(1)
self.sync_all()
assert(len(self.nodes[0].listtransactions("watchonly", 100, 0, False)) == 0)
check_array_result(self.nodes[0].listtransactions("watchonly", 100, 0, True),
assert_array_result(self.nodes[0].listtransactions("watchonly", 100, 0, True),
{"category":"receive","amount":Decimal("0.1")},
{"txid":txid, "account" : "watchonly"} )
self.run_rbf_opt_in_test()
# Check that the opt-in-rbf flag works properly, for sent and received
# transactions.
def run_rbf_opt_in_test(self):
# Check whether a transaction signals opt-in RBF itself
def is_opt_in(node, txid):
rawtx = node.getrawtransaction(txid, 1)
for x in rawtx["vin"]:
if x["sequence"] < 0xfffffffe:
return True
return False
# Find an unconfirmed output matching a certain txid
def get_unconfirmed_utxo_entry(node, txid_to_match):
utxo = node.listunspent(0, 0)
for i in utxo:
if i["txid"] == txid_to_match:
return i
return None
# 1. Chain a few transactions that don't opt-in.
txid_1 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1)
assert(not is_opt_in(self.nodes[0], txid_1))
assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_1}, {"bip125-replaceable":"no"})
sync_mempools(self.nodes)
assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_1}, {"bip125-replaceable":"no"})
# Tx2 will build off txid_1, still not opting in to RBF.
utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[1], txid_1)
# Create tx2 using createrawtransaction
inputs = [{"txid":utxo_to_use["txid"], "vout":utxo_to_use["vout"]}]
outputs = {self.nodes[0].getnewaddress(): 0.999}
tx2 = self.nodes[1].createrawtransaction(inputs, outputs)
tx2_signed = self.nodes[1].signrawtransaction(tx2)["hex"]
txid_2 = self.nodes[1].sendrawtransaction(tx2_signed)
# ...and check the result
assert(not is_opt_in(self.nodes[1], txid_2))
assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_2}, {"bip125-replaceable":"no"})
sync_mempools(self.nodes)
assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_2}, {"bip125-replaceable":"no"})
# Tx3 will opt-in to RBF
utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[0], txid_2)
inputs = [{"txid": txid_2, "vout":utxo_to_use["vout"]}]
outputs = {self.nodes[1].getnewaddress(): 0.998}
tx3 = self.nodes[0].createrawtransaction(inputs, outputs)
tx3_modified = txFromHex(tx3)
tx3_modified.vin[0].nSequence = 0
tx3 = bytes_to_hex_str(tx3_modified.serialize())
tx3_signed = self.nodes[0].signrawtransaction(tx3)['hex']
txid_3 = self.nodes[0].sendrawtransaction(tx3_signed)
assert(is_opt_in(self.nodes[0], txid_3))
assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_3}, {"bip125-replaceable":"yes"})
sync_mempools(self.nodes)
assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_3}, {"bip125-replaceable":"yes"})
# Tx4 will chain off tx3. Doesn't signal itself, but depends on one
# that does.
utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[1], txid_3)
inputs = [{"txid": txid_3, "vout":utxo_to_use["vout"]}]
outputs = {self.nodes[0].getnewaddress(): 0.997}
tx4 = self.nodes[1].createrawtransaction(inputs, outputs)
tx4_signed = self.nodes[1].signrawtransaction(tx4)["hex"]
txid_4 = self.nodes[1].sendrawtransaction(tx4_signed)
assert(not is_opt_in(self.nodes[1], txid_4))
assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"yes"})
sync_mempools(self.nodes)
assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"yes"})
# Replace tx3, and check that tx4 becomes unknown
tx3_b = tx3_modified
tx3_b.vout[0].nValue -= int(Decimal("0.004") * COIN) # bump the fee
tx3_b = bytes_to_hex_str(tx3_b.serialize())
tx3_b_signed = self.nodes[0].signrawtransaction(tx3_b)['hex']
txid_3b = self.nodes[0].sendrawtransaction(tx3_b_signed, True)
assert(is_opt_in(self.nodes[0], txid_3b))
assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"unknown"})
sync_mempools(self.nodes)
assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"unknown"})
# Check gettransaction as well:
for n in self.nodes[0:2]:
assert_equal(n.gettransaction(txid_1)["bip125-replaceable"], "no")
assert_equal(n.gettransaction(txid_2)["bip125-replaceable"], "no")
assert_equal(n.gettransaction(txid_3)["bip125-replaceable"], "yes")
assert_equal(n.gettransaction(txid_3b)["bip125-replaceable"], "yes")
assert_equal(n.gettransaction(txid_4)["bip125-replaceable"], "unknown")
# After mining a transaction, it's no longer BIP125-replaceable
self.nodes[0].generate(1)
assert(txid_3b not in self.nodes[0].getrawmempool())
assert_equal(self.nodes[0].gettransaction(txid_3b)["bip125-replaceable"], "no")
assert_equal(self.nodes[0].gettransaction(txid_4)["bip125-replaceable"], "unknown")
if __name__ == '__main__':
ListTransactionsTest().main()

View File

@@ -1,8 +1,7 @@
#!/usr/bin/env python2
#
# Distributed under the MIT/X11 software license, see the accompanying
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
from test_framework.mininode import *
from test_framework.test_framework import BitcoinTestFramework
@@ -34,7 +33,6 @@ class TestManager(NodeConnCB):
def __init__(self):
NodeConnCB.__init__(self)
self.log = logging.getLogger("BlockRelayTest")
self.create_callback_map()
def add_new_connection(self, connection):
self.connection = connection
@@ -42,40 +40,36 @@ class TestManager(NodeConnCB):
self.disconnectOkay = False
def run(self):
try:
fail = False
self.connection.rpc.generate(1) # Leave IBD
self.connection.rpc.generate(1) # Leave IBD
numBlocksToGenerate = [ 8, 16, 128, 1024 ]
for count in range(len(numBlocksToGenerate)):
current_invs = []
for i in range(numBlocksToGenerate[count]):
current_invs.append(CInv(2, random.randrange(0, 1<<256)))
if len(current_invs) >= 50000:
self.connection.send_message(msg_inv(current_invs))
current_invs = []
if len(current_invs) > 0:
numBlocksToGenerate = [8, 16, 128, 1024]
for count in range(len(numBlocksToGenerate)):
current_invs = []
for i in range(numBlocksToGenerate[count]):
current_invs.append(CInv(2, random.randrange(0, 1 << 256)))
if len(current_invs) >= 50000:
self.connection.send_message(msg_inv(current_invs))
# Wait and see how many blocks were requested
time.sleep(2)
current_invs = []
if len(current_invs) > 0:
self.connection.send_message(msg_inv(current_invs))
total_requests = 0
with mininode_lock:
for key in self.blockReqCounts:
total_requests += self.blockReqCounts[key]
if self.blockReqCounts[key] > 1:
raise AssertionError("Error, test failed: block %064x requested more than once" % key)
if total_requests > MAX_REQUESTS:
raise AssertionError("Error, too many blocks (%d) requested" % total_requests)
print "Round %d: success (total requests: %d)" % (count, total_requests)
except AssertionError as e:
print "TEST FAILED: ", e.args
# Wait and see how many blocks were requested
time.sleep(2)
total_requests = 0
with mininode_lock:
for key in self.blockReqCounts:
total_requests += self.blockReqCounts[key]
if self.blockReqCounts[key] > 1:
raise AssertionError("Error, test failed: block %064x requested more than once" % key)
if total_requests > MAX_REQUESTS:
raise AssertionError("Error, too many blocks (%d) requested" % total_requests)
print("Round %d: success (total requests: %d)" % (count, total_requests))
self.disconnectOkay = True
self.connection.disconnect_node()
class MaxBlocksInFlightTest(BitcoinTestFramework):
def add_options(self, parser):
parser.add_option("--testbinary", dest="testbinary",
@@ -83,11 +77,11 @@ class MaxBlocksInFlightTest(BitcoinTestFramework):
help="Binary to test max block requests behavior")
def setup_chain(self):
print "Initializing test directory "+self.options.tmpdir
print("Initializing test directory "+self.options.tmpdir)
initialize_chain_clean(self.options.tmpdir, 1)
def setup_network(self):
self.nodes = start_nodes(1, self.options.tmpdir,
self.nodes = start_nodes(1, self.options.tmpdir,
extra_args=[['-debug', '-whitelist=127.0.0.1']],
binary=[self.options.testbinary])

View File

@@ -1,13 +1,11 @@
#!/usr/bin/env python2
#
# Distributed under the MIT/X11 software license, see the accompanying
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
from test_framework.mininode import *
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from test_framework.comptool import wait_until
import time
'''
@@ -25,7 +23,6 @@ if uploadtarget has been reached.
class TestNode(NodeConnCB):
def __init__(self):
NodeConnCB.__init__(self)
self.create_callback_map()
self.connection = None
self.ping_counter = 1
self.last_pong = msg_pong()
@@ -85,22 +82,7 @@ class TestNode(NodeConnCB):
class MaxUploadTest(BitcoinTestFramework):
def __init__(self):
self.utxo = []
# Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create
# So we have big transactions and full blocks to fill up our block files
# create one script_pubkey
script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes
for i in xrange (512):
script_pubkey = script_pubkey + "01"
# concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change
self.txouts = "81"
for k in xrange(128):
# add txout value
self.txouts = self.txouts + "0000000000000000"
# add length of script_pubkey
self.txouts = self.txouts + "fd0402"
# add script_pubkey
self.txouts = self.txouts + script_pubkey
self.txouts = gen_return_txouts()
def add_options(self, parser):
parser.add_option("--testbinary", dest="testbinary",
@@ -118,7 +100,7 @@ class MaxUploadTest(BitcoinTestFramework):
def mine_full_block(self, node, address):
# Want to create a full block
# We'll generate a 66k transaction below, and 14 of them is close to the 1MB block limit
for j in xrange(14):
for j in range(14):
if len(self.utxo) < 14:
self.utxo = node.listunspent()
inputs=[]
@@ -156,7 +138,7 @@ class MaxUploadTest(BitcoinTestFramework):
test_nodes = []
connections = []
for i in xrange(3):
for i in range(3):
test_nodes.append(TestNode())
connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_nodes[i]))
test_nodes[i].add_connection(connections[i])
@@ -192,13 +174,13 @@ class MaxUploadTest(BitcoinTestFramework):
getdata_request.inv.append(CInv(2, big_old_block))
max_bytes_per_day = 200*1024*1024
daily_buffer = 144 * 1000000
daily_buffer = 144 * MAX_BLOCK_SIZE
max_bytes_available = max_bytes_per_day - daily_buffer
success_count = max_bytes_available / old_block_size
success_count = max_bytes_available // old_block_size
# 144MB will be reserved for relaying new blocks, so expect this to
# succeed for ~70 tries.
for i in xrange(success_count):
for i in range(success_count):
test_nodes[0].send_message(getdata_request)
test_nodes[0].sync_with_ping()
assert_equal(test_nodes[0].block_receive_map[big_old_block], i+1)
@@ -206,22 +188,22 @@ class MaxUploadTest(BitcoinTestFramework):
assert_equal(len(self.nodes[0].getpeerinfo()), 3)
# At most a couple more tries should succeed (depending on how long
# the test has been running so far).
for i in xrange(3):
for i in range(3):
test_nodes[0].send_message(getdata_request)
test_nodes[0].wait_for_disconnect()
assert_equal(len(self.nodes[0].getpeerinfo()), 2)
print "Peer 0 disconnected after downloading old block too many times"
print("Peer 0 disconnected after downloading old block too many times")
# Requesting the current block on test_nodes[1] should succeed indefinitely,
# even when over the max upload target.
# We'll try 200 times
getdata_request.inv = [CInv(2, big_new_block)]
for i in xrange(200):
for i in range(200):
test_nodes[1].send_message(getdata_request)
test_nodes[1].sync_with_ping()
assert_equal(test_nodes[1].block_receive_map[big_new_block], i+1)
print "Peer 1 able to repeatedly download new block"
print("Peer 1 able to repeatedly download new block")
# But if test_nodes[1] tries for an old block, it gets disconnected too.
getdata_request.inv = [CInv(2, big_old_block)]
@@ -229,9 +211,9 @@ class MaxUploadTest(BitcoinTestFramework):
test_nodes[1].wait_for_disconnect()
assert_equal(len(self.nodes[0].getpeerinfo()), 1)
print "Peer 1 disconnected after trying to download old block"
print("Peer 1 disconnected after trying to download old block")
print "Advancing system time on node to clear counters..."
print("Advancing system time on node to clear counters...")
# If we advance the time by 24 hours, then the counters should reset,
# and test_nodes[2] should be able to retrieve the old block.
@@ -241,12 +223,12 @@ class MaxUploadTest(BitcoinTestFramework):
test_nodes[2].sync_with_ping()
assert_equal(test_nodes[2].block_receive_map[big_old_block], 1)
print "Peer 2 able to download old block"
print("Peer 2 able to download old block")
[c.disconnect_node() for c in connections]
#stop and start node 0 with 1MB maxuploadtarget, whitelist 127.0.0.1
print "Restarting nodes with -whitelist=127.0.0.1"
print("Restarting nodes with -whitelist=127.0.0.1")
stop_node(self.nodes[0], 0)
self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-whitelist=127.0.0.1", "-maxuploadtarget=1", "-blockmaxsize=999000"])
@@ -254,7 +236,7 @@ class MaxUploadTest(BitcoinTestFramework):
test_nodes = []
connections = []
for i in xrange(3):
for i in range(3):
test_nodes.append(TestNode())
connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_nodes[i]))
test_nodes[i].add_connection(connections[i])
@@ -264,7 +246,7 @@ class MaxUploadTest(BitcoinTestFramework):
#retrieve 20 blocks which should be enough to break the 1MB limit
getdata_request.inv = [CInv(2, big_new_block)]
for i in xrange(20):
for i in range(20):
test_nodes[1].send_message(getdata_request)
test_nodes[1].sync_with_ping()
assert_equal(test_nodes[1].block_receive_map[big_new_block], i+1)
@@ -274,7 +256,7 @@ class MaxUploadTest(BitcoinTestFramework):
test_nodes[1].wait_for_disconnect()
assert_equal(len(self.nodes[0].getpeerinfo()), 3) #node is still connected because of the whitelist
print "Peer 1 still connected after trying to download old block (whitelisted)"
print("Peer 1 still connected after trying to download old block (whitelisted)")
[c.disconnect_node() for c in connections]

54
qa/rpc-tests/mempool_limit.py Executable file
View File

@@ -0,0 +1,54 @@
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
# Test mempool limiting together/eviction with the wallet
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
class MempoolLimitTest(BitcoinTestFramework):
def __init__(self):
self.txouts = gen_return_txouts()
def setup_network(self):
self.nodes = []
self.nodes.append(start_node(0, self.options.tmpdir, ["-maxmempool=5", "-spendzeroconfchange=0", "-debug"]))
self.is_network_split = False
self.sync_all()
self.relayfee = self.nodes[0].getnetworkinfo()['relayfee']
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
initialize_chain_clean(self.options.tmpdir, 2)
def run_test(self):
txids = []
utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], 90)
#create a mempool tx that will be evicted
us0 = utxos.pop()
inputs = [{ "txid" : us0["txid"], "vout" : us0["vout"]}]
outputs = {self.nodes[0].getnewaddress() : 0.0001}
tx = self.nodes[0].createrawtransaction(inputs, outputs)
self.nodes[0].settxfee(self.relayfee) # specifically fund this tx with low fee
txF = self.nodes[0].fundrawtransaction(tx)
self.nodes[0].settxfee(0) # return to automatic fee selection
txFS = self.nodes[0].signrawtransaction(txF['hex'])
txid = self.nodes[0].sendrawtransaction(txFS['hex'])
relayfee = self.nodes[0].getnetworkinfo()['relayfee']
base_fee = relayfee*100
for i in range (4):
txids.append([])
txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[30*i:30*i+30], (i+1)*base_fee)
# by now, the tx should be evicted, check confirmation state
assert(txid not in self.nodes[0].getrawmempool())
txdata = self.nodes[0].gettransaction(txid)
assert(txdata['confirmations'] == 0) #confirmation should still be 0
if __name__ == '__main__':
MempoolLimitTest().main()

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014-2015 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -7,6 +7,7 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from test_framework.mininode import COIN
MAX_ANCESTORS = 25
MAX_DESCENDANTS = 25
@@ -27,7 +28,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
send_value = satoshi_round((value - fee)/num_outputs)
inputs = [ {'txid' : parent_txid, 'vout' : vout} ]
outputs = {}
for i in xrange(num_outputs):
for i in range(num_outputs):
outputs[node.getnewaddress()] = send_value
rawtx = node.createrawtransaction(inputs, outputs)
signedtx = node.signrawtransaction(rawtx)
@@ -47,7 +48,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
fee = Decimal("0.0001")
# MAX_ANCESTORS transactions off a confirmed tx should be fine
chain = []
for i in xrange(MAX_ANCESTORS):
for i in range(MAX_ANCESTORS):
(txid, sent_value) = self.chain_transaction(self.nodes[0], txid, 0, value, fee, 1)
value = sent_value
chain.append(txid)
@@ -59,21 +60,53 @@ class MempoolPackagesTest(BitcoinTestFramework):
descendant_count = 1
descendant_fees = 0
descendant_size = 0
SATOSHIS = 100000000
for x in reversed(chain):
assert_equal(mempool[x]['descendantcount'], descendant_count)
descendant_fees += mempool[x]['fee']
assert_equal(mempool[x]['descendantfees'], SATOSHIS*descendant_fees)
assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee'])
assert_equal(mempool[x]['descendantfees'], descendant_fees * COIN)
descendant_size += mempool[x]['size']
assert_equal(mempool[x]['descendantsize'], descendant_size)
descendant_count += 1
# Check that descendant modified fees includes fee deltas from
# prioritisetransaction
self.nodes[0].prioritisetransaction(chain[-1], 0, 1000)
mempool = self.nodes[0].getrawmempool(True)
descendant_fees = 0
for x in reversed(chain):
descendant_fees += mempool[x]['fee']
assert_equal(mempool[x]['descendantfees'], descendant_fees * COIN + 1000)
# Adding one more transaction on to the chain should fail.
try:
self.chain_transaction(self.nodes[0], txid, vout, value, fee, 1)
except JSONRPCException as e:
print "too-long-ancestor-chain successfully rejected"
print("too-long-ancestor-chain successfully rejected")
# Check that prioritising a tx before it's added to the mempool works
# First clear the mempool by mining a block.
self.nodes[0].generate(1)
sync_blocks(self.nodes)
assert_equal(len(self.nodes[0].getrawmempool()), 0)
# Prioritise a transaction that has been mined, then add it back to the
# mempool by using invalidateblock.
self.nodes[0].prioritisetransaction(chain[-1], 0, 2000)
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
# Keep node1's tip synced with node0
self.nodes[1].invalidateblock(self.nodes[1].getbestblockhash())
# Now check that the transaction is in the mempool, with the right modified fee
mempool = self.nodes[0].getrawmempool(True)
descendant_fees = 0
for x in reversed(chain):
descendant_fees += mempool[x]['fee']
if (x == chain[-1]):
assert_equal(mempool[x]['modifiedfee'], mempool[x]['fee']+satoshi_round(0.00002))
assert_equal(mempool[x]['descendantfees'], descendant_fees * COIN + 2000)
# TODO: check that node1's mempool is as expected
@@ -88,22 +121,22 @@ class MempoolPackagesTest(BitcoinTestFramework):
# First create one parent tx with 10 children
(txid, sent_value) = self.chain_transaction(self.nodes[0], txid, vout, value, fee, 10)
parent_transaction = txid
for i in xrange(10):
for i in range(10):
transaction_package.append({'txid': txid, 'vout': i, 'amount': sent_value})
for i in xrange(MAX_DESCENDANTS):
for i in range(MAX_DESCENDANTS):
utxo = transaction_package.pop(0)
try:
(txid, sent_value) = self.chain_transaction(self.nodes[0], utxo['txid'], utxo['vout'], utxo['amount'], fee, 10)
for j in xrange(10):
for j in range(10):
transaction_package.append({'txid': txid, 'vout': j, 'amount': sent_value})
if i == MAX_DESCENDANTS - 2:
mempool = self.nodes[0].getrawmempool(True)
assert_equal(mempool[parent_transaction]['descendantcount'], MAX_DESCENDANTS)
except JSONRPCException as e:
print e.error['message']
print(e.error['message'])
assert_equal(i, MAX_DESCENDANTS - 1)
print "tx that would create too large descendant package successfully rejected"
print("tx that would create too large descendant package successfully rejected")
# TODO: check that node1's mempool is as expected
@@ -138,7 +171,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
send_value = satoshi_round((value - fee)/2)
inputs = [ {'txid' : txid, 'vout' : vout} ]
outputs = {}
for i in xrange(2):
for i in range(2):
outputs[self.nodes[0].getnewaddress()] = send_value
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
signedtx = self.nodes[0].signrawtransaction(rawtx)
@@ -152,7 +185,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
# Create tx2-7
vout = 1
txid = tx0_id
for i in xrange(6):
for i in range(6):
(txid, sent_value) = self.chain_transaction(self.nodes[0], txid, vout, value, fee, 1)
vout = 0
value = sent_value

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -10,8 +10,6 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import os
import shutil
# Create one-input, one-output, no-fee transaction:
class MempoolCoinbaseTest(BitcoinTestFramework):
@@ -25,15 +23,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
self.nodes.append(start_node(1, self.options.tmpdir, args))
connect_nodes(self.nodes[1], 0)
self.is_network_split = False
self.sync_all
def create_tx(self, from_txid, to_address, amount):
inputs = [{ "txid" : from_txid, "vout" : 0}]
outputs = { to_address : amount }
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
signresult = self.nodes[0].signrawtransaction(rawtx)
assert_equal(signresult["complete"], True)
return signresult["hex"]
self.sync_all()
def run_test(self):
start_count = self.nodes[0].getblockcount()
@@ -54,9 +44,9 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
# and make sure the mempool code behaves correctly.
b = [ self.nodes[0].getblockhash(n) for n in range(101, 105) ]
coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
spend_101_raw = self.create_tx(coinbase_txids[1], node1_address, 50)
spend_102_raw = self.create_tx(coinbase_txids[2], node0_address, 50)
spend_103_raw = self.create_tx(coinbase_txids[3], node0_address, 50)
spend_101_raw = create_tx(self.nodes[0], coinbase_txids[1], node1_address, 50)
spend_102_raw = create_tx(self.nodes[0], coinbase_txids[2], node0_address, 50)
spend_103_raw = create_tx(self.nodes[0], coinbase_txids[3], node0_address, 50)
# Create a block-height-locked transaction which will be invalid after reorg
timelock_tx = self.nodes[0].createrawtransaction([{"txid": coinbase_txids[0], "vout": 0}], {node0_address: 50})
@@ -73,8 +63,8 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx)
# Create 102_1 and 103_1:
spend_102_1_raw = self.create_tx(spend_102_id, node1_address, 50)
spend_103_1_raw = self.create_tx(spend_103_id, node1_address, 50)
spend_102_1_raw = create_tx(self.nodes[0], spend_102_id, node1_address, 50)
spend_103_1_raw = create_tx(self.nodes[0], spend_103_id, node1_address, 50)
# Broadcast and mine 103_1:
spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw)
@@ -87,11 +77,11 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
self.sync_all()
assert_equal(set(self.nodes[0].getrawmempool()), set([ spend_101_id, spend_102_1_id, timelock_tx_id ]))
assert_equal(set(self.nodes[0].getrawmempool()), {spend_101_id, spend_102_1_id, timelock_tx_id})
for node in self.nodes:
node.invalidateblock(last_block[0])
assert_equal(set(self.nodes[0].getrawmempool()), set([ spend_101_id, spend_102_1_id, spend_103_1_id ]))
assert_equal(set(self.nodes[0].getrawmempool()), {spend_101_id, spend_102_1_id, spend_103_1_id})
# Use invalidateblock to re-org back and make all those coinbase spends
# immature/invalid:

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -10,8 +10,6 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import os
import shutil
# Create one-input, one-output, no-fee transaction:
class MempoolCoinbaseTest(BitcoinTestFramework):
@@ -23,14 +21,6 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
self.nodes.append(start_node(0, self.options.tmpdir, args))
self.is_network_split = False
def create_tx(self, from_txid, to_address, amount):
inputs = [{ "txid" : from_txid, "vout" : 0}]
outputs = { to_address : amount }
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
signresult = self.nodes[0].signrawtransaction(rawtx)
assert_equal(signresult["complete"], True)
return signresult["hex"]
def run_test(self):
node0_address = self.nodes[0].getnewaddress()
# Spend block 1/2/3's coinbase transactions
@@ -45,13 +35,13 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
b = [ self.nodes[0].getblockhash(n) for n in range(1, 4) ]
coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
spends1_raw = [ self.create_tx(txid, node0_address, 50) for txid in coinbase_txids ]
spends1_raw = [ create_tx(self.nodes[0], txid, node0_address, 50) for txid in coinbase_txids ]
spends1_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends1_raw ]
blocks = []
blocks.extend(self.nodes[0].generate(1))
spends2_raw = [ self.create_tx(txid, node0_address, 49.99) for txid in spends1_id ]
spends2_raw = [ create_tx(self.nodes[0], txid, node0_address, 49.99) for txid in spends1_id ]
spends2_id = [ self.nodes[0].sendrawtransaction(tx) for tx in spends2_raw ]
blocks.extend(self.nodes[0].generate(1))

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -15,8 +15,6 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import os
import shutil
# Create one-input, one-output, no-fee transaction:
class MempoolSpendCoinbaseTest(BitcoinTestFramework):
@@ -28,14 +26,6 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework):
self.nodes.append(start_node(0, self.options.tmpdir, args))
self.is_network_split = False
def create_tx(self, from_txid, to_address, amount):
inputs = [{ "txid" : from_txid, "vout" : 0}]
outputs = { to_address : amount }
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
signresult = self.nodes[0].signrawtransaction(rawtx)
assert_equal(signresult["complete"], True)
return signresult["hex"]
def run_test(self):
chain_height = self.nodes[0].getblockcount()
assert_equal(chain_height, 200)
@@ -46,7 +36,7 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework):
# is too immature to spend.
b = [ self.nodes[0].getblockhash(n) for n in range(101, 103) ]
coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
spends_raw = [ self.create_tx(txid, node0_address, 50) for txid in coinbase_txids ]
spends_raw = [ create_tx(self.nodes[0], txid, node0_address, 50) for txid in coinbase_txids ]
spend_101_id = self.nodes[0].sendrawtransaction(spends_raw[0])

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -9,8 +9,6 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import os
import shutil
class MerkleBlockTest(BitcoinTestFramework):
@@ -34,7 +32,7 @@ class MerkleBlockTest(BitcoinTestFramework):
self.sync_all()
def run_test(self):
print "Mining blocks..."
print("Mining blocks...")
self.nodes[0].generate(105)
self.sync_all()

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2015 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -9,16 +9,9 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import base64
try:
import http.client as httplib
except ImportError:
import httplib
try:
import urllib.parse as urlparse
except ImportError:
import urlparse
import http.client
import urllib.parse
class HTTPBasicsTest (BitcoinTestFramework):
def setup_nodes(self):
@@ -39,12 +32,12 @@ class HTTPBasicsTest (BitcoinTestFramework):
##################################################
# Check correctness of the rpcauth config option #
##################################################
url = urlparse.urlparse(self.nodes[0].url)
url = urllib.parse.urlparse(self.nodes[0].url)
#Old authpair
authpair = url.username + ':' + url.password
#New authpair generated via contrib/rpcuser tool
#New authpair generated via share/rpcuser tool
rpcauth = "rpcauth=rt:93648e835a54c573682c2eb19f882535$7681e9c5b74bdd85e78166031d2058e1069b3ed7ed967c93fc63abba06f31144"
password = "cA773lm788buwYe4g4WT+05pKyNruVKjQ25x3n0DQcM="
@@ -53,9 +46,9 @@ class HTTPBasicsTest (BitcoinTestFramework):
password2 = "8/F3uMDw4KSEbw96U3CA1C4X05dkHDN2BPFjTgZW4KI="
authpairnew = "rt:"+password
headers = {"Authorization": "Basic " + base64.b64encode(authpair)}
headers = {"Authorization": "Basic " + str_to_b64str(authpair)}
conn = httplib.HTTPConnection(url.hostname, url.port)
conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
resp = conn.getresponse()
@@ -63,9 +56,9 @@ class HTTPBasicsTest (BitcoinTestFramework):
conn.close()
#Use new authpair to confirm both work
headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)}
headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
conn = httplib.HTTPConnection(url.hostname, url.port)
conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
resp = conn.getresponse()
@@ -74,9 +67,9 @@ class HTTPBasicsTest (BitcoinTestFramework):
#Wrong login name with rt's password
authpairnew = "rtwrong:"+password
headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)}
headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
conn = httplib.HTTPConnection(url.hostname, url.port)
conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
resp = conn.getresponse()
@@ -85,9 +78,9 @@ class HTTPBasicsTest (BitcoinTestFramework):
#Wrong password for rt
authpairnew = "rt:"+password+"wrong"
headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)}
headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
conn = httplib.HTTPConnection(url.hostname, url.port)
conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
resp = conn.getresponse()
@@ -96,9 +89,9 @@ class HTTPBasicsTest (BitcoinTestFramework):
#Correct for rt2
authpairnew = "rt2:"+password2
headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)}
headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
conn = httplib.HTTPConnection(url.hostname, url.port)
conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
resp = conn.getresponse()
@@ -107,9 +100,9 @@ class HTTPBasicsTest (BitcoinTestFramework):
#Wrong password for rt2
authpairnew = "rt2:"+password2+"wrong"
headers = {"Authorization": "Basic " + base64.b64encode(authpairnew)}
headers = {"Authorization": "Basic " + str_to_b64str(authpairnew)}
conn = httplib.HTTPConnection(url.hostname, url.port)
conn = http.client.HTTPConnection(url.hostname, url.port)
conn.connect()
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
resp = conn.getresponse()
@@ -117,6 +110,5 @@ class HTTPBasicsTest (BitcoinTestFramework):
conn.close()
if __name__ == '__main__':
HTTPBasicsTest ().main ()

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -9,16 +9,9 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import base64
try:
import http.client as httplib
except ImportError:
import httplib
try:
import urllib.parse as urlparse
except ImportError:
import urlparse
import http.client
import urllib.parse
class NodeHandlingTest (BitcoinTestFramework):
def run_test(self):
@@ -54,7 +47,7 @@ class NodeHandlingTest (BitcoinTestFramework):
self.nodes[2].setban("127.0.0.0/24", "add")
self.nodes[2].setban("192.168.0.1", "add", 1) #ban for 1 seconds
self.nodes[2].setban("2001:4d48:ac57:400:cacf:e9ff:fe1d:9c63/19", "add", 1000) #ban for 1000 seconds
listBeforeShutdown = self.nodes[2].listbanned();
listBeforeShutdown = self.nodes[2].listbanned()
assert_equal("192.168.0.1/32", listBeforeShutdown[2]['address']) #must be here
time.sleep(2) #make 100% sure we expired 192.168.0.1 node time
@@ -62,7 +55,7 @@ class NodeHandlingTest (BitcoinTestFramework):
stop_node(self.nodes[2], 2)
self.nodes[2] = start_node(2, self.options.tmpdir)
listAfterShutdown = self.nodes[2].listbanned();
listAfterShutdown = self.nodes[2].listbanned()
assert_equal("127.0.0.0/24", listAfterShutdown[0]['address'])
assert_equal("127.0.0.0/32", listAfterShutdown[1]['address'])
assert_equal("/19" in listAfterShutdown[2]['address'], True)
@@ -70,7 +63,7 @@ class NodeHandlingTest (BitcoinTestFramework):
###########################
# RPC disconnectnode test #
###########################
url = urlparse.urlparse(self.nodes[1].url)
url = urllib.parse.urlparse(self.nodes[1].url)
self.nodes[0].disconnectnode(url.hostname+":"+str(p2p_port(1)))
time.sleep(2) #disconnecting a node needs a little bit of time
for node in self.nodes[0].getpeerinfo():

View File

@@ -1,8 +1,7 @@
#!/usr/bin/env python2
#
# Distributed under the MIT/X11 software license, see the accompanying
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
from test_framework.mininode import *
from test_framework.test_framework import BitcoinTestFramework
@@ -62,7 +61,6 @@ The test:
class TestNode(NodeConnCB):
def __init__(self):
NodeConnCB.__init__(self)
self.create_callback_map()
self.connection = None
self.ping_counter = 1
self.last_pong = msg_pong()
@@ -146,13 +144,13 @@ class AcceptBlockTest(BitcoinTestFramework):
# 1. Have both nodes mine a block (leave IBD)
[ n.generate(1) for n in self.nodes ]
tips = [ int ("0x" + n.getbestblockhash() + "L", 0) for n in self.nodes ]
tips = [ int("0x" + n.getbestblockhash(), 0) for n in self.nodes ]
# 2. Send one block that builds on each tip.
# This should be accepted.
blocks_h2 = [] # the height 2 blocks on each node's chain
block_time = time.time() + 1
for i in xrange(2):
block_time = int(time.time()) + 1
for i in range(2):
blocks_h2.append(create_block(tips[i], create_coinbase(2), block_time))
blocks_h2[i].solve()
block_time += 1
@@ -162,11 +160,11 @@ class AcceptBlockTest(BitcoinTestFramework):
[ x.sync_with_ping() for x in [test_node, white_node] ]
assert_equal(self.nodes[0].getblockcount(), 2)
assert_equal(self.nodes[1].getblockcount(), 2)
print "First height 2 block accepted by both nodes"
print("First height 2 block accepted by both nodes")
# 3. Send another block that builds on the original tip.
blocks_h2f = [] # Blocks at height 2 that fork off the main chain
for i in xrange(2):
for i in range(2):
blocks_h2f.append(create_block(tips[i], create_coinbase(2), blocks_h2[i].nTime+1))
blocks_h2f[i].solve()
test_node.send_message(msg_block(blocks_h2f[0]))
@@ -181,11 +179,11 @@ class AcceptBlockTest(BitcoinTestFramework):
if x['hash'] == blocks_h2f[1].hash:
assert_equal(x['status'], "valid-headers")
print "Second height 2 block accepted only from whitelisted peer"
print("Second height 2 block accepted only from whitelisted peer")
# 4. Now send another block that builds on the forking chain.
blocks_h3 = []
for i in xrange(2):
for i in range(2):
blocks_h3.append(create_block(blocks_h2f[i].sha256, create_coinbase(3), blocks_h2f[i].nTime+1))
blocks_h3[i].solve()
test_node.send_message(msg_block(blocks_h3[0]))
@@ -201,13 +199,13 @@ class AcceptBlockTest(BitcoinTestFramework):
# But this block should be accepted by node0 since it has more work.
try:
self.nodes[0].getblock(blocks_h3[0].hash)
print "Unrequested more-work block accepted from non-whitelisted peer"
print("Unrequested more-work block accepted from non-whitelisted peer")
except:
raise AssertionError("Unrequested more work block was not processed")
# Node1 should have accepted and reorged.
assert_equal(self.nodes[1].getblockcount(), 3)
print "Successfully reorged to length 3 chain from whitelisted peer"
print("Successfully reorged to length 3 chain from whitelisted peer")
# 4b. Now mine 288 more blocks and deliver; all should be processed but
# the last (height-too-high) on node0. Node1 should process the tip if
@@ -215,8 +213,8 @@ class AcceptBlockTest(BitcoinTestFramework):
tips = blocks_h3
headers_message = msg_headers()
all_blocks = [] # node0's blocks
for j in xrange(2):
for i in xrange(288):
for j in range(2):
for i in range(288):
next_block = create_block(tips[j].sha256, create_coinbase(i + 4), tips[j].nTime+1)
next_block.solve()
if j==0:
@@ -234,7 +232,7 @@ class AcceptBlockTest(BitcoinTestFramework):
raise AssertionError("Unrequested block too far-ahead should have been ignored")
except:
if x == all_blocks[287]:
print "Unrequested block too far-ahead not processed"
print("Unrequested block too far-ahead not processed")
else:
raise AssertionError("Unrequested block with more work should have been accepted")
@@ -244,7 +242,7 @@ class AcceptBlockTest(BitcoinTestFramework):
try:
white_node.sync_with_ping()
self.nodes[1].getblock(tips[1].hash)
print "Unrequested block far ahead of tip accepted from whitelisted peer"
print("Unrequested block far ahead of tip accepted from whitelisted peer")
except:
raise AssertionError("Unrequested block from whitelisted peer not accepted")
@@ -260,7 +258,7 @@ class AcceptBlockTest(BitcoinTestFramework):
# a getdata request for this block.
test_node.sync_with_ping()
assert_equal(self.nodes[0].getblockcount(), 2)
print "Unrequested block that would complete more-work chain was ignored"
print("Unrequested block that would complete more-work chain was ignored")
# 6. Try to get node to request the missing block.
# Poke the node with an inv for block at height 3 and see if that
@@ -276,14 +274,14 @@ class AcceptBlockTest(BitcoinTestFramework):
# Check that the getdata includes the right block
assert_equal(getdata.inv[0].hash, blocks_h2f[0].sha256)
print "Inv at tip triggered getdata for unprocessed block"
print("Inv at tip triggered getdata for unprocessed block")
# 7. Send the missing block for the third time (now it is requested)
test_node.send_message(msg_block(blocks_h2f[0]))
test_node.sync_with_ping()
assert_equal(self.nodes[0].getblockcount(), 290)
print "Successfully reorged to longer chain from non-whitelisted peer"
print("Successfully reorged to longer chain from non-whitelisted peer")
[ c.disconnect_node() for c in connections ]

View File

@@ -1,21 +1,15 @@
#!/usr/bin/env python2
#
# Distributed under the MIT/X11 software license, see the accompanying
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
from test_framework.test_framework import ComparisonTestFramework
from test_framework.util import *
from test_framework.comptool import TestManager, TestInstance
from test_framework.mininode import *
from test_framework.comptool import TestManager, TestInstance, RejectResult
from test_framework.blocktools import *
import logging
import copy
import time
import numbers
from test_framework.key import CECKey
from test_framework.script import CScript, CScriptOp, SignatureHash, SIGHASH_ALL, OP_TRUE
from test_framework.script import CScript, SignatureHash, SIGHASH_ALL, OP_TRUE, OP_FALSE
class PreviousSpendableOutput(object):
def __init__(self, tx = CTransaction(), n = -1):
@@ -38,7 +32,7 @@ class FullBlockTest(ComparisonTestFramework):
self.num_nodes = 1
self.block_heights = {}
self.coinbase_key = CECKey()
self.coinbase_key.set_secretbytes(bytes("horsebattery"))
self.coinbase_key.set_secretbytes(b"horsebattery")
self.coinbase_pubkey = self.coinbase_key.get_pubkey()
self.block_time = int(time.time())+1
self.tip = None
@@ -75,7 +69,7 @@ class FullBlockTest(ComparisonTestFramework):
block = create_block(base_block_hash, coinbase, self.block_time)
if (spend != None):
tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(spend.tx.sha256, spend.n), "", 0xffffffff)) # no signature yet
tx.vin.append(CTxIn(COutPoint(spend.tx.sha256, spend.n), b"", 0xffffffff)) # no signature yet
# This copies the java comparison tool testing behavior: the first
# txout has a garbage scriptPubKey, "to make sure we're not
# pre-verifying too much" (?)
@@ -85,7 +79,7 @@ class FullBlockTest(ComparisonTestFramework):
else:
tx.vout.append(CTxOut(1, script))
# Now sign it if necessary
scriptSig = ""
scriptSig = b""
scriptPubKey = bytearray(spend.tx.vout[spend.n].scriptPubKey)
if (scriptPubKey[0] == OP_TRUE): # looks like an anyone-can-spend
scriptSig = CScript([OP_TRUE])
@@ -122,13 +116,29 @@ class FullBlockTest(ComparisonTestFramework):
return TestInstance([[self.tip, True]])
# returns a test case that asserts that the current tip was rejected
def rejected():
return TestInstance([[self.tip, False]])
def rejected(reject = None):
if reject is None:
return TestInstance([[self.tip, False]])
else:
return TestInstance([[self.tip, reject]])
# move the tip back to a previous block
def tip(number):
self.tip = self.blocks[number]
# add transactions to a block produced by next_block
def update_block(block_number, new_transactions):
block = self.blocks[block_number]
old_hash = block.sha256
self.add_transactions_to_block(block, new_transactions)
block.solve()
# Update the internal state just like in next_block
self.tip = block
self.block_heights[block.sha256] = self.block_heights[old_hash]
del self.block_heights[old_hash]
self.blocks[block_number] = block
return block
# creates a new block and advances the tip to that block
block = self.next_block
@@ -141,14 +151,15 @@ class FullBlockTest(ComparisonTestFramework):
# Now we need that block to mature so we can spend the coinbase.
test = TestInstance(sync_every_block=False)
for i in range(100):
for i in range(99):
block(1000 + i)
test.blocks_and_transactions.append([self.tip, True])
save_spendable_output()
yield test
# Start by bulding a couple of blocks on top (which output is spent is in parentheses):
# Start by building a couple of blocks on top (which output is spent is
# in parentheses):
# genesis -> b1 (0) -> b2 (1)
out0 = get_spendable_output()
block(1, spend=out0)
@@ -156,8 +167,7 @@ class FullBlockTest(ComparisonTestFramework):
yield accepted()
out1 = get_spendable_output()
block(2, spend=out1)
# Inv again, then deliver twice (shouldn't break anything).
b2 = block(2, spend=out1)
yield accepted()
@@ -168,8 +178,8 @@ class FullBlockTest(ComparisonTestFramework):
#
# Nothing should happen at this point. We saw b2 first so it takes priority.
tip(1)
block(3, spend=out1)
# Deliver twice (should still not break anything)
b3 = block(3, spend=out1)
txout_b3 = PreviousSpendableOutput(b3.vtx[1], 1)
yield rejected()
@@ -214,7 +224,7 @@ class FullBlockTest(ComparisonTestFramework):
# \-> b3 (1) -> b4 (2)
tip(6)
block(9, spend=out4, additional_coinbase_value=1)
yield rejected()
yield rejected(RejectResult(16, b'bad-cb-amount'))
# Create a fork that ends in a block with too much fee (the one that causes the reorg)
@@ -226,7 +236,7 @@ class FullBlockTest(ComparisonTestFramework):
yield rejected()
block(11, spend=out4, additional_coinbase_value=1)
yield rejected()
yield rejected(RejectResult(16, b'bad-cb-amount'))
# Try again, but with a valid fork first
@@ -252,9 +262,13 @@ class FullBlockTest(ComparisonTestFramework):
yield TestInstance([[b12, True, b13.sha256]]) # New tip should be b13.
# Add a block with MAX_BLOCK_SIGOPS and one with one more sigop
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
# \-> b12 (3) -> b13 (4) -> b15 (5) -> b16 (6)
# \-> b3 (1) -> b4 (2)
# Test that a block with a lot of checksigs is okay
lots_of_checksigs = CScript([OP_CHECKSIG] * (1000000 / 50 - 1))
lots_of_checksigs = CScript([OP_CHECKSIG] * (1000000 // 50 - 1))
tip(13)
block(15, spend=out5, script=lots_of_checksigs)
yield accepted()
@@ -262,10 +276,123 @@ class FullBlockTest(ComparisonTestFramework):
# Test that a block with too many checksigs is rejected
out6 = get_spendable_output()
too_many_checksigs = CScript([OP_CHECKSIG] * (1000000 / 50))
too_many_checksigs = CScript([OP_CHECKSIG] * (1000000 // 50))
block(16, spend=out6, script=too_many_checksigs)
yield rejected(RejectResult(16, b'bad-blk-sigops'))
# Attempt to spend a transaction created on a different fork
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
# \-> b12 (3) -> b13 (4) -> b15 (5) -> b17 (b3.vtx[1])
# \-> b3 (1) -> b4 (2)
tip(15)
block(17, spend=txout_b3)
yield rejected(RejectResult(16, b'bad-txns-inputs-missingorspent'))
# Attempt to spend a transaction created on a different fork (on a fork this time)
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
# \-> b12 (3) -> b13 (4) -> b15 (5)
# \-> b18 (b3.vtx[1]) -> b19 (6)
# \-> b3 (1) -> b4 (2)
tip(13)
block(18, spend=txout_b3)
yield rejected()
block(19, spend=out6)
yield rejected()
# Attempt to spend a coinbase at depth too low
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
# \-> b12 (3) -> b13 (4) -> b15 (5) -> b20 (7)
# \-> b3 (1) -> b4 (2)
tip(15)
out7 = get_spendable_output()
block(20, spend=out7)
yield rejected(RejectResult(16, b'bad-txns-premature-spend-of-coinbase'))
# Attempt to spend a coinbase at depth too low (on a fork this time)
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
# \-> b12 (3) -> b13 (4) -> b15 (5)
# \-> b21 (6) -> b22 (5)
# \-> b3 (1) -> b4 (2)
tip(13)
block(21, spend=out6)
yield rejected()
block(22, spend=out5)
yield rejected()
# Create a block on either side of MAX_BLOCK_SIZE and make sure its accepted/rejected
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
# \-> b12 (3) -> b13 (4) -> b15 (5) -> b23 (6)
# \-> b24 (6) -> b25 (7)
# \-> b3 (1) -> b4 (2)
tip(15)
b23 = block(23, spend=out6)
old_hash = b23.sha256
tx = CTransaction()
script_length = MAX_BLOCK_SIZE - len(b23.serialize()) - 69
script_output = CScript([b'\x00' * script_length])
tx.vout.append(CTxOut(0, script_output))
tx.vin.append(CTxIn(COutPoint(b23.vtx[1].sha256, 1)))
b23 = update_block(23, [tx])
# Make sure the math above worked out to produce a max-sized block
assert_equal(len(b23.serialize()), MAX_BLOCK_SIZE)
yield accepted()
# Make the next block one byte bigger and check that it fails
tip(15)
b24 = block(24, spend=out6)
script_length = MAX_BLOCK_SIZE - len(b24.serialize()) - 69
script_output = CScript([b'\x00' * (script_length+1)])
tx.vout = [CTxOut(0, script_output)]
b24 = update_block(24, [tx])
assert_equal(len(b24.serialize()), MAX_BLOCK_SIZE+1)
yield rejected(RejectResult(16, b'bad-blk-length'))
b25 = block(25, spend=out7)
yield rejected()
# Create blocks with a coinbase input script size out of range
# genesis -> b1 (0) -> b2 (1) -> b5 (2) -> b6 (3)
# \-> b12 (3) -> b13 (4) -> b15 (5) -> b23 (6) -> b30 (7)
# \-> ... (6) -> ... (7)
# \-> b3 (1) -> b4 (2)
tip(15)
b26 = block(26, spend=out6)
b26.vtx[0].vin[0].scriptSig = b'\x00'
b26.vtx[0].rehash()
# update_block causes the merkle root to get updated, even with no new
# transactions, and updates the required state.
b26 = update_block(26, [])
yield rejected(RejectResult(16, b'bad-cb-length'))
# Extend the b26 chain to make sure bitcoind isn't accepting b26
b27 = block(27, spend=out7)
yield rejected()
# Now try a too-large-coinbase script
tip(15)
b28 = block(28, spend=out6)
b28.vtx[0].vin[0].scriptSig = b'\x00' * 101
b28.vtx[0].rehash()
b28 = update_block(28, [])
yield rejected(RejectResult(16, b'bad-cb-length'))
# Extend the b28 chain to make sure bitcoind isn't accepted b28
b29 = block(29, spend=out7)
# TODO: Should get a reject message back with "bad-prevblk", except
# there's a bug that prevents this from being detected. Just note
# failure for now, and add the reject result later.
yield rejected()
# b30 has a max-sized coinbase scriptSig.
tip(23)
b30 = block(30)
b30.vtx[0].vin[0].scriptSig = b'\x00' * 100
b30.vtx[0].rehash()
b30 = update_block(30, [])
yield accepted()
if __name__ == '__main__':

View File

@@ -0,0 +1,159 @@
#!/usr/bin/env python3
# Copyright (c) 2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.mininode import *
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import time
from test_framework.blocktools import create_block, create_coinbase
'''
Test version bits' warning system.
Generate chains with block versions that appear to be signalling unknown
soft-forks, and test that warning alerts are generated.
'''
VB_PERIOD = 144 # versionbits period length for regtest
VB_THRESHOLD = 108 # versionbits activation threshold for regtest
VB_TOP_BITS = 0x20000000
VB_UNKNOWN_BIT = 27 # Choose a bit unassigned to any deployment
# TestNode: bare-bones "peer". Used mostly as a conduit for a test to sending
# p2p messages to a node, generating the messages in the main testing logic.
class TestNode(NodeConnCB):
def __init__(self):
NodeConnCB.__init__(self)
self.connection = None
self.ping_counter = 1
self.last_pong = msg_pong()
def add_connection(self, conn):
self.connection = conn
def on_inv(self, conn, message):
pass
# Wrapper for the NodeConn's send_message function
def send_message(self, message):
self.connection.send_message(message)
def on_pong(self, conn, message):
self.last_pong = message
# Sync up with the node after delivery of a block
def sync_with_ping(self, timeout=30):
self.connection.send_message(msg_ping(nonce=self.ping_counter))
received_pong = False
sleep_time = 0.05
while not received_pong and timeout > 0:
time.sleep(sleep_time)
timeout -= sleep_time
with mininode_lock:
if self.last_pong.nonce == self.ping_counter:
received_pong = True
self.ping_counter += 1
return received_pong
class VersionBitsWarningTest(BitcoinTestFramework):
def setup_chain(self):
initialize_chain_clean(self.options.tmpdir, 1)
def setup_network(self):
self.nodes = []
self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt")
# Open and close to create zero-length file
with open(self.alert_filename, 'w') as f:
pass
self.node_options = ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]
self.nodes.append(start_node(0, self.options.tmpdir, self.node_options))
import re
self.vb_pattern = re.compile("^Warning.*versionbit")
# Send numblocks blocks via peer with nVersionToUse set.
def send_blocks_with_version(self, peer, numblocks, nVersionToUse):
tip = self.nodes[0].getbestblockhash()
height = self.nodes[0].getblockcount()
block_time = self.nodes[0].getblockheader(tip)["time"]+1
tip = int(tip, 16)
for i in range(numblocks):
block = create_block(tip, create_coinbase(height+1), block_time)
block.nVersion = nVersionToUse
block.solve()
peer.send_message(msg_block(block))
block_time += 1
height += 1
tip = block.sha256
peer.sync_with_ping()
def test_versionbits_in_alert_file(self):
with open(self.alert_filename, 'r') as f:
alert_text = f.read()
assert(self.vb_pattern.match(alert_text))
def run_test(self):
# Setup the p2p connection and start up the network thread.
test_node = TestNode()
connections = []
connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], test_node))
test_node.add_connection(connections[0])
NetworkThread().start() # Start up network handling in another thread
# Test logic begins here
test_node.wait_for_verack()
# 1. Have the node mine one period worth of blocks
self.nodes[0].generate(VB_PERIOD)
# 2. Now build one period of blocks on the tip, with < VB_THRESHOLD
# blocks signaling some unknown bit.
nVersion = VB_TOP_BITS | (1<<VB_UNKNOWN_BIT)
self.send_blocks_with_version(test_node, VB_THRESHOLD-1, nVersion)
# Fill rest of period with regular version blocks
self.nodes[0].generate(VB_PERIOD - VB_THRESHOLD + 1)
# Check that we're not getting any versionbit-related errors in
# getinfo()
assert(not self.vb_pattern.match(self.nodes[0].getinfo()["errors"]))
# 3. Now build one period of blocks with >= VB_THRESHOLD blocks signaling
# some unknown bit
self.send_blocks_with_version(test_node, VB_THRESHOLD, nVersion)
self.nodes[0].generate(VB_PERIOD - VB_THRESHOLD)
# Might not get a versionbits-related alert yet, as we should
# have gotten a different alert due to more than 51/100 blocks
# being of unexpected version.
# Check that getinfo() shows some kind of error.
assert(len(self.nodes[0].getinfo()["errors"]) != 0)
# Mine a period worth of expected blocks so the generic block-version warning
# is cleared, and restart the node. This should move the versionbit state
# to ACTIVE.
self.nodes[0].generate(VB_PERIOD)
stop_node(self.nodes[0], 0)
wait_bitcoinds()
# Empty out the alert file
with open(self.alert_filename, 'w') as f:
pass
self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""])
# Connecting one block should be enough to generate an error.
self.nodes[0].generate(1)
assert(len(self.nodes[0].getinfo()["errors"]) != 0)
stop_node(self.nodes[0], 0)
wait_bitcoinds()
self.test_versionbits_in_alert_file()
# Test framework expects the node to still be running...
self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""])
if __name__ == '__main__':
VersionBitsWarningTest().main()

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2015 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -9,27 +9,12 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
COIN = 100000000
from test_framework.mininode import COIN, MAX_BLOCK_SIZE
class PrioritiseTransactionTest(BitcoinTestFramework):
def __init__(self):
# Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create
# So we have big transactions (and therefore can't fit very many into each block)
# create one script_pubkey
script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes
for i in xrange (512):
script_pubkey = script_pubkey + "01"
# concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change
self.txouts = "81"
for k in xrange(128):
# add txout value
self.txouts = self.txouts + "0000000000000000"
# add length of script_pubkey
self.txouts = self.txouts + "fd0402"
# add script_pubkey
self.txouts = self.txouts + script_pubkey
self.txouts = gen_return_txouts()
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
@@ -42,62 +27,30 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-printpriority=1"]))
self.relayfee = self.nodes[0].getnetworkinfo()['relayfee']
def create_confirmed_utxos(self, count):
self.nodes[0].generate(int(0.5*count)+101)
utxos = self.nodes[0].listunspent()
iterations = count - len(utxos)
addr1 = self.nodes[0].getnewaddress()
addr2 = self.nodes[0].getnewaddress()
if iterations <= 0:
return utxos
for i in xrange(iterations):
t = utxos.pop()
fee = self.relayfee
inputs = []
inputs.append({ "txid" : t["txid"], "vout" : t["vout"]})
outputs = {}
send_value = t['amount'] - fee
outputs[addr1] = satoshi_round(send_value/2)
outputs[addr2] = satoshi_round(send_value/2)
raw_tx = self.nodes[0].createrawtransaction(inputs, outputs)
signed_tx = self.nodes[0].signrawtransaction(raw_tx)["hex"]
txid = self.nodes[0].sendrawtransaction(signed_tx)
while (self.nodes[0].getmempoolinfo()['size'] > 0):
self.nodes[0].generate(1)
utxos = self.nodes[0].listunspent()
assert(len(utxos) >= count)
return utxos
def create_lots_of_big_transactions(self, utxos, fee):
addr = self.nodes[0].getnewaddress()
txids = []
for i in xrange(len(utxos)):
t = utxos.pop()
inputs = []
inputs.append({ "txid" : t["txid"], "vout" : t["vout"]})
outputs = {}
send_value = t['amount'] - fee
outputs[addr] = satoshi_round(send_value)
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
newtx = rawtx[0:92]
newtx = newtx + self.txouts
newtx = newtx + rawtx[94:]
signresult = self.nodes[0].signrawtransaction(newtx, None, None, "NONE")
txid = self.nodes[0].sendrawtransaction(signresult["hex"], True)
txids.append(txid)
return txids
def run_test(self):
utxos = self.create_confirmed_utxos(90)
utxo_count = 90
utxos = create_confirmed_utxos(self.relayfee, self.nodes[0], utxo_count)
base_fee = self.relayfee*100 # our transactions are smaller than 100kb
txids = []
# Create 3 batches of transactions at 3 different fee rate levels
for i in xrange(3):
range_size = utxo_count // 3
for i in range(3):
txids.append([])
txids[i] = self.create_lots_of_big_transactions(utxos[30*i:30*i+30], (i+1)*base_fee)
start_range = i * range_size
end_range = start_range + range_size
txids[i] = create_lots_of_big_transactions(self.nodes[0], self.txouts, utxos[start_range:end_range], (i+1)*base_fee)
# Make sure that the size of each group of transactions exceeds
# MAX_BLOCK_SIZE -- otherwise the test needs to be revised to create
# more transactions.
mempool = self.nodes[0].getrawmempool(True)
sizes = [0, 0, 0]
for i in range(3):
for j in txids[i]:
assert(j in mempool)
sizes[i] += mempool[j]['size']
assert(sizes[i] > MAX_BLOCK_SIZE) # Fail => raise utxo_count
# add a fee delta to something in the cheapest bucket and make sure it gets mined
# also check that a different entry in the cheapest bucket is NOT mined (lower
@@ -108,7 +61,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
self.nodes[0].generate(1)
mempool = self.nodes[0].getrawmempool()
print "Assert that prioritised transasction was mined"
print("Assert that prioritised transaction was mined")
assert(txids[0][0] not in mempool)
assert(txids[0][1] in mempool)
@@ -121,7 +74,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
assert(high_fee_tx != None)
# Add a prioritisation before a tx is in the mempool (de-prioritising a
# high-fee transaction).
# high-fee transaction so that it's now low fee).
self.nodes[0].prioritisetransaction(high_fee_tx, -1e15, -int(2*base_fee*COIN))
# Add everything back to mempool
@@ -131,17 +84,60 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
mempool = self.nodes[0].getrawmempool()
assert(high_fee_tx in mempool)
# Now verify the high feerate transaction isn't mined.
self.nodes[0].generate(5)
# Now verify the modified-high feerate transaction isn't mined before
# the other high fee transactions. Keep mining until our mempool has
# decreased by all the high fee size that we calculated above.
while (self.nodes[0].getmempoolinfo()['bytes'] > sizes[0] + sizes[1]):
self.nodes[0].generate(1)
# High fee transaction should not have been mined, but other high fee rate
# transactions should have been.
mempool = self.nodes[0].getrawmempool()
print "Assert that de-prioritised transaction is still in mempool"
print("Assert that de-prioritised transaction is still in mempool")
assert(high_fee_tx in mempool)
for x in txids[2]:
if (x != high_fee_tx):
assert(x not in mempool)
# Create a free, low priority transaction. Should be rejected.
utxo_list = self.nodes[0].listunspent()
assert(len(utxo_list) > 0)
utxo = utxo_list[0]
inputs = []
outputs = {}
inputs.append({"txid" : utxo["txid"], "vout" : utxo["vout"]})
outputs[self.nodes[0].getnewaddress()] = utxo["amount"] - self.relayfee
raw_tx = self.nodes[0].createrawtransaction(inputs, outputs)
tx_hex = self.nodes[0].signrawtransaction(raw_tx)["hex"]
txid = self.nodes[0].sendrawtransaction(tx_hex)
# A tx that spends an in-mempool tx has 0 priority, so we can use it to
# test the effect of using prioritise transaction for mempool acceptance
inputs = []
inputs.append({"txid": txid, "vout": 0})
outputs = {}
outputs[self.nodes[0].getnewaddress()] = utxo["amount"] - self.relayfee
raw_tx2 = self.nodes[0].createrawtransaction(inputs, outputs)
tx2_hex = self.nodes[0].signrawtransaction(raw_tx2)["hex"]
tx2_id = self.nodes[0].decoderawtransaction(tx2_hex)["txid"]
try:
self.nodes[0].sendrawtransaction(tx2_hex)
except JSONRPCException as exp:
assert_equal(exp.error['code'], -26) # insufficient fee
assert(tx2_id not in self.nodes[0].getrawmempool())
else:
assert(False)
# This is a less than 1000-byte transaction, so just set the fee
# to be the minimum for a 1000 byte transaction and check that it is
# accepted.
self.nodes[0].prioritisetransaction(tx2_id, 0, int(self.relayfee*COIN))
print("Assert that prioritised free transaction is accepted to mempool")
assert_equal(self.nodes[0].sendrawtransaction(tx2_hex), tx2_id)
assert(tx2_id in self.nodes[0].getrawmempool())
if __name__ == '__main__':
PrioritiseTransactionTest().main()

View File

@@ -1,15 +1,14 @@
#!/usr/bin/env python2
# Copyright (c) 2015 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
import socket
import traceback, sys
from binascii import hexlify
import time, os
from test_framework.socks5 import Socks5Configuration, Socks5Command, Socks5Server, AddressType
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from test_framework.netutil import test_ipv6_local
'''
Test plan:
- Start bitcoind's with different proxy configurations
@@ -34,8 +33,10 @@ addnode connect to onion
addnode connect to generic DNS name
'''
class ProxyTest(BitcoinTestFramework):
class ProxyTest(BitcoinTestFramework):
def __init__(self):
self.have_ipv6 = test_ipv6_local()
# Create two proxies on different ports
# ... one unauthenticated
self.conf1 = Socks5Configuration()
@@ -47,29 +48,36 @@ class ProxyTest(BitcoinTestFramework):
self.conf2.addr = ('127.0.0.1', 14000 + (os.getpid() % 1000))
self.conf2.unauth = True
self.conf2.auth = True
# ... one on IPv6 with similar configuration
self.conf3 = Socks5Configuration()
self.conf3.af = socket.AF_INET6
self.conf3.addr = ('::1', 15000 + (os.getpid() % 1000))
self.conf3.unauth = True
self.conf3.auth = True
if self.have_ipv6:
# ... one on IPv6 with similar configuration
self.conf3 = Socks5Configuration()
self.conf3.af = socket.AF_INET6
self.conf3.addr = ('::1', 15000 + (os.getpid() % 1000))
self.conf3.unauth = True
self.conf3.auth = True
else:
print("Warning: testing without local IPv6 support")
self.serv1 = Socks5Server(self.conf1)
self.serv1.start()
self.serv2 = Socks5Server(self.conf2)
self.serv2.start()
self.serv3 = Socks5Server(self.conf3)
self.serv3.start()
if self.have_ipv6:
self.serv3 = Socks5Server(self.conf3)
self.serv3.start()
def setup_nodes(self):
# Note: proxies are not used to connect to local nodes
# this is because the proxy to use is based on CService.GetNetwork(), which return NET_UNROUTABLE for localhost
return start_nodes(4, self.options.tmpdir, extra_args=[
args = [
['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-proxyrandomize=1'],
['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf1.addr),'-onion=%s:%i' % (self.conf2.addr),'-proxyrandomize=0'],
['-listen', '-debug=net', '-debug=proxy', '-proxy=%s:%i' % (self.conf2.addr),'-proxyrandomize=1'],
['-listen', '-debug=net', '-debug=proxy', '-proxy=[%s]:%i' % (self.conf3.addr),'-proxyrandomize=0', '-noonion']
])
[]
]
if self.have_ipv6:
args[3] = ['-listen', '-debug=net', '-debug=proxy', '-proxy=[%s]:%i' % (self.conf3.addr),'-proxyrandomize=0', '-noonion']
return start_nodes(4, self.options.tmpdir, extra_args=args)
def node_test(self, node, proxies, auth, test_onion=True):
rv = []
@@ -79,25 +87,26 @@ class ProxyTest(BitcoinTestFramework):
assert(isinstance(cmd, Socks5Command))
# Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6
assert_equal(cmd.atyp, AddressType.DOMAINNAME)
assert_equal(cmd.addr, "15.61.23.23")
assert_equal(cmd.addr, b"15.61.23.23")
assert_equal(cmd.port, 1234)
if not auth:
assert_equal(cmd.username, None)
assert_equal(cmd.password, None)
rv.append(cmd)
# Test: outgoing IPv6 connection through node
node.addnode("[1233:3432:2434:2343:3234:2345:6546:4534]:5443", "onetry")
cmd = proxies[1].queue.get()
assert(isinstance(cmd, Socks5Command))
# Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6
assert_equal(cmd.atyp, AddressType.DOMAINNAME)
assert_equal(cmd.addr, "1233:3432:2434:2343:3234:2345:6546:4534")
assert_equal(cmd.port, 5443)
if not auth:
assert_equal(cmd.username, None)
assert_equal(cmd.password, None)
rv.append(cmd)
if self.have_ipv6:
# Test: outgoing IPv6 connection through node
node.addnode("[1233:3432:2434:2343:3234:2345:6546:4534]:5443", "onetry")
cmd = proxies[1].queue.get()
assert(isinstance(cmd, Socks5Command))
# Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6
assert_equal(cmd.atyp, AddressType.DOMAINNAME)
assert_equal(cmd.addr, b"1233:3432:2434:2343:3234:2345:6546:4534")
assert_equal(cmd.port, 5443)
if not auth:
assert_equal(cmd.username, None)
assert_equal(cmd.password, None)
rv.append(cmd)
if test_onion:
# Test: outgoing onion connection through node
@@ -105,7 +114,7 @@ class ProxyTest(BitcoinTestFramework):
cmd = proxies[2].queue.get()
assert(isinstance(cmd, Socks5Command))
assert_equal(cmd.atyp, AddressType.DOMAINNAME)
assert_equal(cmd.addr, "bitcoinostk4e4re.onion")
assert_equal(cmd.addr, b"bitcoinostk4e4re.onion")
assert_equal(cmd.port, 8333)
if not auth:
assert_equal(cmd.username, None)
@@ -117,7 +126,7 @@ class ProxyTest(BitcoinTestFramework):
cmd = proxies[3].queue.get()
assert(isinstance(cmd, Socks5Command))
assert_equal(cmd.atyp, AddressType.DOMAINNAME)
assert_equal(cmd.addr, "node.noumenon")
assert_equal(cmd.addr, b"node.noumenon")
assert_equal(cmd.port, 8333)
if not auth:
assert_equal(cmd.username, None)
@@ -137,10 +146,11 @@ class ProxyTest(BitcoinTestFramework):
rv = self.node_test(self.nodes[2], [self.serv2, self.serv2, self.serv2, self.serv2], True)
# Check that credentials as used for -proxyrandomize connections are unique
credentials = set((x.username,x.password) for x in rv)
assert_equal(len(credentials), 4)
assert_equal(len(credentials), len(rv))
# proxy on IPv6 localhost
self.node_test(self.nodes[3], [self.serv3, self.serv3, self.serv3, self.serv3], False, False)
if self.have_ipv6:
# proxy on IPv6 localhost
self.node_test(self.nodes[3], [self.serv3, self.serv3, self.serv3, self.serv3], False, False)
def networks_dict(d):
r = {}
@@ -169,11 +179,12 @@ class ProxyTest(BitcoinTestFramework):
assert_equal(n2[net]['proxy_randomize_credentials'], True)
assert_equal(n2['onion']['reachable'], True)
n3 = networks_dict(self.nodes[3].getnetworkinfo())
for net in ['ipv4','ipv6']:
assert_equal(n3[net]['proxy'], '[%s]:%i' % (self.conf3.addr))
assert_equal(n3[net]['proxy_randomize_credentials'], False)
assert_equal(n3['onion']['reachable'], False)
if self.have_ipv6:
n3 = networks_dict(self.nodes[3].getnetworkinfo())
for net in ['ipv4','ipv6']:
assert_equal(n3[net]['proxy'], '[%s]:%i' % (self.conf3.addr))
assert_equal(n3[net]['proxy_randomize_credentials'], False)
assert_equal(n3['onion']['reachable'], False)
if __name__ == '__main__':
ProxyTest().main()

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -13,34 +13,16 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import os.path
def calc_usage(blockdir):
return sum(os.path.getsize(blockdir+f) for f in os.listdir(blockdir) if os.path.isfile(blockdir+f))/(1024*1024)
return sum(os.path.getsize(blockdir+f) for f in os.listdir(blockdir) if os.path.isfile(blockdir+f)) / (1024. * 1024.)
class PruneTest(BitcoinTestFramework):
def __init__(self):
self.utxo = []
self.address = ["",""]
# Some pre-processing to create a bunch of OP_RETURN txouts to insert into transactions we create
# So we have big transactions and full blocks to fill up our block files
# create one script_pubkey
script_pubkey = "6a4d0200" #OP_RETURN OP_PUSH2 512 bytes
for i in xrange (512):
script_pubkey = script_pubkey + "01"
# concatenate 128 txouts of above script_pubkey which we'll insert before the txout for change
self.txouts = "81"
for k in xrange(128):
# add txout value
self.txouts = self.txouts + "0000000000000000"
# add length of script_pubkey
self.txouts = self.txouts + "fd0402"
# add script_pubkey
self.txouts = self.txouts + script_pubkey
self.txouts = gen_return_txouts()
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
@@ -74,8 +56,8 @@ class PruneTest(BitcoinTestFramework):
self.nodes[1].generate(200)
sync_blocks(self.nodes[0:2])
self.nodes[0].generate(150)
# Then mine enough full blocks to create more than 550MB of data
for i in xrange(645):
# Then mine enough full blocks to create more than 550MiB of data
for i in range(645):
self.mine_full_block(self.nodes[0], self.address[0])
sync_blocks(self.nodes[0:3])
@@ -83,11 +65,11 @@ class PruneTest(BitcoinTestFramework):
def test_height_min(self):
if not os.path.isfile(self.prunedir+"blk00000.dat"):
raise AssertionError("blk00000.dat is missing, pruning too early")
print "Success"
print "Though we're already using more than 550MB, current usage:", calc_usage(self.prunedir)
print "Mining 25 more blocks should cause the first block file to be pruned"
print("Success")
print("Though we're already using more than 550MiB, current usage:", calc_usage(self.prunedir))
print("Mining 25 more blocks should cause the first block file to be pruned")
# Pruning doesn't run until we're allocating another chunk, 20 full blocks past the height cutoff will ensure this
for i in xrange(25):
for i in range(25):
self.mine_full_block(self.nodes[0],self.address[0])
waitstart = time.time()
@@ -96,17 +78,17 @@ class PruneTest(BitcoinTestFramework):
if time.time() - waitstart > 10:
raise AssertionError("blk00000.dat not pruned when it should be")
print "Success"
print("Success")
usage = calc_usage(self.prunedir)
print "Usage should be below target:", usage
print("Usage should be below target:", usage)
if (usage > 550):
raise AssertionError("Pruning target not being met")
def create_chain_with_staleblocks(self):
# Create stale blocks in manageable sized chunks
print "Mine 24 (stale) blocks on Node 1, followed by 25 (main chain) block reorg from Node 0, for 12 rounds"
print("Mine 24 (stale) blocks on Node 1, followed by 25 (main chain) block reorg from Node 0, for 12 rounds")
for j in xrange(12):
for j in range(12):
# Disconnect node 0 so it can mine a longer reorg chain without knowing about node 1's soon-to-be-stale chain
# Node 2 stays connected, so it hears about the stale blocks and then reorg's when node0 reconnects
# Stopping node 0 also clears its mempool, so it doesn't have node1's transactions to accidentally mine
@@ -114,7 +96,7 @@ class PruneTest(BitcoinTestFramework):
self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=999000", "-checkblocks=5"], timewait=900)
# Mine 24 blocks in node 1
self.utxo = self.nodes[1].listunspent()
for i in xrange(24):
for i in range(24):
if j == 0:
self.mine_full_block(self.nodes[1],self.address[1])
else:
@@ -122,7 +104,7 @@ class PruneTest(BitcoinTestFramework):
# Reorg back with 25 block chain from node 0
self.utxo = self.nodes[0].listunspent()
for i in xrange(25):
for i in range(25):
self.mine_full_block(self.nodes[0],self.address[0])
# Create connections in the order so both nodes can see the reorg at the same time
@@ -130,7 +112,7 @@ class PruneTest(BitcoinTestFramework):
connect_nodes(self.nodes[2], 0)
sync_blocks(self.nodes[0:3])
print "Usage can be over target because of high stale rate:", calc_usage(self.prunedir)
print("Usage can be over target because of high stale rate:", calc_usage(self.prunedir))
def reorg_test(self):
# Node 1 will mine a 300 block chain starting 287 blocks back from Node 0 and Node 2's tip
@@ -141,11 +123,11 @@ class PruneTest(BitcoinTestFramework):
self.nodes[1]=start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=5000", "-checkblocks=5", "-disablesafemode"], timewait=900)
height = self.nodes[1].getblockcount()
print "Current block height:", height
print("Current block height:", height)
invalidheight = height-287
badhash = self.nodes[1].getblockhash(invalidheight)
print "Invalidating block at height:",invalidheight,badhash
print("Invalidating block at height:",invalidheight,badhash)
self.nodes[1].invalidateblock(badhash)
# We've now switched to our previously mined-24 block fork on node 1, but thats not what we want
@@ -157,29 +139,29 @@ class PruneTest(BitcoinTestFramework):
curhash = self.nodes[1].getblockhash(invalidheight - 1)
assert(self.nodes[1].getblockcount() == invalidheight - 1)
print "New best height", self.nodes[1].getblockcount()
print("New best height", self.nodes[1].getblockcount())
# Reboot node1 to clear those giant tx's from mempool
stop_node(self.nodes[1],1)
self.nodes[1]=start_node(1, self.options.tmpdir, ["-debug","-maxreceivebuffer=20000","-blockmaxsize=5000", "-checkblocks=5", "-disablesafemode"], timewait=900)
print "Generating new longer chain of 300 more blocks"
print("Generating new longer chain of 300 more blocks")
self.nodes[1].generate(300)
print "Reconnect nodes"
print("Reconnect nodes")
connect_nodes(self.nodes[0], 1)
connect_nodes(self.nodes[2], 1)
sync_blocks(self.nodes[0:3])
print "Verify height on node 2:",self.nodes[2].getblockcount()
print "Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir)
print("Verify height on node 2:",self.nodes[2].getblockcount())
print("Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir))
print "Mine 220 more blocks so we have requisite history (some blocks will be big and cause pruning of previous chain)"
print("Mine 220 more blocks so we have requisite history (some blocks will be big and cause pruning of previous chain)")
self.nodes[0].generate(220) #node 0 has many large tx's in its mempool from the disconnects
sync_blocks(self.nodes[0:3])
usage = calc_usage(self.prunedir)
print "Usage should be below target:", usage
print("Usage should be below target:", usage)
if (usage > 550):
raise AssertionError("Pruning target not being met")
@@ -191,7 +173,7 @@ class PruneTest(BitcoinTestFramework):
self.nodes[2].getblock(self.forkhash)
raise AssertionError("Old block wasn't pruned so can't test redownload")
except JSONRPCException as e:
print "Will need to redownload block",self.forkheight
print("Will need to redownload block",self.forkheight)
# Verify that we have enough history to reorg back to the fork point
# Although this is more than 288 blocks, because this chain was written more recently
@@ -215,14 +197,14 @@ class PruneTest(BitcoinTestFramework):
# At this point node 2 is within 288 blocks of the fork point so it will preserve its ability to reorg
if self.nodes[2].getblockcount() < self.mainchainheight:
blocks_to_mine = first_reorg_height + 1 - self.mainchainheight
print "Rewind node 0 to prev main chain to mine longer chain to trigger redownload. Blocks needed:", blocks_to_mine
print("Rewind node 0 to prev main chain to mine longer chain to trigger redownload. Blocks needed:", blocks_to_mine)
self.nodes[0].invalidateblock(curchainhash)
assert(self.nodes[0].getblockcount() == self.mainchainheight)
assert(self.nodes[0].getbestblockhash() == self.mainchainhash2)
goalbesthash = self.nodes[0].generate(blocks_to_mine)[-1]
goalbestheight = first_reorg_height + 1
print "Verify node 2 reorged back to the main chain, some blocks of which it had to redownload"
print("Verify node 2 reorged back to the main chain, some blocks of which it had to redownload")
waitstart = time.time()
while self.nodes[2].getblockcount() < goalbestheight:
time.sleep(0.1)
@@ -235,7 +217,7 @@ class PruneTest(BitcoinTestFramework):
def mine_full_block(self, node, address):
# Want to create a full block
# We'll generate a 66k transaction below, and 14 of them is close to the 1MB block limit
for j in xrange(14):
for j in range(14):
if len(self.utxo) < 14:
self.utxo = node.listunspent()
inputs=[]
@@ -259,8 +241,8 @@ class PruneTest(BitcoinTestFramework):
def run_test(self):
print "Warning! This test requires 4GB of disk space and takes over 30 mins (up to 2 hours)"
print "Mining a big blockchain of 995 blocks"
print("Warning! This test requires 4GB of disk space and takes over 30 mins (up to 2 hours)")
print("Mining a big blockchain of 995 blocks")
self.create_big_chain()
# Chain diagram key:
# * blocks on main chain
@@ -271,12 +253,12 @@ class PruneTest(BitcoinTestFramework):
# Start by mining a simple chain that all nodes have
# N0=N1=N2 **...*(995)
print "Check that we haven't started pruning yet because we're below PruneAfterHeight"
print("Check that we haven't started pruning yet because we're below PruneAfterHeight")
self.test_height_min()
# Extend this chain past the PruneAfterHeight
# N0=N1=N2 **...*(1020)
print "Check that we'll exceed disk space target if we have a very high stale block rate"
print("Check that we'll exceed disk space target if we have a very high stale block rate")
self.create_chain_with_staleblocks()
# Disconnect N0
# And mine a 24 block chain on N1 and a separate 25 block chain on N0
@@ -300,7 +282,7 @@ class PruneTest(BitcoinTestFramework):
self.mainchainheight = self.nodes[2].getblockcount() #1320
self.mainchainhash2 = self.nodes[2].getblockhash(self.mainchainheight)
print "Check that we can survive a 288 block reorg still"
print("Check that we can survive a 288 block reorg still")
(self.forkheight,self.forkhash) = self.reorg_test() #(1033, )
# Now create a 288 block reorg by mining a longer chain on N1
# First disconnect N1
@@ -329,11 +311,11 @@ class PruneTest(BitcoinTestFramework):
# \ \
# ++...++(1044) ..
#
# N0 ********************(1032) @@...@@@(1552)
# N0 ********************(1032) @@...@@@(1552)
# \
# *...**(1320)
print "Test that we can rerequest a block we previously pruned if needed for a reorg"
print("Test that we can rerequest a block we previously pruned if needed for a reorg")
self.reorg_back()
# Verify that N2 still has block 1033 on current chain (@), but not on main chain (*)
# Invalidate 1033 on current chain (@) on N2 and we should be able to reorg to
@@ -353,7 +335,7 @@ class PruneTest(BitcoinTestFramework):
#
# N1 doesn't change because 1033 on main chain (*) is invalid
print "Done"
print("Done")
if __name__ == '__main__':
PruneTest().main()

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -10,8 +10,6 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from pprint import pprint
from time import sleep
# Create one-input, one-output, no-fee transaction:
class RawTransactionsTest(BitcoinTestFramework):
@@ -43,9 +41,9 @@ class RawTransactionsTest(BitcoinTestFramework):
self.sync_all()
self.nodes[0].generate(101)
self.sync_all()
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5);
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0);
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0);
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0)
self.sync_all()
self.nodes[0].generate(5)
self.sync_all()
@@ -58,13 +56,13 @@ class RawTransactionsTest(BitcoinTestFramework):
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
rawtx = self.nodes[2].signrawtransaction(rawtx)
errorString = ""
try:
rawtx = self.nodes[2].sendrawtransaction(rawtx['hex'])
except JSONRPCException,e:
errorString = e.error['message']
except JSONRPCException as e:
assert("Missing inputs" in e.error['message'])
else:
assert(False)
assert_equal("Missing inputs" in errorString, True);
#########################
# RAW TX MULTISIG TESTS #
@@ -83,15 +81,13 @@ class RawTransactionsTest(BitcoinTestFramework):
bal = self.nodes[2].getbalance()
# send 1.2 BTC to msig adr
txId = self.nodes[0].sendtoaddress(mSigObj, 1.2);
txId = self.nodes[0].sendtoaddress(mSigObj, 1.2)
self.sync_all()
self.nodes[0].generate(1)
self.sync_all()
assert_equal(self.nodes[2].getbalance(), bal+Decimal('1.20000000')) #node2 has both keys of the 2of2 ms addr., tx should affect the balance
# 2of3 test from different nodes
bal = self.nodes[2].getbalance()
addr1 = self.nodes[1].getnewaddress()
@@ -105,7 +101,7 @@ class RawTransactionsTest(BitcoinTestFramework):
mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']])
mSigObjValid = self.nodes[2].validateaddress(mSigObj)
txId = self.nodes[0].sendtoaddress(mSigObj, 2.2);
txId = self.nodes[0].sendtoaddress(mSigObj, 2.2)
decTx = self.nodes[0].gettransaction(txId)
rawTx = self.nodes[0].decoderawtransaction(decTx['hex'])
sPK = rawTx['vout'][0]['scriptPubKey']['hex']
@@ -123,7 +119,7 @@ class RawTransactionsTest(BitcoinTestFramework):
for outpoint in rawTx['vout']:
if outpoint['value'] == Decimal('2.20000000'):
vout = outpoint
break;
break
bal = self.nodes[0].getbalance()
inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex']}]

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -25,34 +25,13 @@ def get_sub_array_from_array(object_array, to_match):
return item
return []
def check_array_result(object_array, to_match, expected, should_not_find = False):
"""
Pass in array of JSON objects, a dictionary with key/value pairs
to match against, and another dictionary with expected key/value
pairs.
If the should_not_find flag is true, to_match should not be found in object_array
"""
if should_not_find == True:
expected = { }
num_matched = 0
for item in object_array:
all_match = True
for key,value in to_match.items():
if item[key] != value:
all_match = False
if not all_match:
continue
for key,value in expected.items():
if item[key] != value:
raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value)))
num_matched = num_matched+1
if num_matched == 0 and should_not_find != True:
raise AssertionError("No objects matched %s"%(str(to_match)))
if num_matched > 0 and should_not_find == True:
raise AssertionError("Objects was matched %s"%(str(to_match)))
class ReceivedByTest(BitcoinTestFramework):
def setup_nodes(self):
#This test requires mocktime
enable_mocktime()
return start_nodes(4, self.options.tmpdir)
def run_test(self):
'''
listreceivedbyaddress Test
@@ -63,26 +42,26 @@ class ReceivedByTest(BitcoinTestFramework):
self.sync_all()
#Check not listed in listreceivedbyaddress because has 0 confirmations
check_array_result(self.nodes[1].listreceivedbyaddress(),
assert_array_result(self.nodes[1].listreceivedbyaddress(),
{"address":addr},
{ },
True)
#Bury Tx under 10 block so it will be returned by listreceivedbyaddress
self.nodes[1].generate(10)
self.sync_all()
check_array_result(self.nodes[1].listreceivedbyaddress(),
assert_array_result(self.nodes[1].listreceivedbyaddress(),
{"address":addr},
{"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]})
#With min confidence < 10
check_array_result(self.nodes[1].listreceivedbyaddress(5),
assert_array_result(self.nodes[1].listreceivedbyaddress(5),
{"address":addr},
{"address":addr, "account":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]})
#With min confidence > 10, should not find Tx
check_array_result(self.nodes[1].listreceivedbyaddress(11),{"address":addr},{ },True)
assert_array_result(self.nodes[1].listreceivedbyaddress(11),{"address":addr},{ },True)
#Empty Tx
addr = self.nodes[1].getnewaddress()
check_array_result(self.nodes[1].listreceivedbyaddress(0,True),
assert_array_result(self.nodes[1].listreceivedbyaddress(0,True),
{"address":addr},
{"address":addr, "account":"", "amount":0, "confirmations":0, "txids":[]})
@@ -126,7 +105,7 @@ class ReceivedByTest(BitcoinTestFramework):
self.sync_all()
# listreceivedbyaccount should return received_by_account_json because of 0 confirmations
check_array_result(self.nodes[1].listreceivedbyaccount(),
assert_array_result(self.nodes[1].listreceivedbyaccount(),
{"account":account},
received_by_account_json)
@@ -138,7 +117,7 @@ class ReceivedByTest(BitcoinTestFramework):
self.nodes[1].generate(10)
self.sync_all()
# listreceivedbyaccount should return updated account balance
check_array_result(self.nodes[1].listreceivedbyaccount(),
assert_array_result(self.nodes[1].listreceivedbyaccount(),
{"account":account},
{"account":received_by_account_json["account"], "amount":(received_by_account_json["amount"] + Decimal("0.1"))})

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -8,7 +8,6 @@
#
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import os.path
class ReindexTest(BitcoinTestFramework):
@@ -27,7 +26,7 @@ class ReindexTest(BitcoinTestFramework):
wait_bitcoinds()
self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex", "-checkblockindex=1"])
assert_equal(self.nodes[0].getblockcount(), 3)
print "Success"
print("Success")
if __name__ == '__main__':
ReindexTest().main()

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014-2015 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -11,16 +11,11 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from test_framework.script import *
from test_framework.mininode import *
import binascii
COIN = 100000000
MAX_REPLACEMENT_LIMIT = 100
def satoshi_round(amount):
return Decimal(amount).quantize(Decimal('0.00000001'), rounding=ROUND_DOWN)
def txToHex(tx):
return binascii.hexlify(tx.serialize()).decode('utf-8')
return bytes_to_hex_str(tx.serialize())
def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])):
"""Create a txout with a given amount and scriptPubKey
@@ -54,17 +49,20 @@ def make_utxo(node, amount, confirmed=True, scriptPubKey=CScript([1])):
tx2.vout = [CTxOut(amount, scriptPubKey)]
tx2.rehash()
tx2_hex = binascii.hexlify(tx2.serialize()).decode('utf-8')
#print tx2_hex
signed_tx = node.signrawtransaction(binascii.hexlify(tx2.serialize()).decode('utf-8'))
signed_tx = node.signrawtransaction(txToHex(tx2))
txid = node.sendrawtransaction(signed_tx['hex'], True)
# If requested, ensure txouts are confirmed.
if confirmed:
while len(node.getrawmempool()):
mempool_size = len(node.getrawmempool())
while mempool_size > 0:
node.generate(1)
new_size = len(node.getrawmempool())
# Error out if we have something stuck in the mempool, as this
# would likely be a bug.
assert(new_size < mempool_size)
mempool_size = new_size
return COutPoint(int(txid, 16), 0)
@@ -72,7 +70,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def setup_network(self):
self.nodes = []
self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000",
self.nodes.append(start_node(0, self.options.tmpdir, ["-maxorphantx=1000", "-debug",
"-relaypriority=0", "-whitelist=127.0.0.1",
"-limitancestorcount=50",
"-limitancestorsize=101",
@@ -84,35 +82,38 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def run_test(self):
make_utxo(self.nodes[0], 1*COIN)
print "Running test simple doublespend..."
print("Running test simple doublespend...")
self.test_simple_doublespend()
print "Running test doublespend chain..."
print("Running test doublespend chain...")
self.test_doublespend_chain()
print "Running test doublespend tree..."
print("Running test doublespend tree...")
self.test_doublespend_tree()
print "Running test replacement feeperkb..."
print("Running test replacement feeperkb...")
self.test_replacement_feeperkb()
print "Running test spends of conflicting outputs..."
print("Running test spends of conflicting outputs...")
self.test_spends_of_conflicting_outputs()
print "Running test new unconfirmed inputs..."
print("Running test new unconfirmed inputs...")
self.test_new_unconfirmed_inputs()
print "Running test too many replacements..."
print("Running test too many replacements...")
self.test_too_many_replacements()
print "Running test opt-in..."
print("Running test opt-in...")
self.test_opt_in()
print "Passed\n"
print("Running test prioritised transactions...")
self.test_prioritised_transactions()
print("Passed\n")
def test_simple_doublespend(self):
"""Simple doublespend"""
tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
tx1a = CTransaction()
tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)]
@@ -136,7 +137,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Extra 0.1 BTC fee
tx1b = CTransaction()
tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
tx1b.vout = [CTxOut(0.9*COIN, CScript([b'b']))]
tx1b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))]
tx1b_hex = txToHex(tx1b)
tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
@@ -228,7 +229,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
_total_txs=_total_txs):
yield x
fee = 0.0001*COIN
fee = int(0.0001*COIN)
n = MAX_REPLACEMENT_LIMIT
tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee))
assert_equal(len(tree_txs), n)
@@ -261,7 +262,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Try again, but with more total transactions than the "max txs
# double-spent at once" anti-DoS limit.
for n in (MAX_REPLACEMENT_LIMIT+1, MAX_REPLACEMENT_LIMIT*2):
fee = 0.0001*COIN
fee = int(0.0001*COIN)
tx0_outpoint = make_utxo(self.nodes[0], initial_nValue)
tree_txs = list(branch(tx0_outpoint, initial_nValue, n, fee=fee))
assert_equal(len(tree_txs), n)
@@ -284,7 +285,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def test_replacement_feeperkb(self):
"""Replacement requires fee-per-KB to be higher"""
tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
tx1a = CTransaction()
tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)]
@@ -296,7 +297,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# rejected.
tx1b = CTransaction()
tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
tx1b.vout = [CTxOut(0.001*COIN, CScript([b'a'*999000]))]
tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*999000]))]
tx1b_hex = txToHex(tx1b)
try:
@@ -308,12 +309,12 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def test_spends_of_conflicting_outputs(self):
"""Replacements that spend conflicting tx outputs are rejected"""
utxo1 = make_utxo(self.nodes[0], 1.2*COIN)
utxo2 = make_utxo(self.nodes[0], 3.0*COIN)
utxo1 = make_utxo(self.nodes[0], int(1.2*COIN))
utxo2 = make_utxo(self.nodes[0], 3*COIN)
tx1a = CTransaction()
tx1a.vin = [CTxIn(utxo1, nSequence=0)]
tx1a.vout = [CTxOut(1.1*COIN, CScript([b'a']))]
tx1a.vout = [CTxOut(int(1.1*COIN), CScript([b'a']))]
tx1a_hex = txToHex(tx1a)
tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True)
@@ -336,7 +337,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Spend tx1a's output to test the indirect case.
tx1b = CTransaction()
tx1b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)]
tx1b.vout = [CTxOut(1.0*COIN, CScript([b'a']))]
tx1b.vout = [CTxOut(1*COIN, CScript([b'a']))]
tx1b_hex = txToHex(tx1b)
tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
tx1b_txid = int(tx1b_txid, 16)
@@ -356,12 +357,12 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def test_new_unconfirmed_inputs(self):
"""Replacements that add new unconfirmed inputs are rejected"""
confirmed_utxo = make_utxo(self.nodes[0], 1.1*COIN)
unconfirmed_utxo = make_utxo(self.nodes[0], 0.1*COIN, False)
confirmed_utxo = make_utxo(self.nodes[0], int(1.1*COIN))
unconfirmed_utxo = make_utxo(self.nodes[0], int(0.1*COIN), False)
tx1 = CTransaction()
tx1.vin = [CTxIn(confirmed_utxo)]
tx1.vout = [CTxOut(1.0*COIN, CScript([b'a']))]
tx1.vout = [CTxOut(1*COIN, CScript([b'a']))]
tx1_hex = txToHex(tx1)
tx1_txid = self.nodes[0].sendrawtransaction(tx1_hex, True)
@@ -385,7 +386,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Start by creating a single transaction with many outputs
initial_nValue = 10*COIN
utxo = make_utxo(self.nodes[0], initial_nValue)
fee = 0.0001*COIN
fee = int(0.0001*COIN)
split_value = int((initial_nValue-fee)/(MAX_REPLACEMENT_LIMIT+1))
actual_fee = initial_nValue - split_value*(MAX_REPLACEMENT_LIMIT+1)
@@ -438,7 +439,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
def test_opt_in(self):
""" Replacing should only work if orig tx opted in """
tx0_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
# Create a non-opting in transaction
tx1a = CTransaction()
@@ -450,7 +451,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Shouldn't be able to double-spend
tx1b = CTransaction()
tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
tx1b.vout = [CTxOut(0.9*COIN, CScript([b'b']))]
tx1b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))]
tx1b_hex = txToHex(tx1b)
try:
@@ -458,10 +459,10 @@ class ReplaceByFeeTest(BitcoinTestFramework):
except JSONRPCException as exp:
assert_equal(exp.error['code'], -26)
else:
print tx1b_txid
print(tx1b_txid)
assert(False)
tx1_outpoint = make_utxo(self.nodes[0], 1.1*COIN)
tx1_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
# Create a different non-opting in transaction
tx2a = CTransaction()
@@ -473,7 +474,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# Still shouldn't be able to double-spend
tx2b = CTransaction()
tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)]
tx2b.vout = [CTxOut(0.9*COIN, CScript([b'b']))]
tx2b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))]
tx2b_hex = txToHex(tx2b)
try:
@@ -493,19 +494,19 @@ class ReplaceByFeeTest(BitcoinTestFramework):
tx3a = CTransaction()
tx3a.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0xffffffff),
CTxIn(COutPoint(tx2a_txid, 0), nSequence=0xfffffffd)]
tx3a.vout = [CTxOut(0.9*COIN, CScript([b'c'])), CTxOut(0.9*COIN, CScript([b'd']))]
tx3a.vout = [CTxOut(int(0.9*COIN), CScript([b'c'])), CTxOut(int(0.9*COIN), CScript([b'd']))]
tx3a_hex = txToHex(tx3a)
self.nodes[0].sendrawtransaction(tx3a_hex, True)
tx3b = CTransaction()
tx3b.vin = [CTxIn(COutPoint(tx1a_txid, 0), nSequence=0)]
tx3b.vout = [CTxOut(0.5*COIN, CScript([b'e']))]
tx3b.vout = [CTxOut(int(0.5*COIN), CScript([b'e']))]
tx3b_hex = txToHex(tx3b)
tx3c = CTransaction()
tx3c.vin = [CTxIn(COutPoint(tx2a_txid, 0), nSequence=0)]
tx3c.vout = [CTxOut(0.5*COIN, CScript([b'f']))]
tx3c.vout = [CTxOut(int(0.5*COIN), CScript([b'f']))]
tx3c_hex = txToHex(tx3c)
self.nodes[0].sendrawtransaction(tx3b_hex, True)
@@ -513,5 +514,72 @@ class ReplaceByFeeTest(BitcoinTestFramework):
# but make sure it is accepted anyway
self.nodes[0].sendrawtransaction(tx3c_hex, True)
def test_prioritised_transactions(self):
# Ensure that fee deltas used via prioritisetransaction are
# correctly used by replacement logic
# 1. Check that feeperkb uses modified fees
tx0_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
tx1a = CTransaction()
tx1a.vin = [CTxIn(tx0_outpoint, nSequence=0)]
tx1a.vout = [CTxOut(1*COIN, CScript([b'a']))]
tx1a_hex = txToHex(tx1a)
tx1a_txid = self.nodes[0].sendrawtransaction(tx1a_hex, True)
# Higher fee, but the actual fee per KB is much lower.
tx1b = CTransaction()
tx1b.vin = [CTxIn(tx0_outpoint, nSequence=0)]
tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*740000]))]
tx1b_hex = txToHex(tx1b)
# Verify tx1b cannot replace tx1a.
try:
tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
except JSONRPCException as exp:
assert_equal(exp.error['code'], -26)
else:
assert(False)
# Use prioritisetransaction to set tx1a's fee to 0.
self.nodes[0].prioritisetransaction(tx1a_txid, 0, int(-0.1*COIN))
# Now tx1b should be able to replace tx1a
tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
assert(tx1b_txid in self.nodes[0].getrawmempool())
# 2. Check that absolute fee checks use modified fee.
tx1_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
tx2a = CTransaction()
tx2a.vin = [CTxIn(tx1_outpoint, nSequence=0)]
tx2a.vout = [CTxOut(1*COIN, CScript([b'a']))]
tx2a_hex = txToHex(tx2a)
tx2a_txid = self.nodes[0].sendrawtransaction(tx2a_hex, True)
# Lower fee, but we'll prioritise it
tx2b = CTransaction()
tx2b.vin = [CTxIn(tx1_outpoint, nSequence=0)]
tx2b.vout = [CTxOut(int(1.01*COIN), CScript([b'a']))]
tx2b.rehash()
tx2b_hex = txToHex(tx2b)
# Verify tx2b cannot replace tx2a.
try:
tx2b_txid = self.nodes[0].sendrawtransaction(tx2b_hex, True)
except JSONRPCException as exp:
assert_equal(exp.error['code'], -26)
else:
assert(False)
# Now prioritise tx2b to have a higher modified fee
self.nodes[0].prioritisetransaction(tx2b.hash, 0, int(0.1*COIN))
# tx2b should now be accepted
tx2b_txid = self.nodes[0].sendrawtransaction(tx2b_hex, True)
assert(tx2b_txid in self.nodes[0].getrawmempool())
if __name__ == '__main__':
ReplaceByFeeTest().main()

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -11,19 +11,11 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
from struct import *
import binascii
import json
import StringIO
import decimal
from io import BytesIO
from codecs import encode
try:
import http.client as httplib
except ImportError:
import httplib
try:
import urllib.parse as urlparse
except ImportError:
import urlparse
import http.client
import urllib.parse
def deser_uint256(f):
r = 0
@@ -34,17 +26,17 @@ def deser_uint256(f):
#allows simple http get calls
def http_get_call(host, port, path, response_object = 0):
conn = httplib.HTTPConnection(host, port)
conn = http.client.HTTPConnection(host, port)
conn.request('GET', path)
if response_object:
return conn.getresponse()
return conn.getresponse().read()
return conn.getresponse().read().decode('utf-8')
#allows simple http post calls with a request body
def http_post_call(host, port, path, requestdata = '', response_object = 0):
conn = httplib.HTTPConnection(host, port)
conn = http.client.HTTPConnection(host, port)
conn.request('POST', path, requestdata)
if response_object:
@@ -68,8 +60,8 @@ class RESTTest (BitcoinTestFramework):
self.sync_all()
def run_test(self):
url = urlparse.urlparse(self.nodes[0].url)
print "Mining blocks..."
url = urllib.parse.urlparse(self.nodes[0].url)
print("Mining blocks...")
self.nodes[0].generate(1)
self.sync_all()
@@ -142,17 +134,17 @@ class RESTTest (BitcoinTestFramework):
bb_hash = self.nodes[0].getbestblockhash()
binaryRequest = b'\x01\x02'
binaryRequest += binascii.unhexlify(txid)
binaryRequest += pack("i", n);
binaryRequest += binascii.unhexlify(vintx);
binaryRequest += pack("i", 0);
binaryRequest += hex_str_to_bytes(txid)
binaryRequest += pack("i", n)
binaryRequest += hex_str_to_bytes(vintx)
binaryRequest += pack("i", 0)
bin_response = http_post_call(url.hostname, url.port, '/rest/getutxos'+self.FORMAT_SEPARATOR+'bin', binaryRequest)
output = StringIO.StringIO()
output = BytesIO()
output.write(bin_response)
output.seek(0)
chainHeight = unpack("i", output.read(4))[0]
hashFromBinResponse = hex(deser_uint256(output))[2:].zfill(65).rstrip("L")
hashFromBinResponse = hex(deser_uint256(output))[2:].zfill(64)
assert_equal(bb_hash, hashFromBinResponse) #check if getutxo's chaintip during calculation was fine
assert_equal(chainHeight, 102) #chain height must be 102
@@ -206,7 +198,7 @@ class RESTTest (BitcoinTestFramework):
json_request = '/checkmempool/'
for x in range(0, 15):
json_request += txid+'-'+str(n)+'/'
json_request = json_request.rstrip("/");
json_request = json_request.rstrip("/")
response = http_post_call(url.hostname, url.port, '/rest/getutxos'+json_request+self.FORMAT_SEPARATOR+'json', '', True)
assert_equal(response.status, 200) #must be a 500 because we exceeding the limits
@@ -235,7 +227,7 @@ class RESTTest (BitcoinTestFramework):
assert_equal(response_hex.status, 200)
assert_greater_than(int(response_hex.getheader('content-length')), 160)
response_hex_str = response_hex.read()
assert_equal(response_str.encode("hex")[0:160], response_hex_str[0:160])
assert_equal(encode(response_str, "hex_codec")[0:160], response_hex_str[0:160])
# compare with hex block header
response_header_hex = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"hex", True)
@@ -243,7 +235,7 @@ class RESTTest (BitcoinTestFramework):
assert_greater_than(int(response_header_hex.getheader('content-length')), 160)
response_header_hex_str = response_header_hex.read()
assert_equal(response_hex_str[0:160], response_header_hex_str[0:160])
assert_equal(response_header_str.encode("hex")[0:160], response_header_hex_str[0:160])
assert_equal(encode(response_header_str, "hex_codec")[0:160], response_header_hex_str[0:160])
# check json format
block_json_string = http_get_call(url.hostname, url.port, '/rest/block/'+bb_hash+self.FORMAT_SEPARATOR+'json')
@@ -253,8 +245,8 @@ class RESTTest (BitcoinTestFramework):
# compare with json block header
response_header_json = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"json", True)
assert_equal(response_header_json.status, 200)
response_header_json_str = response_header_json.read()
json_obj = json.loads(response_header_json_str, parse_float=decimal.Decimal)
response_header_json_str = response_header_json.read().decode('utf-8')
json_obj = json.loads(response_header_json_str, parse_float=Decimal)
assert_equal(len(json_obj), 1) #ensure that there is one header in the json response
assert_equal(json_obj[0]['hash'], bb_hash) #request/response hash should be the same
@@ -277,12 +269,12 @@ class RESTTest (BitcoinTestFramework):
self.sync_all()
response_header_json = http_get_call(url.hostname, url.port, '/rest/headers/5/'+bb_hash+self.FORMAT_SEPARATOR+"json", True)
assert_equal(response_header_json.status, 200)
response_header_json_str = response_header_json.read()
response_header_json_str = response_header_json.read().decode('utf-8')
json_obj = json.loads(response_header_json_str)
assert_equal(len(json_obj), 5) #now we should have 5 header objects
# do tx test
tx_hash = block_json_obj['tx'][0]['txid'];
tx_hash = block_json_obj['tx'][0]['txid']
json_string = http_get_call(url.hostname, url.port, '/rest/tx/'+tx_hash+self.FORMAT_SEPARATOR+"json")
json_obj = json.loads(json_string)
assert_equal(json_obj['txid'], tx_hash)
@@ -293,7 +285,6 @@ class RESTTest (BitcoinTestFramework):
assert_greater_than(int(response.getheader('content-length')), 10)
# check block tx details
# let's make 3 tx and mine them on node 1
txs = []

View File

@@ -1,17 +1,12 @@
#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
# Test for -rpcbind, as well as -rpcallowip and -rpcconnect
# Add python-bitcoinrpc to module search path:
import os
import sys
# TODO extend this test from the test framework (like all other tests)
import json
import shutil
import subprocess
import tempfile
import traceback
@@ -56,7 +51,7 @@ def run_allowip_test(tmpdir, allow_ips, rpchost, rpcport):
def run_test(tmpdir):
assert(sys.platform == 'linux2') # due to OS-specific network stats queries, this test works only on Linux
assert(sys.platform.startswith('linux')) # due to OS-specific network stats queries, this test works only on Linux
# find the first non-loopback interface for testing
non_loopback_ip = None
for name,ip in all_interfaces():

View File

@@ -1,13 +1,11 @@
#!/usr/bin/env python2
#
# Distributed under the MIT/X11 software license, see the accompanying
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
from test_framework.mininode import *
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
import time
from test_framework.blocktools import create_block, create_coinbase
'''
@@ -70,7 +68,6 @@ f. Announce 1 more header that builds on that fork.
class BaseNode(NodeConnCB):
def __init__(self):
NodeConnCB.__init__(self)
self.create_callback_map()
self.connection = None
self.last_inv = None
self.last_headers = None
@@ -221,18 +218,20 @@ class SendHeadersTest(BitcoinTestFramework):
# mine count blocks and return the new tip
def mine_blocks(self, count):
# Clear out last block announcement from each p2p listener
[ x.clear_last_announcement() for x in self.p2p_connections ]
self.nodes[0].generate(count)
return int(self.nodes[0].getbestblockhash(), 16)
# mine a reorg that invalidates length blocks (replacing them with
# length+1 blocks).
# peers is the p2p nodes we're using; we clear their state after the
# Note: we clear the state of our p2p connections after the
# to-be-reorged-out blocks are mined, so that we don't break later tests.
# return the list of block hashes newly mined
def mine_reorg(self, length, peers):
def mine_reorg(self, length):
self.nodes[0].generate(length) # make sure all invalidated blocks are node0's
sync_blocks(self.nodes, wait=0.1)
[x.clear_last_announcement() for x in peers]
[x.clear_last_announcement() for x in self.p2p_connections]
tip_height = self.nodes[1].getblockcount()
hash_to_invalidate = self.nodes[1].getblockhash(tip_height-(length-1))
@@ -246,6 +245,8 @@ class SendHeadersTest(BitcoinTestFramework):
inv_node = InvNode()
test_node = TestNode()
self.p2p_connections = [inv_node, test_node]
connections = []
connections.append(NodeConn('127.0.0.1', p2p_port(0), self.nodes[0], inv_node))
# Set nServices to 0 for test_node, so no block download will occur outside of
@@ -264,8 +265,8 @@ class SendHeadersTest(BitcoinTestFramework):
# PART 1
# 1. Mine a block; expect inv announcements each time
print "Part 1: headers don't start before sendheaders message..."
for i in xrange(4):
print("Part 1: headers don't start before sendheaders message...")
for i in range(4):
old_tip = tip
tip = self.mine_blocks(1)
assert_equal(inv_node.check_last_announcement(inv=[tip]), True)
@@ -295,16 +296,15 @@ class SendHeadersTest(BitcoinTestFramework):
inv_node.clear_last_announcement()
test_node.clear_last_announcement()
print "Part 1: success!"
print "Part 2: announce blocks with headers after sendheaders message..."
print("Part 1: success!")
print("Part 2: announce blocks with headers after sendheaders message...")
# PART 2
# 2. Send a sendheaders message and test that headers announcements
# commence and keep working.
test_node.send_message(msg_sendheaders())
prev_tip = int(self.nodes[0].getbestblockhash(), 16)
test_node.get_headers(locator=[prev_tip], hashstop=0L)
test_node.get_headers(locator=[prev_tip], hashstop=0)
test_node.sync_with_ping()
test_node.clear_last_announcement() # Clear out empty headers response
# Now that we've synced headers, headers announcements should work
tip = self.mine_blocks(1)
@@ -313,14 +313,14 @@ class SendHeadersTest(BitcoinTestFramework):
height = self.nodes[0].getblockcount()+1
block_time += 10 # Advance far enough ahead
for i in xrange(10):
for i in range(10):
# Mine i blocks, and alternate announcing either via
# inv (of tip) or via headers. After each, new blocks
# mined by the node should successfully be announced
# with block header, even though the blocks are never requested
for j in xrange(2):
for j in range(2):
blocks = []
for b in xrange(i+1):
for b in range(i+1):
blocks.append(create_block(tip, create_coinbase(height), block_time))
blocks[-1].solve()
tip = blocks[-1].sha256
@@ -353,23 +353,21 @@ class SendHeadersTest(BitcoinTestFramework):
# broadcast it)
assert_equal(inv_node.last_inv, None)
assert_equal(inv_node.last_headers, None)
inv_node.clear_last_announcement()
test_node.clear_last_announcement()
tip = self.mine_blocks(1)
assert_equal(inv_node.check_last_announcement(inv=[tip]), True)
assert_equal(test_node.check_last_announcement(headers=[tip]), True)
height += 1
block_time += 1
print "Part 2: success!"
print("Part 2: success!")
print "Part 3: headers announcements can stop after large reorg, and resume after headers/inv from peer..."
print("Part 3: headers announcements can stop after large reorg, and resume after headers/inv from peer...")
# PART 3. Headers announcements can stop after large reorg, and resume after
# getheaders or inv from peer.
for j in xrange(2):
for j in range(2):
# First try mining a reorg that can propagate with header announcement
new_block_hashes = self.mine_reorg(length=7, peers=[test_node, inv_node])
new_block_hashes = self.mine_reorg(length=7)
tip = new_block_hashes[-1]
assert_equal(inv_node.check_last_announcement(inv=[tip]), True)
assert_equal(test_node.check_last_announcement(headers=new_block_hashes), True)
@@ -377,7 +375,7 @@ class SendHeadersTest(BitcoinTestFramework):
block_time += 8
# Mine a too-large reorg, which should be announced with a single inv
new_block_hashes = self.mine_reorg(length=8, peers=[test_node, inv_node])
new_block_hashes = self.mine_reorg(length=8)
tip = new_block_hashes[-1]
assert_equal(inv_node.check_last_announcement(inv=[tip]), True)
assert_equal(test_node.check_last_announcement(inv=[tip]), True)
@@ -389,11 +387,11 @@ class SendHeadersTest(BitcoinTestFramework):
# Use getblocks/getdata
test_node.send_getblocks(locator = [fork_point])
assert_equal(test_node.check_last_announcement(inv=new_block_hashes[0:-1]), True)
assert_equal(test_node.check_last_announcement(inv=new_block_hashes), True)
test_node.get_data(new_block_hashes)
test_node.wait_for_block(new_block_hashes[-1])
for i in xrange(3):
for i in range(3):
# Mine another block, still should get only an inv
tip = self.mine_blocks(1)
assert_equal(inv_node.check_last_announcement(inv=[tip]), True)
@@ -408,7 +406,6 @@ class SendHeadersTest(BitcoinTestFramework):
test_node.get_headers(locator=[fork_point], hashstop=new_block_hashes[1])
test_node.get_data([tip])
test_node.wait_for_block(tip)
test_node.clear_last_announcement()
elif i == 2:
test_node.get_data([tip])
test_node.wait_for_block(tip)
@@ -416,7 +413,7 @@ class SendHeadersTest(BitcoinTestFramework):
# of headers announcements, or mine a new block and inv it, also
# triggering resumption of headers announcements.
if j == 0:
test_node.get_headers(locator=[tip], hashstop=0L)
test_node.get_headers(locator=[tip], hashstop=0)
test_node.sync_with_ping()
else:
test_node.send_block_inv(tip)
@@ -426,9 +423,9 @@ class SendHeadersTest(BitcoinTestFramework):
assert_equal(inv_node.check_last_announcement(inv=[tip]), True)
assert_equal(test_node.check_last_announcement(headers=[tip]), True)
print "Part 3: success!"
print("Part 3: success!")
print "Part 4: Testing direct fetch behavior..."
print("Part 4: Testing direct fetch behavior...")
tip = self.mine_blocks(1)
height = self.nodes[0].getblockcount() + 1
last_time = self.nodes[0].getblock(self.nodes[0].getbestblockhash())['time']
@@ -436,7 +433,7 @@ class SendHeadersTest(BitcoinTestFramework):
# Create 2 blocks. Send the blocks, then send the headers.
blocks = []
for b in xrange(2):
for b in range(2):
blocks.append(create_block(tip, create_coinbase(height), block_time))
blocks[-1].solve()
tip = blocks[-1].sha256
@@ -446,7 +443,7 @@ class SendHeadersTest(BitcoinTestFramework):
inv_node.sync_with_ping() # Make sure blocks are processed
test_node.last_getdata = None
test_node.send_header_for_blocks(blocks);
test_node.send_header_for_blocks(blocks)
test_node.sync_with_ping()
# should not have received any getdata messages
with mininode_lock:
@@ -454,7 +451,7 @@ class SendHeadersTest(BitcoinTestFramework):
# This time, direct fetch should work
blocks = []
for b in xrange(3):
for b in range(3):
blocks.append(create_block(tip, create_coinbase(height), block_time))
blocks[-1].solve()
tip = blocks[-1].sha256
@@ -475,7 +472,7 @@ class SendHeadersTest(BitcoinTestFramework):
blocks = []
# Create extra blocks for later
for b in xrange(20):
for b in range(20):
blocks.append(create_block(tip, create_coinbase(height), block_time))
blocks[-1].solve()
tip = blocks[-1].sha256
@@ -509,7 +506,7 @@ class SendHeadersTest(BitcoinTestFramework):
with mininode_lock:
assert_equal(test_node.last_getdata, None)
print "Part 4: success!"
print("Part 4: success!")
# Finally, check that the inv node never received a getdata request,
# throughout the test

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2015 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2015-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python2
# Copyright (c) 2014-2015 The Bitcoin Core developers
#!/usr/bin/env python3
# Copyright (c) 2014-2016 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -7,6 +7,7 @@
# Test fee estimation code
#
from collections import OrderedDict
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
@@ -22,7 +23,7 @@ SCRIPT_SIG = ["0451025175", "0451025275"]
def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee_increment):
'''
Create and send a transaction with a random fee.
The transaction pays to a trival P2SH script, and assumes that its inputs
The transaction pays to a trivial P2SH script, and assumes that its inputs
are of the same form.
The function takes a list of confirmed outputs and unconfirmed outputs
and attempts to use the confirmed list first for its inputs.
@@ -49,10 +50,10 @@ def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee
if total_in <= amount + fee:
raise RuntimeError("Insufficient funds: need %d, have %d"%(amount+fee, total_in))
outputs = {}
outputs[P2SH_1] = total_in - amount - fee
outputs[P2SH_2] = amount
outputs = OrderedDict([(P2SH_1, total_in - amount - fee),
(P2SH_2, amount)])
rawtx = from_node.createrawtransaction(inputs, outputs)
# Createrawtransaction constructions a transaction that is ready to be signed
# createrawtransaction constructs a transaction that is ready to be signed.
# These transactions don't need to be signed, but we still have to insert the ScriptSig
# that will satisfy the ScriptPubKey.
completetx = rawtx[0:10]
@@ -78,12 +79,10 @@ def split_inputs(from_node, txins, txouts, initial_split = False):
'''
prevtxout = txins.pop()
inputs = []
outputs = {}
inputs.append({ "txid" : prevtxout["txid"], "vout" : prevtxout["vout"] })
half_change = satoshi_round(prevtxout["amount"]/2)
rem_change = prevtxout["amount"] - half_change - Decimal("0.00001000")
outputs[P2SH_1] = half_change
outputs[P2SH_2] = rem_change
outputs = OrderedDict([(P2SH_1, half_change), (P2SH_2, rem_change)])
rawtx = from_node.createrawtransaction(inputs, outputs)
# If this is the initial split we actually need to sign the transaction
# Otherwise we just need to insert the property ScriptSig
@@ -105,7 +104,7 @@ def check_estimates(node, fees_seen, max_invalid, print_estimates = True):
print([str(all_estimates[e-1]) for e in [1,2,3,6,15,25]])
delta = 1.0e-6 # account for rounding error
last_e = max(fees_seen)
for e in filter(lambda x: x >= 0, all_estimates):
for e in [x for x in all_estimates if x >= 0]:
# Estimates should be within the bounds of what transactions fees actually were:
if float(e)+delta < min(fees_seen) or float(e)-delta > max(fees_seen):
raise AssertionError("Estimated fee (%f) out of range (%f,%f)"
@@ -219,12 +218,12 @@ class EstimateFeeTest(BitcoinTestFramework):
from_index = random.randint(1,2)
(txhex, fee) = small_txpuzzle_randfee(self.nodes[from_index], self.confutxo,
self.memutxo, Decimal("0.005"), min_fee, min_fee)
tx_kbytes = (len(txhex)/2)/1000.0
tx_kbytes = (len(txhex) // 2) / 1000.0
self.fees_per_kb.append(float(fee)/tx_kbytes)
sync_mempools(self.nodes[0:3],.1)
mined = mining_node.getblock(mining_node.generate(1)[0],True)["tx"]
sync_blocks(self.nodes[0:3],.1)
#update which txouts are confirmed
# update which txouts are confirmed
newmem = []
for utx in self.memutxo:
if utx["txid"] in mined:
@@ -239,7 +238,7 @@ class EstimateFeeTest(BitcoinTestFramework):
self.confutxo = self.txouts # Start with the set of confirmed txouts after splitting
print("Will output estimates for 1/2/3/6/15/25 blocks")
for i in xrange(2):
for i in range(2):
print("Creating transactions and mining them with a block size that can't keep up")
# Create transactions and mine 10 small blocks with node 2, but create txs faster than we can mine
self.transact_and_mine(10, self.nodes[2])

View File

@@ -61,7 +61,7 @@ class JSONRPCException(Exception):
def EncodeDecimal(o):
if isinstance(o, decimal.Decimal):
return round(o, 8)
return str(o)
raise TypeError(repr(o) + " is not JSON serializable")
class AuthServiceProxy(object):
@@ -92,11 +92,10 @@ class AuthServiceProxy(object):
self.__conn = connection
elif self.__url.scheme == 'https':
self.__conn = httplib.HTTPSConnection(self.__url.hostname, port,
None, None, False,
timeout)
timeout=timeout)
else:
self.__conn = httplib.HTTPConnection(self.__url.hostname, port,
False, timeout)
timeout=timeout)
def __getattr__(self, name):
if name.startswith('__') and name.endswith('__'):
@@ -155,6 +154,11 @@ class AuthServiceProxy(object):
raise JSONRPCException({
'code': -342, 'message': 'missing HTTP response from server'})
content_type = http_response.getheader('Content-Type')
if content_type != 'application/json':
raise JSONRPCException({
'code': -342, 'message': 'non-JSON HTTP response with \'%i %s\' from server' % (http_response.status, http_response.reason)})
responsedata = http_response.read().decode('utf8')
response = json.loads(responsedata, parse_float=decimal.Decimal)
if "error" in response and response["error"] is None:

View File

@@ -1,16 +1,15 @@
#
#!/usr/bin/env python3
#
# bignum.py
#
# This file is copied from python-bitcoinlib.
#
# Distributed under the MIT/X11 software license, see the accompanying
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
"""Bignum routines"""
from __future__ import absolute_import, division, print_function, unicode_literals
import struct

Some files were not shown because too many files have changed in this diff Show More