Browse Source

Merge #8866: [0.13] Backports

5e0dd9e [Doc] Update bips.md for Segregated Witness (fanquake)
d6c83b9 [qa] Fix race condition in sendheaders.py (Suhas Daftuar)
b73f065 [qa] Another attempt to fix race condition in p2p-compactblocks.py (Suhas Daftuar)
b987348 Bugfix: Trivial: RPC: getblockchaininfo help: pruneheight is the lowest, not highest, block (Luke Dashjr)
cbc3fe5 test: Explicitly set encoding to utf8 when opening text files (Wladimir J. van der Laan)
0bee740 [qa] util: Move wait_bitcoinds() into stop_nodes() (MarcoFalke)
794b007 [qa] Add getinfo smoke tests and rework versionbits test (MarcoFalke)
1f60d45 [qa] mininode: Only allow named args in wait_until (MarcoFalke)
624a007 [qa] Fix race condition in p2p-compactblocks test (Suhas Daftuar)
3e4abb5 Fix nulldummy.py test (Johnson Lau)
31ab2f8 test: Avoid ConnectionResetErrors during RPC tests (Wladimir J. van der Laan)
eb18cc1 bitcoin-util-test.py should fail if the output file is empty (jnewbery)
d87227d [qa] nulldummy: Don't run unused code (MarcoFalke)
1dd1783 [qa] blockstore: Switch to dumb dbm (MarcoFalke)
83ad563 [rpc] throw JSONRPCError when utxo set can not be read (MarcoFalke)
6288659 [Wallet] remove "unused" ThreadFlushWalletDB from removeprunedfunds (Jonas Schnelli)
2a8bca4 Add bitcoin-tx JSON tests (jnewbery)
9bbe66e [qa] Split up slow RPC calls to avoid pruning test timeouts (Suhas Daftuar)
375437c Ping regularly in p2p-segwit.py to keep connection alive (Johnson Lau)
0.13
MarcoFalke 8 years ago
parent
commit
94688d8e43
No known key found for this signature in database
GPG Key ID: 2D7F2372E50FE137
  1. 5
      doc/bips.md
  2. 1
      qa/rpc-tests/bip9-softforks.py
  3. 6
      qa/rpc-tests/forknotify.py
  4. 1
      qa/rpc-tests/fundrawtransaction.py
  5. 2
      qa/rpc-tests/maxuploadtarget.py
  6. 2
      qa/rpc-tests/multi_rpc.py
  7. 10
      qa/rpc-tests/nulldummy.py
  8. 22
      qa/rpc-tests/p2p-compactblocks.py
  9. 2
      qa/rpc-tests/p2p-mempool.py
  10. 3
      qa/rpc-tests/p2p-segwit.py
  11. 50
      qa/rpc-tests/p2p-versionbits-warning.py
  12. 5
      qa/rpc-tests/pruning.py
  13. 16
      qa/rpc-tests/reindex.py
  14. 4
      qa/rpc-tests/rpcbind_test.py
  15. 66
      qa/rpc-tests/sendheaders.py
  16. 5
      qa/rpc-tests/test_framework/authproxy.py
  17. 6
      qa/rpc-tests/test_framework/blockstore.py
  18. 4
      qa/rpc-tests/test_framework/coverage.py
  19. 4
      qa/rpc-tests/test_framework/mininode.py
  20. 2
      qa/rpc-tests/test_framework/netutil.py
  21. 4
      qa/rpc-tests/test_framework/test_framework.py
  22. 4
      qa/rpc-tests/test_framework/util.py
  23. 2
      qa/rpc-tests/wallet-dump.py
  24. 3
      qa/rpc-tests/wallet.py
  25. 4
      src/rpc/blockchain.cpp
  26. 3
      src/test/bctest.py
  27. 85
      src/test/data/bitcoin-util-test.json
  28. 10
      src/test/data/blanktx.json
  29. 216
      src/test/data/tt-delin1-out.json
  30. 212
      src/test/data/tt-delout1-out.json
  31. 225
      src/test/data/tt-locktime317000-out.json
  32. 63
      src/test/data/txcreate1.json
  33. 19
      src/test/data/txcreate2.json
  34. 41
      src/test/data/txcreatedata1.json
  35. 41
      src/test/data/txcreatedata2.json
  36. 32
      src/test/data/txcreatedata_seq0.json
  37. 41
      src/test/data/txcreatedata_seq1.json
  38. 32
      src/test/data/txcreatesign.json
  39. 2
      src/wallet/rpcdump.cpp

5
doc/bips.md

@ -26,4 +26,9 @@ BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.13.0**):
* [`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 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)). * [`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)).
* [`BIP 133`](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki): feefilter messages are respected and sent for peer versions `>=70013` as of **v0.13.0** ([PR 7542](https://github.com/bitcoin/bitcoin/pull/7542)). * [`BIP 133`](https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki): feefilter messages are respected and sent for peer versions `>=70013` as of **v0.13.0** ([PR 7542](https://github.com/bitcoin/bitcoin/pull/7542)).
* [`BIP 141`](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki): Segregated Witness (Consensus Layer) as of **v0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)).
* [`BIP 143`](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki): Transaction Signature Verification for Version 0 Witness Program as of **v0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)).
* [`BIP 144`](https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki): Segregated Witness as of **0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)).
* [`BIP 145`](https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki): getblocktemplate updates for Segregated Witness as of **v0.13.0** ([PR 8149](https://github.com/bitcoin/bitcoin/pull/8149)).
* [`BIP 147`](https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki): NULLDUMMY softfork as of **v0.13.1** ([PR 8636](https://github.com/bitcoin/bitcoin/pull/8636)).
* [`BIP 152`](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki): Compact block transfer and related optimizations are used as of **v0.13.0** ([PR 8068](https://github.com/bitcoin/bitcoin/pull/8068)). * [`BIP 152`](https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki): Compact block transfer and related optimizations are used as of **v0.13.0** ([PR 8068](https://github.com/bitcoin/bitcoin/pull/8068)).

1
qa/rpc-tests/bip9-softforks.py

@ -195,7 +195,6 @@ class BIP9SoftForksTest(ComparisonTestFramework):
# Restart all # Restart all
self.test.block_store.close() self.test.block_store.close()
stop_nodes(self.nodes) stop_nodes(self.nodes)
wait_bitcoinds()
shutil.rmtree(self.options.tmpdir) shutil.rmtree(self.options.tmpdir)
self.setup_chain() self.setup_chain()
self.setup_network() self.setup_network()

6
qa/rpc-tests/forknotify.py

@ -22,7 +22,7 @@ class ForkNotifyTest(BitcoinTestFramework):
def setup_network(self): def setup_network(self):
self.nodes = [] self.nodes = []
self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt")
with open(self.alert_filename, 'w') as f: with open(self.alert_filename, 'w', encoding='utf8') as f:
pass # Just open then close to create zero-length file pass # Just open then close to create zero-length file
self.nodes.append(start_node(0, self.options.tmpdir, self.nodes.append(start_node(0, self.options.tmpdir,
["-blockversion=2", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""])) ["-blockversion=2", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]))
@ -44,7 +44,7 @@ class ForkNotifyTest(BitcoinTestFramework):
self.nodes[1].generate(1) self.nodes[1].generate(1)
self.sync_all() self.sync_all()
with open(self.alert_filename, 'r') as f: with open(self.alert_filename, 'r', encoding='utf8') as f:
alert_text = f.read() alert_text = f.read()
if len(alert_text) == 0: if len(alert_text) == 0:
@ -56,7 +56,7 @@ class ForkNotifyTest(BitcoinTestFramework):
self.nodes[1].generate(1) self.nodes[1].generate(1)
self.sync_all() self.sync_all()
with open(self.alert_filename, 'r') as f: with open(self.alert_filename, 'r', encoding='utf8') as f:
alert_text2 = f.read() alert_text2 = f.read()
if alert_text != alert_text2: if alert_text != alert_text2:

1
qa/rpc-tests/fundrawtransaction.py

@ -470,7 +470,6 @@ class RawTransactionsTest(BitcoinTestFramework):
self.nodes[1].encryptwallet("test") self.nodes[1].encryptwallet("test")
self.nodes.pop(1) self.nodes.pop(1)
stop_nodes(self.nodes) stop_nodes(self.nodes)
wait_bitcoinds()
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir) self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
# This test is not meant to test fee estimation and we'd like # This test is not meant to test fee estimation and we'd like

2
qa/rpc-tests/maxuploadtarget.py

@ -75,7 +75,7 @@ class TestNode(NodeConnCB):
def received_pong(): def received_pong():
return (self.last_pong.nonce == self.ping_counter) return (self.last_pong.nonce == self.ping_counter)
self.connection.send_message(msg_ping(nonce=self.ping_counter)) self.connection.send_message(msg_ping(nonce=self.ping_counter))
success = wait_until(received_pong, timeout) success = wait_until(received_pong, timeout=timeout)
self.ping_counter += 1 self.ping_counter += 1
return success return success

2
qa/rpc-tests/multi_rpc.py

@ -26,7 +26,7 @@ class HTTPBasicsTest (BitcoinTestFramework):
#Append rpcauth to bitcoin.conf before initialization #Append rpcauth to bitcoin.conf before initialization
rpcauth = "rpcauth=rt:93648e835a54c573682c2eb19f882535$7681e9c5b74bdd85e78166031d2058e1069b3ed7ed967c93fc63abba06f31144" rpcauth = "rpcauth=rt:93648e835a54c573682c2eb19f882535$7681e9c5b74bdd85e78166031d2058e1069b3ed7ed967c93fc63abba06f31144"
rpcauth2 = "rpcauth=rt2:f8607b1a88861fac29dfccf9b52ff9f$ff36a0c23c8c62b4846112e50fa888416e94c17bfd4c42f88fd8f55ec6a3137e" rpcauth2 = "rpcauth=rt2:f8607b1a88861fac29dfccf9b52ff9f$ff36a0c23c8c62b4846112e50fa888416e94c17bfd4c42f88fd8f55ec6a3137e"
with open(os.path.join(self.options.tmpdir+"/node0", "bitcoin.conf"), 'a') as f: with open(os.path.join(self.options.tmpdir+"/node0", "bitcoin.conf"), 'a', encoding='utf8') as f:
f.write(rpcauth+"\n") f.write(rpcauth+"\n")
f.write(rpcauth2+"\n") f.write(rpcauth2+"\n")

10
qa/rpc-tests/nulldummy.py

@ -3,11 +3,10 @@
# Distributed under the MIT 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. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.test_framework import ComparisonTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import * from test_framework.util import *
from test_framework.mininode import CTransaction, NetworkThread from test_framework.mininode import CTransaction, NetworkThread
from test_framework.blocktools import create_coinbase, create_block, add_witness_commitment from test_framework.blocktools import create_coinbase, create_block, add_witness_commitment
from test_framework.comptool import TestManager
from test_framework.script import CScript from test_framework.script import CScript
from io import BytesIO from io import BytesIO
import time import time
@ -37,11 +36,12 @@ Generate 427 more blocks.
[Policy/Consensus] Check that the new NULLDUMMY rules are enforced on the 432nd block. [Policy/Consensus] Check that the new NULLDUMMY rules are enforced on the 432nd block.
''' '''
class NULLDUMMYTest(ComparisonTestFramework): class NULLDUMMYTest(BitcoinTestFramework):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.num_nodes = 1 self.num_nodes = 1
self.setup_clean_chain = True
def setup_network(self): def setup_network(self):
# Must set the blockversion for this test # Must set the blockversion for this test
@ -54,8 +54,6 @@ class NULLDUMMYTest(ComparisonTestFramework):
self.wit_address = self.nodes[0].addwitnessaddress(self.address) self.wit_address = self.nodes[0].addwitnessaddress(self.address)
self.wit_ms_address = self.nodes[0].addwitnessaddress(self.ms_address) self.wit_ms_address = self.nodes[0].addwitnessaddress(self.ms_address)
test = TestManager(self, self.options.tmpdir)
test.add_all_connections(self.nodes)
NetworkThread().start() # Start up network handling in another thread NetworkThread().start() # Start up network handling in another thread
self.coinbase_blocks = self.nodes[0].generate(2) # Block 2 self.coinbase_blocks = self.nodes[0].generate(2) # Block 2
coinbase_txid = [] coinbase_txid = []
@ -121,6 +119,8 @@ class NULLDUMMYTest(ComparisonTestFramework):
node.sendrawtransaction(bytes_to_hex_str(tx.serialize_with_witness()), True) node.sendrawtransaction(bytes_to_hex_str(tx.serialize_with_witness()), True)
except JSONRPCException as exp: except JSONRPCException as exp:
assert_equal(exp.error["message"], msg) assert_equal(exp.error["message"], msg)
else:
assert_equal('', msg)
return tx.hash return tx.hash

22
qa/rpc-tests/p2p-compactblocks.py

@ -28,6 +28,10 @@ class TestNode(SingleNodeConnCB):
self.last_getblocktxn = None self.last_getblocktxn = None
self.last_block = None self.last_block = None
self.last_blocktxn = None self.last_blocktxn = None
# Store the hashes of blocks we've seen announced.
# This is for synchronizing the p2p message traffic,
# so we can eg wait until a particular block is announced.
self.set_announced_blockhashes = set()
def on_sendcmpct(self, conn, message): def on_sendcmpct(self, conn, message):
self.last_sendcmpct = message self.last_sendcmpct = message
@ -38,14 +42,22 @@ class TestNode(SingleNodeConnCB):
def on_cmpctblock(self, conn, message): def on_cmpctblock(self, conn, message):
self.last_cmpctblock = message self.last_cmpctblock = message
self.block_announced = True self.block_announced = True
self.last_cmpctblock.header_and_shortids.header.calc_sha256()
self.set_announced_blockhashes.add(self.last_cmpctblock.header_and_shortids.header.sha256)
def on_headers(self, conn, message): def on_headers(self, conn, message):
self.last_headers = message self.last_headers = message
self.block_announced = True self.block_announced = True
for x in self.last_headers.headers:
x.calc_sha256()
self.set_announced_blockhashes.add(x.sha256)
def on_inv(self, conn, message): def on_inv(self, conn, message):
self.last_inv = message self.last_inv = message
for x in self.last_inv.inv:
if x.type == 2:
self.block_announced = True self.block_announced = True
self.set_announced_blockhashes.add(x.hash)
def on_getdata(self, conn, message): def on_getdata(self, conn, message):
self.last_getdata = message self.last_getdata = message
@ -85,6 +97,12 @@ class TestNode(SingleNodeConnCB):
assert(self.received_block_announcement()) assert(self.received_block_announcement())
self.clear_block_announcement() self.clear_block_announcement()
# Block until a block announcement for a particular block hash is
# received.
def wait_for_block_announcement(self, block_hash, timeout=30):
def received_hash():
return (block_hash in self.set_announced_blockhashes)
return wait_until(received_hash, timeout=timeout)
class CompactBlocksTest(BitcoinTestFramework): class CompactBlocksTest(BitcoinTestFramework):
def __init__(self): def __init__(self):
@ -237,6 +255,10 @@ class CompactBlocksTest(BitcoinTestFramework):
for i in range(num_transactions): for i in range(num_transactions):
self.nodes[0].sendtoaddress(address, 0.1) self.nodes[0].sendtoaddress(address, 0.1)
# Wait until we've seen the block announcement for the resulting tip
tip = int(self.nodes[0].getbestblockhash(), 16)
assert(self.test_node.wait_for_block_announcement(tip))
# Now mine a block, and look at the resulting compact block. # Now mine a block, and look at the resulting compact block.
self.test_node.clear_block_announcement() self.test_node.clear_block_announcement()
block_hash = int(self.nodes[0].generate(1)[0], 16) block_hash = int(self.nodes[0].generate(1)[0], 16)

2
qa/rpc-tests/p2p-mempool.py

@ -63,7 +63,7 @@ class TestNode(NodeConnCB):
def received_pong(): def received_pong():
return (self.last_pong.nonce == self.ping_counter) return (self.last_pong.nonce == self.ping_counter)
self.connection.send_message(msg_ping(nonce=self.ping_counter)) self.connection.send_message(msg_ping(nonce=self.ping_counter))
success = wait_until(received_pong, timeout) success = wait_until(received_pong, timeout=timeout)
self.ping_counter += 1 self.ping_counter += 1
return success return success

3
qa/rpc-tests/p2p-segwit.py

@ -1389,6 +1389,9 @@ class SegWitTest(BitcoinTestFramework):
block = self.build_next_block() block = self.build_next_block()
used_sighash_single_out_of_bounds = False used_sighash_single_out_of_bounds = False
for i in range(NUM_TESTS): for i in range(NUM_TESTS):
# Ping regularly to keep the connection alive
if (not i % 100):
self.test_node.sync_with_ping()
# Choose random number of inputs to use. # Choose random number of inputs to use.
num_inputs = random.randint(1, 10) num_inputs = random.randint(1, 10)
# Create a slight bias for producing more utxos # Create a slight bias for producing more utxos

50
qa/rpc-tests/p2p-versionbits-warning.py

@ -6,6 +6,7 @@
from test_framework.mininode import * from test_framework.mininode import *
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import * from test_framework.util import *
import re
import time import time
from test_framework.blocktools import create_block, create_coinbase from test_framework.blocktools import create_block, create_coinbase
@ -21,6 +22,10 @@ VB_THRESHOLD = 108 # versionbits activation threshold for regtest
VB_TOP_BITS = 0x20000000 VB_TOP_BITS = 0x20000000
VB_UNKNOWN_BIT = 27 # Choose a bit unassigned to any deployment VB_UNKNOWN_BIT = 27 # Choose a bit unassigned to any deployment
WARN_UNKNOWN_RULES_MINED = "Unknown block versions being mined! It's possible unknown rules are in effect"
WARN_UNKNOWN_RULES_ACTIVE = "unknown new rules activated (versionbit {})".format(VB_UNKNOWN_BIT)
VB_PATTERN = re.compile("^Warning.*versionbit")
# TestNode: bare-bones "peer". Used mostly as a conduit for a test to sending # 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. # p2p messages to a node, generating the messages in the main testing logic.
class TestNode(NodeConnCB): class TestNode(NodeConnCB):
@ -65,16 +70,12 @@ class VersionBitsWarningTest(BitcoinTestFramework):
self.num_nodes = 1 self.num_nodes = 1
def setup_network(self): def setup_network(self):
self.nodes = []
self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt") self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt")
# Open and close to create zero-length file # Open and close to create zero-length file
with open(self.alert_filename, 'w') as f: with open(self.alert_filename, 'w', encoding='utf8') as _:
pass pass
self.node_options = ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""] self.extra_args = [["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]]
self.nodes.append(start_node(0, self.options.tmpdir, self.node_options)) self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args)
import re
self.vb_pattern = re.compile("^Warning.*versionbit")
# Send numblocks blocks via peer with nVersionToUse set. # Send numblocks blocks via peer with nVersionToUse set.
def send_blocks_with_version(self, peer, numblocks, nVersionToUse): def send_blocks_with_version(self, peer, numblocks, nVersionToUse):
@ -83,7 +84,7 @@ class VersionBitsWarningTest(BitcoinTestFramework):
block_time = self.nodes[0].getblockheader(tip)["time"]+1 block_time = self.nodes[0].getblockheader(tip)["time"]+1
tip = int(tip, 16) tip = int(tip, 16)
for i in range(numblocks): for _ in range(numblocks):
block = create_block(tip, create_coinbase(height+1), block_time) block = create_block(tip, create_coinbase(height+1), block_time)
block.nVersion = nVersionToUse block.nVersion = nVersionToUse
block.solve() block.solve()
@ -94,9 +95,9 @@ class VersionBitsWarningTest(BitcoinTestFramework):
peer.sync_with_ping() peer.sync_with_ping()
def test_versionbits_in_alert_file(self): def test_versionbits_in_alert_file(self):
with open(self.alert_filename, 'r') as f: with open(self.alert_filename, 'r', encoding='utf8') as f:
alert_text = f.read() alert_text = f.read()
assert(self.vb_pattern.match(alert_text)) assert(VB_PATTERN.match(alert_text))
def run_test(self): def run_test(self):
# Setup the p2p connection and start up the network thread. # Setup the p2p connection and start up the network thread.
@ -122,8 +123,10 @@ class VersionBitsWarningTest(BitcoinTestFramework):
# Fill rest of period with regular version blocks # Fill rest of period with regular version blocks
self.nodes[0].generate(VB_PERIOD - VB_THRESHOLD + 1) self.nodes[0].generate(VB_PERIOD - VB_THRESHOLD + 1)
# Check that we're not getting any versionbit-related errors in # Check that we're not getting any versionbit-related errors in
# getinfo() # get*info()
assert(not self.vb_pattern.match(self.nodes[0].getinfo()["errors"])) assert(not VB_PATTERN.match(self.nodes[0].getinfo()["errors"]))
assert(not VB_PATTERN.match(self.nodes[0].getmininginfo()["errors"]))
assert(not VB_PATTERN.match(self.nodes[0].getnetworkinfo()["warnings"]))
# 3. Now build one period of blocks with >= VB_THRESHOLD blocks signaling # 3. Now build one period of blocks with >= VB_THRESHOLD blocks signaling
# some unknown bit # some unknown bit
@ -132,30 +135,31 @@ class VersionBitsWarningTest(BitcoinTestFramework):
# Might not get a versionbits-related alert yet, as we should # Might not get a versionbits-related alert yet, as we should
# have gotten a different alert due to more than 51/100 blocks # have gotten a different alert due to more than 51/100 blocks
# being of unexpected version. # being of unexpected version.
# Check that getinfo() shows some kind of error. # Check that get*info() shows some kind of error.
assert(len(self.nodes[0].getinfo()["errors"]) != 0) assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getinfo()["errors"])
assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getmininginfo()["errors"])
assert(WARN_UNKNOWN_RULES_MINED in self.nodes[0].getnetworkinfo()["warnings"])
# Mine a period worth of expected blocks so the generic block-version warning # 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 # is cleared, and restart the node. This should move the versionbit state
# to ACTIVE. # to ACTIVE.
self.nodes[0].generate(VB_PERIOD) self.nodes[0].generate(VB_PERIOD)
stop_node(self.nodes[0], 0) stop_nodes(self.nodes)
wait_bitcoinds()
# Empty out the alert file # Empty out the alert file
with open(self.alert_filename, 'w') as f: with open(self.alert_filename, 'w', encoding='utf8') as _:
pass pass
self.nodes[0] = start_node(0, self.options.tmpdir, ["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]) self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args)
# Connecting one block should be enough to generate an error. # Connecting one block should be enough to generate an error.
self.nodes[0].generate(1) self.nodes[0].generate(1)
assert(len(self.nodes[0].getinfo()["errors"]) != 0) assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getinfo()["errors"])
stop_node(self.nodes[0], 0) assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getmininginfo()["errors"])
wait_bitcoinds() assert(WARN_UNKNOWN_RULES_ACTIVE in self.nodes[0].getnetworkinfo()["warnings"])
stop_nodes(self.nodes)
self.test_versionbits_in_alert_file() self.test_versionbits_in_alert_file()
# Test framework expects the node to still be running... # 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 + "\""]) self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args)
if __name__ == '__main__': if __name__ == '__main__':
VersionBitsWarningTest().main() VersionBitsWarningTest().main()

5
qa/rpc-tests/pruning.py

@ -157,7 +157,10 @@ class PruneTest(BitcoinTestFramework):
print("Usage possibly still high bc of stale blocks in block files:", calc_usage(self.prunedir)) 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 for i in range(22):
# This can be slow, so do this in multiple RPC calls to avoid
# RPC timeouts.
self.nodes[0].generate(10) #node 0 has many large tx's in its mempool from the disconnects
sync_blocks(self.nodes[0:3], timeout=300) sync_blocks(self.nodes[0:3], timeout=300)
usage = calc_usage(self.prunedir) usage = calc_usage(self.prunedir)

16
qa/rpc-tests/reindex.py

@ -7,7 +7,11 @@
# Test -reindex and -reindex-chainstate with CheckBlockIndex # Test -reindex and -reindex-chainstate with CheckBlockIndex
# #
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import * from test_framework.util import (
start_nodes,
stop_nodes,
assert_equal,
)
import time import time
class ReindexTest(BitcoinTestFramework): class ReindexTest(BitcoinTestFramework):
@ -18,16 +22,14 @@ class ReindexTest(BitcoinTestFramework):
self.num_nodes = 1 self.num_nodes = 1
def setup_network(self): def setup_network(self):
self.nodes = [] self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)
self.is_network_split = False
self.nodes.append(start_node(0, self.options.tmpdir))
def reindex(self, justchainstate=False): def reindex(self, justchainstate=False):
self.nodes[0].generate(3) self.nodes[0].generate(3)
blockcount = self.nodes[0].getblockcount() blockcount = self.nodes[0].getblockcount()
stop_node(self.nodes[0], 0) stop_nodes(self.nodes)
wait_bitcoinds() extra_args = [["-debug", "-reindex-chainstate" if justchainstate else "-reindex", "-checkblockindex=1"]]
self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug", "-reindex-chainstate" if justchainstate else "-reindex", "-checkblockindex=1"]) self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args)
while self.nodes[0].getblockcount() < blockcount: while self.nodes[0].getblockcount() < blockcount:
time.sleep(0.1) time.sleep(0.1)
assert_equal(self.nodes[0].getblockcount(), blockcount) assert_equal(self.nodes[0].getblockcount(), blockcount)

4
qa/rpc-tests/rpcbind_test.py

@ -42,11 +42,10 @@ class RPCBindTest(BitcoinTestFramework):
assert_equal(set(get_bind_addrs(pid)), set(expected)) assert_equal(set(get_bind_addrs(pid)), set(expected))
finally: finally:
stop_nodes(self.nodes) stop_nodes(self.nodes)
wait_bitcoinds()
def run_allowip_test(self, allow_ips, rpchost, rpcport): def run_allowip_test(self, allow_ips, rpchost, rpcport):
''' '''
Start a node with rpcwallow IP, and request getinfo Start a node with rpcallow IP, and request getinfo
at a non-localhost IP. at a non-localhost IP.
''' '''
base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips] base_args = ['-disablewallet', '-nolisten'] + ['-rpcallowip='+x for x in allow_ips]
@ -58,7 +57,6 @@ class RPCBindTest(BitcoinTestFramework):
finally: finally:
node = None # make sure connection will be garbage collected and closed node = None # make sure connection will be garbage collected and closed
stop_nodes(self.nodes) stop_nodes(self.nodes)
wait_bitcoinds()
def run_test(self): def run_test(self):
# due to OS-specific network stats queries, this test works only on Linux # due to OS-specific network stats queries, this test works only on Linux

66
qa/rpc-tests/sendheaders.py

@ -80,20 +80,19 @@ e. Announce one more that doesn't connect.
Expect: disconnect. Expect: disconnect.
''' '''
class BaseNode(NodeConnCB): direct_fetch_response_time = 0.05
class BaseNode(SingleNodeConnCB):
def __init__(self): def __init__(self):
NodeConnCB.__init__(self) SingleNodeConnCB.__init__(self)
self.connection = None
self.last_inv = None self.last_inv = None
self.last_headers = None self.last_headers = None
self.last_block = None self.last_block = None
self.ping_counter = 1
self.last_pong = msg_pong(0)
self.last_getdata = None self.last_getdata = None
self.sleep_time = 0.05
self.block_announced = False self.block_announced = False
self.last_getheaders = None self.last_getheaders = None
self.disconnected = False self.disconnected = False
self.last_blockhash_announced = None
def clear_last_announcement(self): def clear_last_announcement(self):
with mininode_lock: with mininode_lock:
@ -101,9 +100,6 @@ class BaseNode(NodeConnCB):
self.last_inv = None self.last_inv = None
self.last_headers = None self.last_headers = None
def add_connection(self, conn):
self.connection = conn
# Request data for a list of block hashes # Request data for a list of block hashes
def get_data(self, block_hashes): def get_data(self, block_hashes):
msg = msg_getdata() msg = msg_getdata()
@ -122,17 +118,17 @@ class BaseNode(NodeConnCB):
msg.inv = [CInv(2, blockhash)] msg.inv = [CInv(2, blockhash)]
self.connection.send_message(msg) self.connection.send_message(msg)
# Wrapper for the NodeConn's send_message function
def send_message(self, message):
self.connection.send_message(message)
def on_inv(self, conn, message): def on_inv(self, conn, message):
self.last_inv = message self.last_inv = message
self.block_announced = True self.block_announced = True
self.last_blockhash_announced = message.inv[-1].hash
def on_headers(self, conn, message): def on_headers(self, conn, message):
self.last_headers = message self.last_headers = message
if len(message.headers):
self.block_announced = True self.block_announced = True
message.headers[-1].calc_sha256()
self.last_blockhash_announced = message.headers[-1].sha256
def on_block(self, conn, message): def on_block(self, conn, message):
self.last_block = message.block self.last_block = message.block
@ -141,9 +137,6 @@ class BaseNode(NodeConnCB):
def on_getdata(self, conn, message): def on_getdata(self, conn, message):
self.last_getdata = message self.last_getdata = message
def on_pong(self, conn, message):
self.last_pong = message
def on_getheaders(self, conn, message): def on_getheaders(self, conn, message):
self.last_getheaders = message self.last_getheaders = message
@ -157,7 +150,7 @@ class BaseNode(NodeConnCB):
expect_headers = headers if headers != None else [] expect_headers = headers if headers != None else []
expect_inv = inv if inv != None else [] expect_inv = inv if inv != None else []
test_function = lambda: self.block_announced test_function = lambda: self.block_announced
self.sync(test_function) assert(wait_until(test_function, timeout=60))
with mininode_lock: with mininode_lock:
self.block_announced = False self.block_announced = False
@ -180,30 +173,14 @@ class BaseNode(NodeConnCB):
return success return success
# Syncing helpers # Syncing helpers
def sync(self, test_function, timeout=60):
while timeout > 0:
with mininode_lock:
if test_function():
return
time.sleep(self.sleep_time)
timeout -= self.sleep_time
raise AssertionError("Sync failed to complete")
def sync_with_ping(self, timeout=60):
self.send_message(msg_ping(nonce=self.ping_counter))
test_function = lambda: self.last_pong.nonce == self.ping_counter
self.sync(test_function, timeout)
self.ping_counter += 1
return
def wait_for_block(self, blockhash, timeout=60): def wait_for_block(self, blockhash, timeout=60):
test_function = lambda: self.last_block != None and self.last_block.sha256 == blockhash test_function = lambda: self.last_block != None and self.last_block.sha256 == blockhash
self.sync(test_function, timeout) assert(wait_until(test_function, timeout=timeout))
return return
def wait_for_getheaders(self, timeout=60): def wait_for_getheaders(self, timeout=60):
test_function = lambda: self.last_getheaders != None test_function = lambda: self.last_getheaders != None
self.sync(test_function, timeout) assert(wait_until(test_function, timeout=timeout))
return return
def wait_for_getdata(self, hash_list, timeout=60): def wait_for_getdata(self, hash_list, timeout=60):
@ -211,12 +188,17 @@ class BaseNode(NodeConnCB):
return return
test_function = lambda: self.last_getdata != None and [x.hash for x in self.last_getdata.inv] == hash_list test_function = lambda: self.last_getdata != None and [x.hash for x in self.last_getdata.inv] == hash_list
self.sync(test_function, timeout) assert(wait_until(test_function, timeout=timeout))
return return
def wait_for_disconnect(self, timeout=60): def wait_for_disconnect(self, timeout=60):
test_function = lambda: self.disconnected test_function = lambda: self.disconnected
self.sync(test_function, timeout) assert(wait_until(test_function, timeout=timeout))
return
def wait_for_block_announcement(self, block_hash, timeout=60):
test_function = lambda: self.last_blockhash_announced == block_hash
assert(wait_until(test_function, timeout=timeout))
return return
def send_header_for_blocks(self, new_blocks): def send_header_for_blocks(self, new_blocks):
@ -266,7 +248,9 @@ class SendHeadersTest(BitcoinTestFramework):
def mine_reorg(self, length): def mine_reorg(self, length):
self.nodes[0].generate(length) # make sure all invalidated blocks are node0's self.nodes[0].generate(length) # make sure all invalidated blocks are node0's
sync_blocks(self.nodes, wait=0.1) sync_blocks(self.nodes, wait=0.1)
[x.clear_last_announcement() for x in self.p2p_connections] for x in self.p2p_connections:
x.wait_for_block_announcement(int(self.nodes[0].getbestblockhash(), 16))
x.clear_last_announcement()
tip_height = self.nodes[1].getblockcount() tip_height = self.nodes[1].getblockcount()
hash_to_invalidate = self.nodes[1].getblockhash(tip_height-(length-1)) hash_to_invalidate = self.nodes[1].getblockhash(tip_height-(length-1))
@ -495,7 +479,7 @@ class SendHeadersTest(BitcoinTestFramework):
test_node.send_header_for_blocks(blocks) test_node.send_header_for_blocks(blocks)
test_node.sync_with_ping() test_node.sync_with_ping()
test_node.wait_for_getdata([x.sha256 for x in blocks], timeout=test_node.sleep_time) test_node.wait_for_getdata([x.sha256 for x in blocks], timeout=direct_fetch_response_time)
[ test_node.send_message(msg_block(x)) for x in blocks ] [ test_node.send_message(msg_block(x)) for x in blocks ]
@ -526,13 +510,13 @@ class SendHeadersTest(BitcoinTestFramework):
# both blocks (same work as tip) # both blocks (same work as tip)
test_node.send_header_for_blocks(blocks[1:2]) test_node.send_header_for_blocks(blocks[1:2])
test_node.sync_with_ping() test_node.sync_with_ping()
test_node.wait_for_getdata([x.sha256 for x in blocks[0:2]], timeout=test_node.sleep_time) test_node.wait_for_getdata([x.sha256 for x in blocks[0:2]], timeout=direct_fetch_response_time)
# Announcing 16 more headers should trigger direct fetch for 14 more # Announcing 16 more headers should trigger direct fetch for 14 more
# blocks # blocks
test_node.send_header_for_blocks(blocks[2:18]) test_node.send_header_for_blocks(blocks[2:18])
test_node.sync_with_ping() test_node.sync_with_ping()
test_node.wait_for_getdata([x.sha256 for x in blocks[2:16]], timeout=test_node.sleep_time) test_node.wait_for_getdata([x.sha256 for x in blocks[2:16]], timeout=direct_fetch_response_time)
# Announcing 1 more header should not trigger any response # Announcing 1 more header should not trigger any response
test_node.last_getdata = None test_node.last_getdata = None

5
qa/rpc-tests/test_framework/authproxy.py

@ -126,8 +126,9 @@ class AuthServiceProxy(object):
return self._get_response() return self._get_response()
else: else:
raise raise
except BrokenPipeError: except (BrokenPipeError,ConnectionResetError):
# Python 3.5+ raises this instead of BadStatusLine when the connection was reset # Python 3.5+ raises BrokenPipeError instead of BadStatusLine when the connection was reset
# ConnectionResetError happens on FreeBSD with Python 3.4
self.__conn.close() self.__conn.close()
self.__conn.request(method, path, postdata, headers) self.__conn.request(method, path, postdata, headers)
return self._get_response() return self._get_response()

6
qa/rpc-tests/test_framework/blockstore.py

@ -9,11 +9,11 @@
from .mininode import * from .mininode import *
from io import BytesIO from io import BytesIO
import dbm.ndbm import dbm.dumb as dbmd
class BlockStore(object): class BlockStore(object):
def __init__(self, datadir): def __init__(self, datadir):
self.blockDB = dbm.ndbm.open(datadir + "/blocks", 'c') self.blockDB = dbmd.open(datadir + "/blocks", 'c')
self.currentBlock = 0 self.currentBlock = 0
self.headers_map = dict() self.headers_map = dict()
@ -123,7 +123,7 @@ class BlockStore(object):
class TxStore(object): class TxStore(object):
def __init__(self, datadir): def __init__(self, datadir):
self.txDB = dbm.ndbm.open(datadir + "/transactions", 'c') self.txDB = dbmd.open(datadir + "/transactions", 'c')
def close(self): def close(self):
self.txDB.close() self.txDB.close()

4
qa/rpc-tests/test_framework/coverage.py

@ -50,7 +50,7 @@ class AuthServiceProxyWrapper(object):
rpc_method = self.auth_service_proxy_instance._service_name rpc_method = self.auth_service_proxy_instance._service_name
if self.coverage_logfile: if self.coverage_logfile:
with open(self.coverage_logfile, 'a+') as f: with open(self.coverage_logfile, 'a+', encoding='utf8') as f:
f.write("%s\n" % rpc_method) f.write("%s\n" % rpc_method)
return return_val return return_val
@ -100,7 +100,7 @@ def write_all_rpc_commands(dirname, node):
if line and not line.startswith('='): if line and not line.startswith('='):
commands.add("%s\n" % line.split()[0]) commands.add("%s\n" % line.split()[0])
with open(filename, 'w') as f: with open(filename, 'w', encoding='utf8') as f:
f.writelines(list(commands)) f.writelines(list(commands))
return True return True

4
qa/rpc-tests/test_framework/mininode.py

@ -1320,7 +1320,7 @@ class msg_reject(object):
% (self.message, self.code, self.reason, self.data) % (self.message, self.code, self.reason, self.data)
# Helper function # Helper function
def wait_until(predicate, attempts=float('inf'), timeout=float('inf')): def wait_until(predicate, *, attempts=float('inf'), timeout=float('inf')):
attempt = 0 attempt = 0
elapsed = 0 elapsed = 0
@ -1536,7 +1536,7 @@ class SingleNodeConnCB(NodeConnCB):
def received_pong(): def received_pong():
return (self.last_pong.nonce == self.ping_counter) return (self.last_pong.nonce == self.ping_counter)
self.send_message(msg_ping(nonce=self.ping_counter)) self.send_message(msg_ping(nonce=self.ping_counter))
success = wait_until(received_pong, timeout) success = wait_until(received_pong, timeout=timeout)
self.ping_counter += 1 self.ping_counter += 1
return success return success

2
qa/rpc-tests/test_framework/netutil.py

@ -58,7 +58,7 @@ def netstat(typ='tcp'):
To get pid of all network process running on system, you must run this script To get pid of all network process running on system, you must run this script
as superuser as superuser
''' '''
with open('/proc/net/'+typ,'r') as f: with open('/proc/net/'+typ,'r',encoding='utf8') as f:
content = f.readlines() content = f.readlines()
content.pop(0) content.pop(0)
result = [] result = []

4
qa/rpc-tests/test_framework/test_framework.py

@ -21,7 +21,6 @@ from .util import (
sync_mempools, sync_mempools,
stop_nodes, stop_nodes,
stop_node, stop_node,
wait_bitcoinds,
enable_coverage, enable_coverage,
check_json_precision, check_json_precision,
initialize_chain_clean, initialize_chain_clean,
@ -81,7 +80,6 @@ class BitcoinTestFramework(object):
""" """
assert not self.is_network_split assert not self.is_network_split
stop_nodes(self.nodes) stop_nodes(self.nodes)
wait_bitcoinds()
self.setup_network(True) self.setup_network(True)
def sync_all(self): def sync_all(self):
@ -100,7 +98,6 @@ class BitcoinTestFramework(object):
""" """
assert self.is_network_split assert self.is_network_split
stop_nodes(self.nodes) stop_nodes(self.nodes)
wait_bitcoinds()
self.setup_network(False) self.setup_network(False)
def main(self): def main(self):
@ -168,7 +165,6 @@ class BitcoinTestFramework(object):
if not self.options.noshutdown: if not self.options.noshutdown:
print("Stopping nodes") print("Stopping nodes")
stop_nodes(self.nodes) stop_nodes(self.nodes)
wait_bitcoinds()
else: else:
print("Note: bitcoinds were not stopped and may still be running") print("Note: bitcoinds were not stopped and may still be running")

4
qa/rpc-tests/test_framework/util.py

@ -157,7 +157,7 @@ def initialize_datadir(dirname, n):
if not os.path.isdir(datadir): if not os.path.isdir(datadir):
os.makedirs(datadir) os.makedirs(datadir)
rpc_u, rpc_p = rpc_auth_pair(n) rpc_u, rpc_p = rpc_auth_pair(n)
with open(os.path.join(datadir, "bitcoin.conf"), 'w') as f: with open(os.path.join(datadir, "bitcoin.conf"), 'w', encoding='utf8') as f:
f.write("regtest=1\n") f.write("regtest=1\n")
f.write("rpcuser=" + rpc_u + "\n") f.write("rpcuser=" + rpc_u + "\n")
f.write("rpcpassword=" + rpc_p + "\n") f.write("rpcpassword=" + rpc_p + "\n")
@ -262,7 +262,6 @@ def initialize_chain(test_dir, num_nodes):
# Shut them down, and clean up cache directories: # Shut them down, and clean up cache directories:
stop_nodes(rpcs) stop_nodes(rpcs)
wait_bitcoinds()
disable_mocktime() disable_mocktime()
for i in range(MAX_NODES): for i in range(MAX_NODES):
os.remove(log_filename("cache", i, "debug.log")) os.remove(log_filename("cache", i, "debug.log"))
@ -361,6 +360,7 @@ def stop_nodes(nodes):
except http.client.CannotSendRequest as e: except http.client.CannotSendRequest as e:
print("WARN: Unable to stop node: " + repr(e)) print("WARN: Unable to stop node: " + repr(e))
del nodes[:] # Emptying array closes connections as a side effect del nodes[:] # Emptying array closes connections as a side effect
wait_bitcoinds()
def set_node_times(nodes, t): def set_node_times(nodes, t):
for node in nodes: for node in nodes:

2
qa/rpc-tests/wallet-dump.py

@ -12,7 +12,7 @@ def read_dump(file_name, addrs, hd_master_addr_old):
Read the given dump, count the addrs that match, count change and reserve. Read the given dump, count the addrs that match, count change and reserve.
Also check that the old hd_master is inactive Also check that the old hd_master is inactive
""" """
with open(file_name) as inputfile: with open(file_name, encoding='utf8') as inputfile:
found_addr = 0 found_addr = 0
found_addr_chg = 0 found_addr_chg = 0
found_addr_rsv = 0 found_addr_rsv = 0

3
qa/rpc-tests/wallet.py

@ -199,7 +199,6 @@ class WalletTest (BitcoinTestFramework):
#do some -walletbroadcast tests #do some -walletbroadcast tests
stop_nodes(self.nodes) stop_nodes(self.nodes)
wait_bitcoinds()
self.nodes = start_nodes(3, self.options.tmpdir, [["-walletbroadcast=0"],["-walletbroadcast=0"],["-walletbroadcast=0"]]) self.nodes = start_nodes(3, self.options.tmpdir, [["-walletbroadcast=0"],["-walletbroadcast=0"],["-walletbroadcast=0"]])
connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,0,1)
connect_nodes_bi(self.nodes,1,2) connect_nodes_bi(self.nodes,1,2)
@ -225,7 +224,6 @@ class WalletTest (BitcoinTestFramework):
#restart the nodes with -walletbroadcast=1 #restart the nodes with -walletbroadcast=1
stop_nodes(self.nodes) stop_nodes(self.nodes)
wait_bitcoinds()
self.nodes = start_nodes(3, self.options.tmpdir) self.nodes = start_nodes(3, self.options.tmpdir)
connect_nodes_bi(self.nodes,0,1) connect_nodes_bi(self.nodes,0,1)
connect_nodes_bi(self.nodes,1,2) connect_nodes_bi(self.nodes,1,2)
@ -335,7 +333,6 @@ class WalletTest (BitcoinTestFramework):
for m in maintenance: for m in maintenance:
print("check " + m) print("check " + m)
stop_nodes(self.nodes) stop_nodes(self.nodes)
wait_bitcoinds()
self.nodes = start_nodes(3, self.options.tmpdir, [[m]] * 3) self.nodes = start_nodes(3, self.options.tmpdir, [[m]] * 3)
while m == '-reindex' and [block_count] * 3 != [self.nodes[i].getblockcount() for i in range(3)]: while m == '-reindex' and [block_count] * 3 != [self.nodes[i].getblockcount() for i in range(3)]:
# reindex will leave rpc warm up "early"; Wait for it to finish # reindex will leave rpc warm up "early"; Wait for it to finish

4
src/rpc/blockchain.cpp

@ -704,6 +704,8 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp)
ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize)); ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize));
ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex())); ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex()));
ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount))); ret.push_back(Pair("total_amount", ValueFromAmount(stats.nTotalAmount)));
} else {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Unable to read UTXO set");
} }
return ret; return ret;
} }
@ -892,7 +894,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp)
" \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n" " \"verificationprogress\": xxxx, (numeric) estimate of verification progress [0..1]\n"
" \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n" " \"chainwork\": \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n"
" \"pruned\": xx, (boolean) if the blocks are subject to pruning\n" " \"pruned\": xx, (boolean) if the blocks are subject to pruning\n"
" \"pruneheight\": xxxxxx, (numeric) heighest block available\n" " \"pruneheight\": xxxxxx, (numeric) lowest-height complete block stored\n"
" \"softforks\": [ (array) status of softforks in progress\n" " \"softforks\": [ (array) status of softforks in progress\n"
" {\n" " {\n"
" \"id\": \"xxxx\", (string) name of softfork\n" " \"id\": \"xxxx\", (string) name of softfork\n"

3
src/test/bctest.py

@ -24,6 +24,9 @@ def bctest(testDir, testObj, exeext):
if "output_cmp" in testObj: if "output_cmp" in testObj:
outputFn = testObj['output_cmp'] outputFn = testObj['output_cmp']
outputData = open(testDir + "/" + outputFn).read() outputData = open(testDir + "/" + outputFn).read()
if not outputData:
print("Output data missing for " + outputFn)
sys.exit(1)
proc = subprocess.Popen(execrun, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True) proc = subprocess.Popen(execrun, stdin=stdinCfg, stdout=subprocess.PIPE, stderr=subprocess.PIPE,universal_newlines=True)
try: try:
outs = proc.communicate(input=inputData) outs = proc.communicate(input=inputData)

85
src/test/data/bitcoin-util-test.json

@ -1,18 +1,32 @@
[ [
{ "exec": "././bitcoin-tx", { "exec": "./bitcoin-tx",
"args": ["-create"], "args": ["-create"],
"output_cmp": "blanktx.hex" "output_cmp": "blanktx.hex"
}, },
{ "exec": "./bitcoin-tx",
"args": ["-json","-create"],
"output_cmp": "blanktx.json"
},
{ "exec": "./bitcoin-tx", { "exec": "./bitcoin-tx",
"args": ["-"], "args": ["-"],
"input": "blanktx.hex", "input": "blanktx.hex",
"output_cmp": "blanktx.hex" "output_cmp": "blanktx.hex"
}, },
{ "exec": "./bitcoin-tx",
"args": ["-json","-"],
"input": "blanktx.hex",
"output_cmp": "blanktx.json"
},
{ "exec": "./bitcoin-tx", { "exec": "./bitcoin-tx",
"args": ["-", "delin=1"], "args": ["-", "delin=1"],
"input": "tx394b54bb.hex", "input": "tx394b54bb.hex",
"output_cmp": "tt-delin1-out.hex" "output_cmp": "tt-delin1-out.hex"
}, },
{ "exec": "./bitcoin-tx",
"args": ["-json", "-", "delin=1"],
"input": "tx394b54bb.hex",
"output_cmp": "tt-delin1-out.json"
},
{ "exec": "./bitcoin-tx", { "exec": "./bitcoin-tx",
"args": ["-", "delin=31"], "args": ["-", "delin=31"],
"input": "tx394b54bb.hex", "input": "tx394b54bb.hex",
@ -23,6 +37,11 @@
"input": "tx394b54bb.hex", "input": "tx394b54bb.hex",
"output_cmp": "tt-delout1-out.hex" "output_cmp": "tt-delout1-out.hex"
}, },
{ "exec": "./bitcoin-tx",
"args": ["-json", "-", "delout=1"],
"input": "tx394b54bb.hex",
"output_cmp": "tt-delout1-out.json"
},
{ "exec": "./bitcoin-tx", { "exec": "./bitcoin-tx",
"args": ["-", "delout=2"], "args": ["-", "delout=2"],
"input": "tx394b54bb.hex", "input": "tx394b54bb.hex",
@ -33,6 +52,11 @@
"input": "tx394b54bb.hex", "input": "tx394b54bb.hex",
"output_cmp": "tt-locktime317000-out.hex" "output_cmp": "tt-locktime317000-out.hex"
}, },
{ "exec": "./bitcoin-tx",
"args": ["-json", "-", "locktime=317000"],
"input": "tx394b54bb.hex",
"output_cmp": "tt-locktime317000-out.json"
},
{ "exec": "./bitcoin-tx", { "exec": "./bitcoin-tx",
"args": "args":
["-create", ["-create",
@ -43,10 +67,25 @@
"outaddr=4:1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46"], "outaddr=4:1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46"],
"output_cmp": "txcreate1.hex" "output_cmp": "txcreate1.hex"
}, },
{ "exec": "./bitcoin-tx",
"args":
["-json",
"-create",
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
"in=bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c:18",
"in=22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc:1",
"outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
"outaddr=4:1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46"],
"output_cmp": "txcreate1.json"
},
{ "exec": "./bitcoin-tx", { "exec": "./bitcoin-tx",
"args": ["-create", "outscript=0:"], "args": ["-create", "outscript=0:"],
"output_cmp": "txcreate2.hex" "output_cmp": "txcreate2.hex"
}, },
{ "exec": "./bitcoin-tx",
"args": ["-json", "-create", "outscript=0:"],
"output_cmp": "txcreate2.json"
},
{ "exec": "./bitcoin-tx", { "exec": "./bitcoin-tx",
"args": "args":
["-create", ["-create",
@ -57,6 +96,17 @@
"outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"], "outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"],
"output_cmp": "txcreatesign.hex" "output_cmp": "txcreatesign.hex"
}, },
{ "exec": "./bitcoin-tx",
"args":
["-json",
"-create",
"in=4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485:0",
"set=privatekeys:[\"5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf\"]",
"set=prevtxs:[{\"txid\":\"4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485\",\"vout\":0,\"scriptPubKey\":\"76a91491b24bf9f5288532960ac687abb035127b1d28a588ac\"}]",
"sign=ALL",
"outaddr=0.001:193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"],
"output_cmp": "txcreatesign.json"
},
{ "exec": "./bitcoin-tx", { "exec": "./bitcoin-tx",
"args": "args":
["-create", ["-create",
@ -79,6 +129,15 @@
"outdata=4:54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"], "outdata=4:54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"],
"output_cmp": "txcreatedata1.hex" "output_cmp": "txcreatedata1.hex"
}, },
{ "exec": "./bitcoin-tx",
"args":
["-json",
"-create",
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
"outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
"outdata=4:54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"],
"output_cmp": "txcreatedata1.json"
},
{ "exec": "./bitcoin-tx", { "exec": "./bitcoin-tx",
"args": "args":
["-create", ["-create",
@ -87,6 +146,15 @@
"outdata=54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"], "outdata=54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"],
"output_cmp": "txcreatedata2.hex" "output_cmp": "txcreatedata2.hex"
}, },
{ "exec": "./bitcoin-tx",
"args":
["-json",
"-create",
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0",
"outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o",
"outdata=54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e"],
"output_cmp": "txcreatedata2.json"
},
{ "exec": "./bitcoin-tx", { "exec": "./bitcoin-tx",
"args": "args":
["-create", ["-create",
@ -94,10 +162,25 @@
"outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"], "outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"],
"output_cmp": "txcreatedata_seq0.hex" "output_cmp": "txcreatedata_seq0.hex"
}, },
{ "exec": "./bitcoin-tx",
"args":
["-json",
"-create",
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:4294967293",
"outaddr=0.18:13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"],
"output_cmp": "txcreatedata_seq0.json"
},
{ "exec": "./bitcoin-tx", { "exec": "./bitcoin-tx",
"args": "args":
["01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000", ["01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000",
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:1"], "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:1"],
"output_cmp": "txcreatedata_seq1.hex" "output_cmp": "txcreatedata_seq1.hex"
},
{ "exec": "./bitcoin-tx",
"args":
["-json",
"01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000",
"in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0:1"],
"output_cmp": "txcreatedata_seq1.json"
} }
] ]

10
src/test/data/blanktx.json

@ -0,0 +1,10 @@
{
"txid": "d21633ba23f70118185227be58a63527675641ad37967e2aa461559f577aec43",
"version": 1,
"locktime": 0,
"vin": [
],
"vout": [
],
"hex": "01000000000000000000"
}

216
src/test/data/tt-delin1-out.json

File diff suppressed because one or more lines are too long

212
src/test/data/tt-delout1-out.json

File diff suppressed because one or more lines are too long

225
src/test/data/tt-locktime317000-out.json

File diff suppressed because one or more lines are too long

63
src/test/data/txcreate1.json

@ -0,0 +1,63 @@
{
"txid": "f70f0d6c71416ed538e37549f430ab3665fee2437a42f10238c1bd490e782231",
"version": 1,
"locktime": 0,
"vin": [
{
"txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f",
"vout": 0,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967295
},
{
"txid": "bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c",
"vout": 18,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967295
},
{
"txid": "22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc",
"vout": 1,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 0.18,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"
]
}
},
{
"value": 4.00,
"n": 1,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 f2d4db28cad6502226ee484ae24505c2885cb12d OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a914f2d4db28cad6502226ee484ae24505c2885cb12d88ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"1P8yWvZW8jVihP1bzHeqfE4aoXNX8AVa46"
]
}
}
],
"hex": "01000000031f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff7cca453133921c50d5025878f7f738d1df891fd359763331935784cf6b9c82bf1200000000fffffffffccd319e04a996c96cfc0bf4c07539aa90bd0b1a700ef72fae535d6504f9a6220100000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d717000000001976a914f2d4db28cad6502226ee484ae24505c2885cb12d88ac00000000"
}

19
src/test/data/txcreate2.json

@ -0,0 +1,19 @@
{
"txid": "cf90229625e9eb10f6be8156bf6aa5ec2eca19a42b1e05c11f3029b560a32e13",
"version": 1,
"locktime": 0,
"vin": [
],
"vout": [
{
"value": 0.00,
"n": 0,
"scriptPubKey": {
"asm": "",
"hex": "",
"type": "nonstandard"
}
}
],
"hex": "01000000000100000000000000000000000000"
}

41
src/test/data/txcreatedata1.json

@ -0,0 +1,41 @@
{
"txid": "07894b4d12fe7853dd911402db1620920d261b9627c447f931417d330c25f06e",
"version": 1,
"locktime": 0,
"vin": [
{
"txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f",
"vout": 0,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 0.18,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"
]
}
},
{
"value": 4.00,
"n": 1,
"scriptPubKey": {
"asm": "OP_RETURN 54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e",
"hex": "6a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e",
"type": "nulldata"
}
}
],
"hex": "01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0084d71700000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000"
}

41
src/test/data/txcreatedata2.json

@ -0,0 +1,41 @@
{
"txid": "4ed17118f5e932ba8c75c461787d171bc02a016d8557cb5bcf34cd416c27bb8b",
"version": 1,
"locktime": 0,
"vin": [
{
"txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f",
"vout": 0,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 0.18,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"
]
}
},
{
"value": 0.00,
"n": 1,
"scriptPubKey": {
"asm": "OP_RETURN 54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e",
"hex": "6a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e",
"type": "nulldata"
}
}
],
"hex": "01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000ffffffff0280a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac0000000000000000526a4c4f54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e00000000"
}

32
src/test/data/txcreatedata_seq0.json

@ -0,0 +1,32 @@
{
"txid": "71603ccb1cd76d73d76eb6cfd5f0b9df6d65d90d76860ee52cb461c4be7032e8",
"version": 1,
"locktime": 0,
"vin": [
{
"txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f",
"vout": 0,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967293
}
],
"vout": [
{
"value": 0.18,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"
]
}
}
],
"hex": "01000000011f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff0180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000"
}

41
src/test/data/txcreatedata_seq1.json

@ -0,0 +1,41 @@
{
"txid": "c4dea671b0d7b48f8ab10bc46650e8329d3c5766931f548f513847a19f5ba75b",
"version": 1,
"locktime": 0,
"vin": [
{
"txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f",
"vout": 0,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967293
},
{
"txid": "5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f",
"vout": 0,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 1
}
],
"vout": [
{
"value": 0.18,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"13tuJJDR2RgArmgfv6JScSdreahzgc4T6o"
]
}
}
],
"hex": "01000000021f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000fdffffff1f5c38dfcf6f1a5f5a87c416076d392c87e6d41970d5ad5e477a02d66bde97580000000000010000000180a81201000000001976a9141fc11f39be1729bf973a7ab6a615ca4729d6457488ac00000000"
}

32
src/test/data/txcreatesign.json

@ -0,0 +1,32 @@
{
"txid": "977e7cd286cb72cd470d539ba6cb48400f8f387d97451d45cdb8819437a303af",
"version": 1,
"locktime": 0,
"vin": [
{
"txid": "4d49a71ec9da436f71ec4ee231d04f292a29cd316f598bb7068feccabdc59485",
"vout": 0,
"scriptSig": {
"asm": "304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e2[ALL] 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8",
"hex": "48304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e201410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"
},
"sequence": 4294967295
}
],
"vout": [
{
"value": 0.001,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 5834479edbbe0539b31ffd3a8f8ebadc2165ed01 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"193P6LtvS4nCnkDvM9uXn1gsSRqh4aDAz7"
]
}
}
],
"hex": "01000000018594c5bdcaec8f06b78b596f31cd292a294fd031e24eec716f43dac91ea7494d000000008b48304502210096a75056c9e2cc62b7214777b3d2a592cfda7092520126d4ebfcd6d590c99bd8022051bb746359cf98c0603f3004477eac68701132380db8facba19c89dc5ab5c5e201410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8ffffffff01a0860100000000001976a9145834479edbbe0539b31ffd3a8f8ebadc2165ed0188ac00000000"
}

2
src/wallet/rpcdump.cpp

@ -346,8 +346,6 @@ UniValue removeprunedfunds(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction does not exist in wallet."); throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction does not exist in wallet.");
} }
ThreadFlushWalletDB(pwalletMain->strWalletFile);
return NullUniValue; return NullUniValue;
} }

Loading…
Cancel
Save