From 1cfda206a8b59363a4ed99ad55dd4f97a84b2fd5 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 16 Mar 2017 11:43:06 +0100 Subject: [PATCH 01/20] Merge #9993: Initialize nRelockTime fb6f90a Initialize nRelockTime (Patrick Strateman) Tree-SHA512: 82675ab4b05d5f3ea08a99e85d3f49d18068887d23cbacb5e899ad66799049c5f1d5bd33768dbe153116424c9f0caddaa3622000924e373aa01ac2a54b5f3577 --- src/wallet/wallet.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index fc5e95e05f67..26095893b95f 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -803,6 +803,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface nLastResend = 0; nTimeFirstKey = 0; fBroadcastTransactions = false; + nRelockTime = 0; fAnonymizableTallyCached = false; fAnonymizableTallyCachedNonDenom = false; vecAnonymizableTallyCached.clear(); From 5ae202da9677882b9d9893605c25abc97fea8fd9 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Thu, 16 Mar 2017 11:57:09 +0100 Subject: [PATCH 02/20] Merge #9842: Fix RPC failure testing (continuation of #9707) c9bd0f6 Fix RPC failure testing (2 of 2) (John Newbery) Tree-SHA512: df30e6e85abe8c4e12910dc60699f1201e9c243457abd738c1fdeac45f0ff05c674f68619ad9a47c847ec557954007d672cd89d3a9a3b2398dd188d9ffa6dcc9 s/serialize_with_witness/serialize/ miss a tx_submit -> sendrawtransaction dropped dip4 Fix tests Signed-off-by: Pasta Fix file permissions --- qa/rpc-tests/bip65-cltv.py | 8 +--- qa/rpc-tests/bip68-sequence.py | 46 +++++++--------------- qa/rpc-tests/bipdersig.py | 8 +--- qa/rpc-tests/blockchain.py | 6 +-- qa/rpc-tests/disablewallet.py | 17 ++------ qa/rpc-tests/getblocktemplate_proposals.py | 4 +- qa/rpc-tests/keypool.py | 18 ++------- qa/rpc-tests/mempool_packages.py | 29 ++++++-------- qa/rpc-tests/mempool_reorg.py | 16 +++++--- qa/rpc-tests/mempool_spendcoinbase.py | 2 +- qa/rpc-tests/nulldummy.py | 29 +++++--------- qa/rpc-tests/prioritise_transaction.py | 10 ++--- qa/rpc-tests/rpcbind_test.py | 6 +-- qa/rpc-tests/wallet.py | 20 +++------- 14 files changed, 73 insertions(+), 146 deletions(-) diff --git a/qa/rpc-tests/bip65-cltv.py b/qa/rpc-tests/bip65-cltv.py index c9d02a98f3f4..7f13bb9952f1 100755 --- a/qa/rpc-tests/bip65-cltv.py +++ b/qa/rpc-tests/bip65-cltv.py @@ -69,12 +69,8 @@ def run_test(self): if (self.nodes[0].getblockcount() != cnt + 1051): raise AssertionError("Failed to mine a version=4 block") - # Mine 1 old-version blocks - try: - self.nodes[1].generate(1) - raise AssertionError("Succeeded to mine a version=3 block after 950 version=4 blocks") - except JSONRPCException: - pass + # Mine 1 old-version blocks. This should fail + assert_raises_jsonrpc(-1,"CreateNewBlock: TestBlockValidity failed: bad-version(0x00000003)", self.nodes[1].generate, 1) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 1051): raise AssertionError("Accepted a version=3 block after 950 version=4 blocks") diff --git a/qa/rpc-tests/bip68-sequence.py b/qa/rpc-tests/bip68-sequence.py index c6d11ac9a201..5a628a2fa0bf 100755 --- a/qa/rpc-tests/bip68-sequence.py +++ b/qa/rpc-tests/bip68-sequence.py @@ -90,12 +90,7 @@ def test_disable_flag(self): 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) + assert_raises_jsonrpc(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, ToHex(tx2)) # Setting the version back down to 1 should disable the sequence lock, # so this should be accepted. @@ -190,14 +185,12 @@ def test_sequence_lock_confirmed_inputs(self): 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) + if (using_sequence_locks and not should_pass): + # This transaction should be rejected + assert_raises_jsonrpc(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, rawtx) else: - assert(should_pass or not using_sequence_locks) - # Recalculate utxos if we successfully sent the transaction + # This raw transaction should be accepted + self.nodes[0].sendrawtransaction(rawtx) utxos = self.nodes[0].listunspent() # Test that sequence locks on unconfirmed inputs must have nSequence @@ -239,14 +232,13 @@ def test_nonzero_locks(orig_tx, node, relayfee, use_height_lock): 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()) + if (orig_tx.hash in node.getrawmempool()): + # sendrawtransaction should fail if the tx is in the mempool + assert_raises_jsonrpc(-26, NOT_FINAL_ERROR, node.sendrawtransaction, ToHex(tx)) else: - # orig_tx must not be in mempool - assert(orig_tx.hash not in node.getrawmempool()) + # sendrawtransaction should succeed if the tx is not in the mempool + node.sendrawtransaction(ToHex(tx)) + return tx test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=True) @@ -295,12 +287,7 @@ def test_nonzero_locks(orig_tx, node, relayfee, use_height_lock): 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) + assert_raises_jsonrpc(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, raw_tx5) # Test mempool-BIP68 consistency after reorg # @@ -373,12 +360,7 @@ def test_bip68_not_consensus(self): 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) + assert_raises_jsonrpc(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, ToHex(tx3)) # make a block that violates bip68; ensure that the tip updates tip = int(self.nodes[0].getbestblockhash(), 16) diff --git a/qa/rpc-tests/bipdersig.py b/qa/rpc-tests/bipdersig.py index fa54bc2749f4..371cc41bb714 100755 --- a/qa/rpc-tests/bipdersig.py +++ b/qa/rpc-tests/bipdersig.py @@ -68,12 +68,8 @@ def run_test(self): if (self.nodes[0].getblockcount() != cnt + 1051): raise AssertionError("Failed to mine a version=3 block") - # Mine 1 old-version blocks - try: - self.nodes[1].generate(1) - raise AssertionError("Succeeded to mine a version=2 block after 950 version=3 blocks") - except JSONRPCException: - pass + # Mine 1 old-version blocks. This should fail + assert_raises_jsonrpc(-1, "CreateNewBlock: TestBlockValidity failed: bad-version(0x00000002)", self.nodes[1].generate, 1) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 1051): raise AssertionError("Accepted a version=2 block after 950 version=3 blocks") diff --git a/qa/rpc-tests/blockchain.py b/qa/rpc-tests/blockchain.py index 4896468e03bb..3472841c1795 100755 --- a/qa/rpc-tests/blockchain.py +++ b/qa/rpc-tests/blockchain.py @@ -14,10 +14,9 @@ from decimal import Decimal from test_framework.test_framework import BitcoinTestFramework -from test_framework.authproxy import JSONRPCException from test_framework.util import ( assert_equal, - assert_raises, + assert_raises_jsonrpc, assert_is_hex_string, assert_is_hash_string, start_nodes, @@ -82,8 +81,7 @@ def _test_gettxoutsetinfo(self): def _test_getblockheader(self): node = self.nodes[0] - assert_raises( - JSONRPCException, lambda: node.getblockheader('nonsense')) + assert_raises_jsonrpc(-5, "Block not found", node.getblockheader, "nonsense") besthash = node.getbestblockhash() secondbesthash = node.getblockhash(199) diff --git a/qa/rpc-tests/disablewallet.py b/qa/rpc-tests/disablewallet.py index 633e70125a93..58bf373f0c1b 100755 --- a/qa/rpc-tests/disablewallet.py +++ b/qa/rpc-tests/disablewallet.py @@ -31,19 +31,10 @@ def run_test (self): x = self.nodes[0].validateaddress('ycwedq2f3sz2Yf9JqZsBCQPxp18WU3Hp4J') assert(x['isvalid'] == True) - # Checking mining to an address without a wallet - try: - self.nodes[0].generatetoaddress(1, 'ycwedq2f3sz2Yf9JqZsBCQPxp18WU3Hp4J') - except JSONRPCException as e: - assert("Invalid address" not in e.error['message']) - assert("ProcessNewBlock, block not accepted" not in e.error['message']) - assert("Couldn't create new block" not in e.error['message']) - - try: - self.nodes[0].generatetoaddress(1, '7TSBtVu959hGEGPKyHjJz9k55RpWrPffXz') - raise AssertionError("Must not mine to invalid address!") - except JSONRPCException as e: - assert("Invalid address" in e.error['message']) + # Checking mining to an address without a wallet. Generating to a valid address should succeed + # but generating to an invalid address will fail. + self.nodes[0].generatetoaddress(1, 'ycwedq2f3sz2Yf9JqZsBCQPxp18WU3Hp4J') + assert_raises_jsonrpc(-5, "Invalid address", self.nodes[0].generatetoaddress, 1, '7TSBtVu959hGEGPKyHjJz9k55RpWrPffXz') if __name__ == '__main__': DisableWalletTest ().main () diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py index 8442c545dda7..057b51afe1a8 100755 --- a/qa/rpc-tests/getblocktemplate_proposals.py +++ b/qa/rpc-tests/getblocktemplate_proposals.py @@ -106,7 +106,7 @@ def run_test(self): # Test 3: Truncated final tx lastbyte = txlist[-1].pop() - assert_raises(JSONRPCException, assert_template, node, tmpl, txlist, 'n/a') + assert_raises_jsonrpc(-22, "Block decode failed", assert_template, node, tmpl, txlist, 'n/a') txlist[-1].append(lastbyte) # Test 4: Add an invalid tx to the end (duplicate of gen tx) @@ -127,7 +127,7 @@ def run_test(self): # Test 7: Bad tx count txlist.append(b'') - assert_raises(JSONRPCException, assert_template, node, tmpl, txlist, 'n/a') + assert_raises_jsonrpc(-22, 'Block decode failed', assert_template, node, tmpl, txlist, 'n/a') txlist.pop() # Test 8: Bad bits diff --git a/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py index b4caf79e2dbf..2fdc39dbf72b 100755 --- a/qa/rpc-tests/keypool.py +++ b/qa/rpc-tests/keypool.py @@ -25,11 +25,7 @@ def run_test(self): # Keep creating keys addr = nodes[0].getnewaddress() - try: - addr = nodes[0].getnewaddress() - raise AssertionError('Keypool should be exhausted after one address') - except JSONRPCException as e: - assert(e.error['code']==-12) + assert_raises_jsonrpc(-12, "Error: Keypool ran out, please call keypoolrefill first", nodes[0].getnewaddress) # put three new keys in the keypool nodes[0].walletpassphrase('test', 12000) @@ -44,11 +40,7 @@ def run_test(self): # assert that three unique addresses were returned assert(len(addr) == 3) # the next one should fail - try: - addr = nodes[0].getrawchangeaddress() - raise AssertionError('Keypool should be exhausted after three addresses') - except JSONRPCException as e: - assert(e.error['code']==-12) + assert_raises_jsonrpc(-12, "Keypool ran out", nodes[0].getrawchangeaddress) # refill keypool with three new addresses nodes[0].walletpassphrase('test', 1) @@ -61,11 +53,7 @@ def run_test(self): nodes[0].generate(1) nodes[0].generate(1) nodes[0].generate(1) - try: - nodes[0].generate(1) - raise AssertionError('Keypool should be exhausted after three addesses') - except JSONRPCException as e: - assert(e.error['code']==-12) + assert_raises_jsonrpc(-12, "Keypool ran out", nodes[0].generate, 1) def setup_network(self): self.nodes = start_nodes(1, self.options.tmpdir, [['-usehd=0']]) diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py index d475aabdf821..feec8a7fd923 100755 --- a/qa/rpc-tests/mempool_packages.py +++ b/qa/rpc-tests/mempool_packages.py @@ -124,10 +124,7 @@ def run_test(self): 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: - self.log.info("too-long-ancestor-chain successfully rejected") + assert_raises_jsonrpc(-26, "too-long-mempool-chain", self.chain_transaction, self.nodes[0], txid, vout, value, fee, 1) # Check that prioritising a tx before it's added to the mempool works # First clear the mempool by mining a block. @@ -167,19 +164,19 @@ def run_test(self): for i in range(10): transaction_package.append({'txid': txid, 'vout': i, 'amount': sent_value}) - for i in range(MAX_DESCENDANTS): + # Sign and send up to MAX_DESCENDANT transactions chained off the parent tx + for i in range(MAX_DESCENDANTS - 1): 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 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: - self.log.info(e.error['message']) - assert_equal(i, MAX_DESCENDANTS - 1) - self.log.info("tx that would create too large descendant package successfully rejected") + (txid, sent_value) = self.chain_transaction(self.nodes[0], utxo['txid'], utxo['vout'], utxo['amount'], fee, 10) + for j in range(10): + transaction_package.append({'txid': txid, 'vout': j, 'amount': sent_value}) + + mempool = self.nodes[0].getrawmempool(True) + assert_equal(mempool[parent_transaction]['descendantcount'], MAX_DESCENDANTS) + + # Sending one more chained transaction will fail + utxo = transaction_package.pop(0) + assert_raises_jsonrpc(-26, "too-long-mempool-chain", self.chain_transaction, self.nodes[0], utxo['txid'], utxo['vout'], utxo['amount'], fee, 10) # TODO: check that node1's mempool is as expected diff --git a/qa/rpc-tests/mempool_reorg.py b/qa/rpc-tests/mempool_reorg.py index 9b64610d61d5..07992e838222 100755 --- a/qa/rpc-tests/mempool_reorg.py +++ b/qa/rpc-tests/mempool_reorg.py @@ -30,9 +30,10 @@ def setup_network(self): self.sync_all() def run_test(self): - start_count = self.nodes[0].getblockcount() + # Start with a 200 block chain + assert_equal(self.nodes[0].getblockcount(), 200) - # Mine three blocks. After this, nodes[0] blocks + # Mine four blocks. After this, nodes[0] blocks # 101, 102, and 103 are spend-able. new_blocks = self.nodes[1].generate(4) self.sync_all() @@ -52,19 +53,21 @@ def run_test(self): spend_102_raw = create_tx(self.nodes[0], coinbase_txids[2], node0_address, 499.9) spend_103_raw = create_tx(self.nodes[0], coinbase_txids[3], node0_address, 499.9) - # Create a block-height-locked transaction which will be invalid after reorg + # Create a transaction which is time-locked to two blocks in the future timelock_tx = self.nodes[0].createrawtransaction([{"txid": coinbase_txids[0], "vout": 0}], {node0_address: 499.9}) # Set the time lock timelock_tx = timelock_tx.replace("ffffffff", "11111191", 1) timelock_tx = timelock_tx[:-8] + hex(self.nodes[0].getblockcount() + 2)[2:] + "000000" timelock_tx = self.nodes[0].signrawtransaction(timelock_tx)["hex"] - assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx) + # This will raise an exception because the timelock transaction is too immature to spend + assert_raises_jsonrpc(-26, "non-final", self.nodes[0].sendrawtransaction, timelock_tx) # Broadcast and mine spend_102 and 103: spend_102_id = self.nodes[0].sendrawtransaction(spend_102_raw) spend_103_id = self.nodes[0].sendrawtransaction(spend_103_raw) self.nodes[0].generate(1) - assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx) + # Time-locked transaction is still too immature to spend + assert_raises_jsonrpc(-26,'non-final', self.nodes[0].sendrawtransaction, timelock_tx) # Create 102_1 and 103_1: spend_102_1_raw = create_tx(self.nodes[0], spend_102_id, node1_address, 499.8) @@ -73,6 +76,7 @@ def run_test(self): # Broadcast and mine 103_1: spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw) last_block = self.nodes[0].generate(1) + # Time-locked transaction can now be spent timelock_tx_id = self.nodes[0].sendrawtransaction(timelock_tx) # ... now put spend_101 and spend_102_1 in memory pools: @@ -85,6 +89,8 @@ def run_test(self): for node in self.nodes: node.invalidateblock(last_block[0]) + # Time-locked transaction is now too immature and has been removed from the mempool + # spend_103_1 has been re-orged out of the chain and is back in the mempool 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 diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py index 88c4a44cc222..08ca626e71a8 100755 --- a/qa/rpc-tests/mempool_spendcoinbase.py +++ b/qa/rpc-tests/mempool_spendcoinbase.py @@ -45,7 +45,7 @@ def run_test(self): spend_101_id = self.nodes[0].sendrawtransaction(spends_raw[0]) # coinbase at height 102 should be too immature to spend - assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, spends_raw[1]) + assert_raises_jsonrpc(-26,"bad-txns-premature-spend-of-coinbase", self.nodes[0].sendrawtransaction, spends_raw[1], False, False, True) # mempool should have just spend_101: assert_equal(self.nodes[0].getrawmempool(), [ spend_101_id ]) diff --git a/qa/rpc-tests/nulldummy.py b/qa/rpc-tests/nulldummy.py index 22d1f63e01b7..5dd3e65b8309 100755 --- a/qa/rpc-tests/nulldummy.py +++ b/qa/rpc-tests/nulldummy.py @@ -63,29 +63,29 @@ def run_test(self): self.log.info("Test 1: NULLDUMMY compliant base transactions should be accepted to mempool and mined before activation [430]") test1txs = [self.create_transaction(self.nodes[0], coinbase_txid[0], self.ms_address, 49)] - txid1 = self.tx_submit(self.nodes[0], test1txs[0]) + txid1 = self.nodes[0].sendrawtransaction(bytes_to_hex_str(test1txs[0].serialize()), True) test1txs.append(self.create_transaction(self.nodes[0], txid1, self.ms_address, 48)) - txid2 = self.tx_submit(self.nodes[0], test1txs[1]) + txid2 = self.nodes[0].sendrawtransaction(bytes_to_hex_str(test1txs[1].serialize()), True) self.block_submit(self.nodes[0], test1txs, True) self.log.info("Test 2: Non-NULLDUMMY base multisig transaction should not be accepted to mempool before activation") test2tx = self.create_transaction(self.nodes[0], txid2, self.ms_address, 47) trueDummy(test2tx) - txid4 = self.tx_submit(self.nodes[0], test2tx, NULLDUMMY_ERROR) + assert_raises_jsonrpc(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, bytes_to_hex_str(test2tx.serialize()), True) self.log.info("Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [431]") self.block_submit(self.nodes[0], [test2tx], True) - self.log.info("Test 4: Non-NULLDUMMY base multisig transaction is invalid after activation") - test4tx = self.create_transaction(self.nodes[0], txid4, self.address, 46) + self.log.info ("Test 4: Non-NULLDUMMY base multisig transaction is invalid after activation") + test4tx = self.create_transaction(self.nodes[0], test2tx.hash, self.address, 46) test6txs=[CTransaction(test4tx)] trueDummy(test4tx) - self.tx_submit(self.nodes[0], test4tx, NULLDUMMY_ERROR) + assert_raises_jsonrpc(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, bytes_to_hex_str(test4tx.serialize()), True) self.block_submit(self.nodes[0], [test4tx]) self.log.info("Test 6: NULLDUMMY compliant transactions should be accepted to mempool and in block after activation [432]") for i in test6txs: - self.tx_submit(self.nodes[0], i) + self.nodes[0].sendrawtransaction(bytes_to_hex_str(i.serialize()), True) self.block_submit(self.nodes[0], test6txs, True) @@ -100,19 +100,8 @@ def create_transaction(self, node, txid, to_address, amount): return tx - def tx_submit(self, node, tx, msg = ""): - tx.rehash() - try: - node.sendrawtransaction(bytes_to_hex_str(tx.serialize()), True) - except JSONRPCException as exp: - assert_equal(exp.error["message"], msg) - else: - assert_equal('', msg) - return tx.hash - - - def block_submit(self, node, txs, accept = False): - dip4_activated = self.lastblockheight + 1 >= 432 + def block_submit(self, node, txs, witness = False, accept = False): + dip4_activated = self.lastblockheight + 1 >= 432 block = create_block(self.tip, create_coinbase(self.lastblockheight + 1, dip4_activated=dip4_activated), self.lastblocktime + 1) block.nVersion = 4 for tx in txs: diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py index c503f3e12107..f8fb1e7a269e 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -109,13 +109,9 @@ def run_test(self): tx_hex = self.nodes[0].signrawtransaction(raw_tx)["hex"] tx_id = self.nodes[0].decoderawtransaction(tx_hex)["txid"] - try: - self.nodes[0].sendrawtransaction(tx_hex) - except JSONRPCException as exp: - assert_equal(exp.error['code'], -26) # insufficient fee - assert(tx_id not in self.nodes[0].getrawmempool()) - else: - assert(False) + # This will raise an exception due to min relay fee not being met + assert_raises_jsonrpc(-26, "66: min relay fee not met", self.nodes[0].sendrawtransaction, tx2_hex) + assert(tx2_id not in self.nodes[0].getrawmempool()) # 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 diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py index 220bf4ddd072..8720a345cea5 100755 --- a/qa/rpc-tests/rpcbind_test.py +++ b/qa/rpc-tests/rpcbind_test.py @@ -92,11 +92,7 @@ def run_test(self): # Check that with invalid rpcallowip, we are denied self.run_allowip_test([non_loopback_ip], non_loopback_ip, defaultport) - try: - self.run_allowip_test(['1.1.1.1'], non_loopback_ip, defaultport) - assert(not 'Connection not denied by rpcallowip as expected') - except JSONRPCException: - pass + assert_raises_jsonrpc(-342, "non-JSON HTTP response with '403 Forbidden' from server", self.run_allowip_test, ['1.1.1.1'], non_loopback_ip, defaultport) if __name__ == '__main__': RPCBindTest().main() diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index c43447b99950..70c1b61ba67a 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -72,7 +72,7 @@ def run_test (self): unspent_0 = self.nodes[2].listunspent()[0] unspent_0 = {"txid": unspent_0["txid"], "vout": unspent_0["vout"]} self.nodes[2].lockunspent(False, [unspent_0]) - assert_raises_message(JSONRPCException, "Insufficient funds", self.nodes[2].sendtoaddress, self.nodes[2].getnewaddress(), 200) + assert_raises_jsonrpc(-4, "Insufficient funds", self.nodes[2].sendtoaddress, self.nodes[2].getnewaddress(), 200) assert_equal([unspent_0], self.nodes[2].listlockunspent()) self.nodes[2].lockunspent(True, [unspent_0]) assert_equal(len(self.nodes[2].listlockunspent()), 0) @@ -255,19 +255,11 @@ def run_test (self): txObj = self.nodes[0].gettransaction(txId) assert_equal(txObj['amount'], Decimal('-0.0001')) - try: - txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1f-4") - except JSONRPCException as e: - assert("Invalid amount" in e.error['message']) - else: - raise AssertionError("Must not parse invalid amounts") + # This will raise an exception because the amount type is wrong + assert_raises_jsonrpc(-3, "Invalid amount", self.nodes[0].sendtoaddress, self.nodes[2].getnewaddress(), "1f-4") - - try: - self.nodes[0].generate("2") - raise AssertionError("Must not accept strings as numeric") - except JSONRPCException as e: - assert("not an integer" in e.error['message']) + # This will raise an exception since generate does not accept a string + assert_raises_jsonrpc(-1, "not an integer", self.nodes[0].generate, "2") # Import address and private key to check correct behavior of spendable unspents # 1. Send some coins to generate new UTXO @@ -398,7 +390,7 @@ def run_test (self): node0_balance = self.nodes[0].getbalance() # With walletrejectlongchains we will not create the tx and store it in our wallet. - assert_raises_message(JSONRPCException, "mempool chain", self.nodes[0].sendtoaddress, sending_addr, node0_balance - Decimal('0.01')) + assert_raises_jsonrpc(-4, "Transaction has too long of a mempool chain", self.nodes[0].sendtoaddress, sending_addr, node0_balance - Decimal('0.01')) # Verify nothing new in wallet assert_equal(total_txs, len(self.nodes[0].listtransactions("*",99999))) From 594b78fdf5dcb31b7c93b89839de066648c68cb7 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 16 Mar 2017 12:02:54 +0100 Subject: [PATCH 03/20] Merge #9921: build: Probe MSG_DONTWAIT in the same way as MSG_NOSIGNAL a4d1c9f compat: use `unsigned int` instead of `u_int` (Wladimir J. van der Laan) 25da1ee build: cleanup: define MSG_DONTWAIT/MSG_NO_SIGNAL locally (Wladimir J. van der Laan) c459d50 build: Probe MSG_DONTWAIT in the same way as MSG_NOSIGNAL (Wladimir J. van der Laan) Tree-SHA512: 60d79d69439bb181465e4244aa5ddc28bbd84f69c0ca0c753956b3798c9022394e29d791bc085fe7ffb1268c64c789a57e24797daad63525bb776088188ff9ae fix merge error in configure.ac Signed-off-by: Pasta --- configure.ac | 8 ++++++++ src/compat.h | 11 ++--------- src/net.cpp | 7 ++++++- src/netbase.cpp | 2 +- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index e07ba70292f8..830c3ba88213 100644 --- a/configure.ac +++ b/configure.ac @@ -603,6 +603,14 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [ AC_MSG_RESULT(no)] ) +dnl Check for MSG_DONTWAIT +AC_MSG_CHECKING(for MSG_DONTWAIT) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[ int f = MSG_DONTWAIT; ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_DONTWAIT, 1,[Define this symbol if you have MSG_DONTWAIT]) ], + [ AC_MSG_RESULT(no)] +) + dnl Check for mallopt(M_ARENA_MAX) (to set glibc arenas) AC_MSG_CHECKING(for mallopt M_ARENA_MAX) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], diff --git a/src/compat.h b/src/compat.h index 2e9663b8d63f..7c7b0b3d7301 100644 --- a/src/compat.h +++ b/src/compat.h @@ -47,10 +47,8 @@ #include #endif -#ifdef WIN32 -#define MSG_DONTWAIT 0 -#else -typedef u_int SOCKET; +#ifndef WIN32 +typedef unsigned int SOCKET; #include "errno.h" #define WSAGetLastError() errno #define WSAEINVAL EINVAL @@ -74,11 +72,6 @@ typedef u_int SOCKET; #define MAX_PATH 1024 #endif -// As Solaris does not have the MSG_NOSIGNAL flag for send(2) syscall, it is defined as 0 -#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL) -#define MSG_NOSIGNAL 0 -#endif - #if HAVE_DECL_STRNLEN == 0 size_t strnlen( const char *start, size_t max_len); #endif // HAVE_DECL_STRNLEN diff --git a/src/net.cpp b/src/net.cpp index 79ca7982972c..00cab7b419b5 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -52,10 +52,15 @@ // We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization. #define FEELER_SLEEP_WINDOW 1 -#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL) +#if !defined(HAVE_MSG_NOSIGNAL) #define MSG_NOSIGNAL 0 #endif +// MSG_DONTWAIT is not available on some platforms, if it doesn't exist define it as 0 +#if !defined(HAVE_MSG_DONTWAIT) +#define MSG_DONTWAIT 0 +#endif + // Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h. // Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version. #ifdef WIN32 diff --git a/src/netbase.cpp b/src/netbase.cpp index 03e336c3deff..90a087f7e8d7 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -25,7 +25,7 @@ #include // for to_lower() #include // for startswith() and endswith() -#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL) +#if !defined(HAVE_MSG_NOSIGNAL) #define MSG_NOSIGNAL 0 #endif From ae9ca8459d83a66aa1b81ae541a8bfb83afc9fa0 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 17 Mar 2017 10:28:50 +0100 Subject: [PATCH 04/20] Merge #10010: util: rename variable to avoid shadowing 9350e13 util: rename variable to avoid shadowing (Pavol Rusnak) Tree-SHA512: 8abc09fdb134c913e823754f3f02a4d8ef120a73f252fbc1217dbd2bdd4ed4fffce92d823a66d1fe51607dc021065df8826f21274ef26e55d82575e96d07224f --- src/util.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/util.h b/src/util.h index eda300bdeec9..aa303761d9de 100644 --- a/src/util.h +++ b/src/util.h @@ -40,7 +40,7 @@ #ifdef ENABLE_DASH_DEBUG #define DBG( x ) x #else -#define DBG( x ) +#define DBG( x ) #endif //Dash only features @@ -103,8 +103,8 @@ std::string SafeStringFormat(const std::string& fmt, const Args&... args) { try { return tinyformat::format(fmt, args...); - } catch (std::runtime_error& e) { - std::string message = tinyformat::format("\n****TINYFORMAT ERROR****\n err=\"%s\"\n fmt=\"%s\"\n", e.what(), fmt); + } catch (std::runtime_error& fmterr) { + std::string message = tinyformat::format("\n****TINYFORMAT ERROR****\n err=\"%s\"\n fmt=\"%s\"\n", fmterr.what(), fmt); fprintf(stderr, "%s", message.c_str()); return message; } From aee4472acef828fabbc95af02388c6d0bb832707 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 17 Mar 2017 14:30:48 +0100 Subject: [PATCH 05/20] Merge #9974: Add basic Qt wallet test 9576b01 Enable xvfb in travis to allow running test_bitcoin-qt (Russell Yanofsky) 9e6817e Add new test_bitcoin-qt static library dependencies (Russell Yanofsky) 2754ef1 Add simple qt wallet test sending a transaction (Russell Yanofsky) b61b34c Add braces to if statements in Qt test_main (Russell Yanofsky) cc9503c Make qt test compatible with TestChain100Setup framework (Russell Yanofsky) 91e3035 Make test_bitcoin.cpp compatible with Qt Test framework (Russell Yanofsky) Tree-SHA512: da491181848b8c39138e997ae5ff2df0b16eef2d9cdd0a965229b1a28d4fa862d5f1ef314a1736e5050e88858f329124d15c689659fc6e50fefde769ba24e523 remove line, testing bitcoin -> dash, testing bitcoin -> dash, testing resolve name conflict, testing bitcoin -> dash re-add test fixture line code review, fix tests Signed-off-by: Pasta move ExceptionInitializer into test_dash_main.cpp remove witness from nulldummy.py Signed-off-by: Pasta change error text to match expected Signed-off-by: Pasta --- ci/matrix.sh | 2 +- ci/test_unittests.sh | 6 ++ qa/rpc-tests/nulldummy.py | 2 +- qa/rpc-tests/prioritise_transaction.py | 2 +- src/Makefile.qttest.include | 24 ++++-- src/Makefile.test.include | 1 + src/qt/test/rpcnestedtests.cpp | 4 + src/qt/test/test_main.cpp | 45 +++++++---- src/qt/test/wallettests.cpp | 104 +++++++++++++++++++++++++ src/qt/test/wallettests.h | 15 ++++ src/test/test_dash.cpp | 60 ++------------ src/test/test_dash_main.cpp | 58 ++++++++++++++ 12 files changed, 247 insertions(+), 76 deletions(-) create mode 100644 src/qt/test/wallettests.cpp create mode 100644 src/qt/test/wallettests.h create mode 100644 src/test/test_dash_main.cpp diff --git a/ci/matrix.sh b/ci/matrix.sh index 5afcbee0b549..91ce9658c026 100755 --- a/ci/matrix.sh +++ b/ci/matrix.sh @@ -66,7 +66,7 @@ elif [ "$BUILD_TARGET" = "linux64" ]; then export RUN_TESTS=true elif [ "$BUILD_TARGET" = "linux64_nowallet" ]; then export HOST=x86_64-unknown-linux-gnu - export PACKAGES="python3" + export PACKAGES="python3 xvfb" export DEP_OPTS="NO_WALLET=1" export BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" elif [ "$BUILD_TARGET" = "linux64_release" ]; then diff --git a/ci/test_unittests.sh b/ci/test_unittests.sh index f5af7e39637e..9b0516a5517b 100755 --- a/ci/test_unittests.sh +++ b/ci/test_unittests.sh @@ -19,6 +19,12 @@ export WINEDEBUG=fixme-all export BOOST_TEST_LOG_LEVEL=test_suite cd build-ci/dashcore-$BUILD_TARGET + +if [ "$RUN_TESTS" = "true" -a "${DEP_OPTS#*NO_QT=1}" = "$DEP_OPTS" ]; then + export DISPLAY=:99.0; + /sbin/start-stop-daemon --start --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac; +fi + if [ "$DIRECT_WINE_EXEC_TESTS" = "true" ]; then # Inside Docker, binfmt isn't working so we can't trust in make invoking windows binaries correctly wine ./src/test/test_dash.exe diff --git a/qa/rpc-tests/nulldummy.py b/qa/rpc-tests/nulldummy.py index 5dd3e65b8309..492f358e1aae 100755 --- a/qa/rpc-tests/nulldummy.py +++ b/qa/rpc-tests/nulldummy.py @@ -100,7 +100,7 @@ def create_transaction(self, node, txid, to_address, amount): return tx - def block_submit(self, node, txs, witness = False, accept = False): + def block_submit(self, node, txs, accept = False): dip4_activated = self.lastblockheight + 1 >= 432 block = create_block(self.tip, create_coinbase(self.lastblockheight + 1, dip4_activated=dip4_activated), self.lastblocktime + 1) block.nVersion = 4 diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py index f8fb1e7a269e..ac74ca73a923 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -110,7 +110,7 @@ def run_test(self): tx_id = self.nodes[0].decoderawtransaction(tx_hex)["txid"] # This will raise an exception due to min relay fee not being met - assert_raises_jsonrpc(-26, "66: min relay fee not met", self.nodes[0].sendrawtransaction, tx2_hex) + assert_raises_jsonrpc(-26, "66: insufficient priority", self.nodes[0].sendrawtransaction, tx2_hex) assert(tx2_id not in self.nodes[0].getrawmempool()) # This is a less than 1000-byte transaction, so just set the fee diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index efca183cb6e6..63324be321eb 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -10,10 +10,12 @@ TEST_QT_MOC_CPP = \ qt/test/moc_compattests.cpp \ qt/test/moc_rpcnestedtests.cpp \ qt/test/moc_trafficgraphdatatests.cpp \ - qt/test/moc_uritests.cpp + qt/test/moc_uritests.cpp if ENABLE_WALLET -TEST_QT_MOC_CPP += qt/test/moc_paymentservertests.cpp +TEST_QT_MOC_CPP += \ + qt/test/moc_paymentservertests.cpp \ + qt/test/moc_wallettests.cpp endif TEST_QT_H = \ @@ -22,7 +24,16 @@ TEST_QT_H = \ qt/test/uritests.h \ qt/test/paymentrequestdata.h \ qt/test/paymentservertests.h \ - qt/test/trafficgraphdatatests.h + qt/test/trafficgraphdatatests.h \ + qt/test/wallettests.h + +TEST_BITCOIN_CPP = \ + test/test_dash.cpp \ + test/testutil.cpp + +TEST_BITCOIN_H = \ + test/test_dash.h \ + test/testutil.h qt_test_test_dash_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ $(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS) @@ -33,10 +44,13 @@ qt_test_test_dash_qt_SOURCES = \ qt/test/test_main.cpp \ qt/test/uritests.cpp \ qt/test/trafficgraphdatatests.cpp \ - $(TEST_QT_H) + $(TEST_QT_H) \ + $(TEST_BITCOIN_CPP) \ + $(TEST_BITCOIN_H) if ENABLE_WALLET qt_test_test_dash_qt_SOURCES += \ - qt/test/paymentservertests.cpp + qt/test/paymentservertests.cpp \ + qt/test/wallettests.cpp endif nodist_qt_test_test_dash_qt_SOURCES = $(TEST_QT_MOC_CPP) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index b7285e91a899..cd56343a29c3 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -129,6 +129,7 @@ BITCOIN_TESTS =\ test/subsidy_tests.cpp \ test/test_dash.cpp \ test/test_dash.h \ + test/test_dash_main.cpp \ test/test_random.h \ test/testutil.cpp \ test/testutil.h \ diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp index d85da3d46cd6..30b9c9233072 100644 --- a/src/qt/test/rpcnestedtests.cpp +++ b/src/qt/test/rpcnestedtests.cpp @@ -155,11 +155,15 @@ void RPCNestedTests::rpcNestedTests() QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest(abc,,)"), std::runtime_error); //don't tollerate empty arguments when using , #endif + UnloadBlockIndex(); delete pcoinsTip; + pcoinsTip = nullptr; llmq::DestroyLLMQSystem(); delete deterministicMNManager; delete pcoinsdbview; + pcoinsdbview = nullptr; delete pblocktree; + pblocktree = nullptr; delete evoDb; boost::filesystem::remove_all(boost::filesystem::path(path)); diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index 3bc073b13d7c..c73459b3aa58 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -8,7 +8,6 @@ #endif #include "chainparams.h" -#include "key.h" #include "rpcnestedtests.h" #include "util.h" #include "uritests.h" @@ -17,20 +16,31 @@ #ifdef ENABLE_WALLET #include "paymentservertests.h" +#include "wallettests.h" #endif -#include +#include #include #include #include -#if defined(QT_STATICPLUGIN) && QT_VERSION < 0x050000 +#if defined(QT_STATICPLUGIN) #include +#if QT_VERSION < 0x050000 Q_IMPORT_PLUGIN(qcncodecs) Q_IMPORT_PLUGIN(qjpcodecs) Q_IMPORT_PLUGIN(qtwcodecs) Q_IMPORT_PLUGIN(qkrcodecs) +#else +#if defined(QT_QPA_PLATFORM_XCB) +Q_IMPORT_PLUGIN(QXcbIntegrationPlugin); +#elif defined(QT_QPA_PLATFORM_WINDOWS) +Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin); +#elif defined(QT_QPA_PLATFORM_COCOA) +Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin); +#endif +#endif #endif extern void noui_connect(); @@ -38,7 +48,6 @@ extern void noui_connect(); // This is all you need to run all the tests int main(int argc, char *argv[]) { - ECC_Start(); SetupEnvironment(); SetupNetworking(); SelectParams(CBaseChainParams::MAIN); @@ -47,31 +56,39 @@ int main(int argc, char *argv[]) bool fInvalid = false; // Don't remove this, it's needed to access - // QCoreApplication:: in the tests - QCoreApplication app(argc, argv); + // QApplication:: and QCoreApplication:: in the tests + QApplication app(argc, argv); app.setApplicationName("Dash-Qt-test"); SSL_library_init(); URITests test1; - if (QTest::qExec(&test1) != 0) + if (QTest::qExec(&test1) != 0) { fInvalid = true; + } #ifdef ENABLE_WALLET PaymentServerTests test2; - if (QTest::qExec(&test2) != 0) + if (QTest::qExec(&test2) != 0) { fInvalid = true; + } #endif RPCNestedTests test3; - if (QTest::qExec(&test3) != 0) + if (QTest::qExec(&test3) != 0) { fInvalid = true; - + } CompatTests test4; - if (QTest::qExec(&test4) != 0) + if (QTest::qExec(&test4) != 0) { fInvalid = true; + } +#ifdef ENABLE_WALLET + WalletTests test5; + if (QTest::qExec(&test5) != 0) { + fInvalid = true; + } +#endif - TrafficGraphDataTests test5; - if (QTest::qExec(&test5) != 0) + TrafficGraphDataTests test6; + if (QTest::qExec(&test6) != 0) fInvalid = true; - ECC_Stop(); return fInvalid; } diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp new file mode 100644 index 000000000000..79c685582801 --- /dev/null +++ b/src/qt/test/wallettests.cpp @@ -0,0 +1,104 @@ +#include "wallettests.h" + +#include "qt/bitcoinamountfield.h" +#include "qt/optionsmodel.h" +#include "qt/platformstyle.h" +#include "qt/qvalidatedlineedit.h" +#include "qt/sendcoinsdialog.h" +#include "qt/sendcoinsentry.h" +#include "qt/transactiontablemodel.h" +#include "qt/walletmodel.h" +#include "test/test_dash.h" +#include "validation.h" +#include "wallet/wallet.h" + +#include +#include +#include +#include + +namespace +{ +//! Press "Yes" button in modal send confirmation dialog. +void ConfirmSend() +{ + QTimer::singleShot(0, Qt::PreciseTimer, []() { + for (QWidget* widget : QApplication::topLevelWidgets()) { + if (widget->inherits("SendConfirmationDialog")) { + SendConfirmationDialog* dialog = qobject_cast(widget); + QAbstractButton* button = dialog->button(QMessageBox::Yes); + button->setEnabled(true); + button->click(); + } + } + }); +} + +//! Send coins to address and return txid. +uint256 SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CBitcoinAddress& address, CAmount amount) +{ + QVBoxLayout* entries = sendCoinsDialog.findChild("entries"); + SendCoinsEntry* entry = qobject_cast(entries->itemAt(0)->widget()); + entry->findChild("payTo")->setText(QString::fromStdString(address.ToString())); + entry->findChild("payAmount")->setValue(amount); + uint256 txid; + boost::signals2::scoped_connection c = wallet.NotifyTransactionChanged.connect([&txid](CWallet*, const uint256& hash, ChangeType status) { + if (status == CT_NEW) txid = hash; + }); + ConfirmSend(); + QMetaObject::invokeMethod(&sendCoinsDialog, "on_sendButton_clicked"); + return txid; +} + +//! Find index of txid in transaction list. +QModelIndex FindTx(const QAbstractItemModel& model, const uint256& txid) +{ + QString hash = QString::fromStdString(txid.ToString()); + int rows = model.rowCount({}); + for (int row = 0; row < rows; ++row) { + QModelIndex index = model.index(row, 0, {}); + if (model.data(index, TransactionTableModel::TxHashRole) == hash) { + return index; + } + } + return {}; +} +} + +//! Simple qt wallet tests. +void WalletTests::walletTests() +{ + // Set up wallet and chain with 101 blocks (1 mature block for spending). + TestChain100Setup test; + test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey())); + bitdb.MakeMock(); + CWallet wallet("wallet_test.dat"); + bool firstRun; + wallet.LoadWallet(firstRun); + { + LOCK(wallet.cs_wallet); + wallet.SetAddressBook(test.coinbaseKey.GetPubKey().GetID(), "", "receive"); + wallet.AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey()); + } + wallet.ScanForWalletTransactions(chainActive.Genesis(), true); + wallet.SetBroadcastTransactions(true); + + // Create widgets for sending coins and listing transactions. + std::unique_ptr platformStyle(PlatformStyle::instantiate("other")); + SendCoinsDialog sendCoinsDialog(platformStyle.get()); + OptionsModel optionsModel; + WalletModel walletModel(platformStyle.get(), &wallet, &optionsModel); + sendCoinsDialog.setModel(&walletModel); + + // Send two transactions, and verify they are added to transaction list. + TransactionTableModel* transactionTableModel = walletModel.getTransactionTableModel(); + QCOMPARE(transactionTableModel->rowCount({}), 101); + uint256 txid1 = SendCoins(wallet, sendCoinsDialog, CBitcoinAddress(CKeyID()), 5 * COIN); + uint256 txid2 = SendCoins(wallet, sendCoinsDialog, CBitcoinAddress(CKeyID()), 10 * COIN); + QCOMPARE(transactionTableModel->rowCount({}), 103); + QVERIFY(FindTx(*transactionTableModel, txid1).isValid()); + QVERIFY(FindTx(*transactionTableModel, txid2).isValid()); + + bitdb.Flush(true); + bitdb.Reset(); +} diff --git a/src/qt/test/wallettests.h b/src/qt/test/wallettests.h new file mode 100644 index 000000000000..342f7916c30b --- /dev/null +++ b/src/qt/test/wallettests.h @@ -0,0 +1,15 @@ +#ifndef BITCOIN_QT_TEST_WALLETTESTS_H +#define BITCOIN_QT_TEST_WALLETTESTS_H + +#include +#include + +class WalletTests : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void walletTests(); +}; + +#endif // BITCOIN_QT_TEST_WALLETTESTS_H diff --git a/src/test/test_dash.cpp b/src/test/test_dash.cpp index e57f10dc62aa..73b96f55fcff 100644 --- a/src/test/test_dash.cpp +++ b/src/test/test_dash.cpp @@ -2,8 +2,6 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#define BOOST_TEST_MODULE Dash Test Suite - #include "test_dash.h" #include "chainparams.h" @@ -21,7 +19,6 @@ #include "rpc/server.h" #include "rpc/register.h" #include "script/sigcache.h" -#include "stacktraces.h" #include "test/testutil.h" @@ -33,11 +30,8 @@ #include #include -#include -#include #include -std::unique_ptr g_connman; FastRandomContext insecure_rand_ctx(true); extern bool fPrintToConsole; @@ -84,11 +78,14 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha pcoinsdbview = new CCoinsViewDB(1 << 23, true); llmq::InitLLMQSystem(*evoDb, nullptr, true); pcoinsTip = new CCoinsViewCache(pcoinsdbview); - BOOST_REQUIRE(InitBlockIndex(chainparams)); + if (!InitBlockIndex(chainparams)) { + throw std::runtime_error("InitBlockIndex failed."); + } { CValidationState state; - bool ok = ActivateBestChain(state, chainparams); - BOOST_REQUIRE(ok); + if (!ActivateBestChain(state, chainparams)) { + throw std::runtime_error("ActivateBestChain failed."); + } } nScriptCheckThreads = 3; for (int i=0; i < nScriptCheckThreads-1; i++) @@ -215,48 +212,3 @@ CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransaction &txn) { return CTxMemPoolEntry(MakeTransactionRef(txn), nFee, nTime, nHeight, spendsCoinbase, sigOpCount, lp); } - -void Shutdown(void* parg) -{ - exit(EXIT_SUCCESS); -} - -void StartShutdown() -{ - exit(EXIT_SUCCESS); -} - -bool ShutdownRequested() -{ - return false; -} - -template -void translate_exception(const T &e) -{ - std::cerr << GetPrettyExceptionStr(std::current_exception()) << std::endl; - throw; -} - -template -void register_exception_translator() -{ - boost::unit_test::unit_test_monitor.register_exception_translator(&translate_exception); -} - -struct ExceptionInitializer { - ExceptionInitializer() - { - RegisterPrettyTerminateHander(); - RegisterPrettySignalHandlers(); - - register_exception_translator(); - register_exception_translator(); - register_exception_translator(); - } - ~ExceptionInitializer() - { - } -}; - -BOOST_GLOBAL_FIXTURE( ExceptionInitializer ); diff --git a/src/test/test_dash_main.cpp b/src/test/test_dash_main.cpp new file mode 100644 index 000000000000..802aaa83a506 --- /dev/null +++ b/src/test/test_dash_main.cpp @@ -0,0 +1,58 @@ +// Copyright (c) 2011-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. + +#define BOOST_TEST_MODULE Bitcoin Test Suite + +#include "net.h" +#include "stacktraces.h" + +#include +#include + +std::unique_ptr g_connman; + +void Shutdown(void* parg) +{ + exit(EXIT_SUCCESS); +} + +void StartShutdown() +{ + exit(EXIT_SUCCESS); +} + +bool ShutdownRequested() +{ + return false; +} + +template +void translate_exception(const T &e) +{ + std::cerr << GetPrettyExceptionStr(std::current_exception()) << std::endl; + throw; +} + +template +void register_exception_translator() +{ + boost::unit_test::unit_test_monitor.register_exception_translator(&translate_exception); +} + +struct ExceptionInitializer { + ExceptionInitializer() + { + RegisterPrettyTerminateHander(); + RegisterPrettySignalHandlers(); + + register_exception_translator(); + register_exception_translator(); + register_exception_translator(); + } + ~ExceptionInitializer() + { + } +}; + +BOOST_GLOBAL_FIXTURE(ExceptionInitializer); From 8e0968faf76bba1d479890efc383710f56295c3c Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 17 Mar 2017 14:44:29 +0100 Subject: [PATCH 06/20] Merge #9690: Change 'Clear' button string to 'Reset' 9155241 Change 'Clear' button string to 'Reset' (Daniel Aleksandersen) Tree-SHA512: 9d68aaaeef88f174b29bffced81f3b2cb6a76f7a2dd8c43df4d9bd5d29cdbcf073c1f250c6bdfad12540976b1bb27a764e5033d219a1491f27f4d89ddd06e49b --- src/qt/forms/debugwindow.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index cd60a440aae5..0710120a39a1 100644 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -659,7 +659,7 @@ - &Clear + &Reset false From 6376da03fa0693296960aa813cfef2fdfaeacdd5 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 17 Mar 2017 20:34:55 +0100 Subject: [PATCH 07/20] Merge #9818: Save watch only key timestamps when reimporting keys 7759aa2 Save watch only key timestamps when reimporting keys (Russell Yanofsky) Tree-SHA512: 433b5a78e5626fb2f3166e6c84c22eabd5239d451dc82694da95af237e034612a24f1a8bc959b7d2f2e576ce0b679be1fa4af929ebfae758c7e832056ab67061 --- qa/rpc-tests/importmulti.py | 19 +++++++++++++++++++ src/wallet/rpcdump.cpp | 10 +++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/qa/rpc-tests/importmulti.py b/qa/rpc-tests/importmulti.py index 298b6e9b86ae..ca5d42eced8d 100755 --- a/qa/rpc-tests/importmulti.py +++ b/qa/rpc-tests/importmulti.py @@ -314,6 +314,7 @@ def run_test (self): self.nodes[1].generate(100) transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00) self.nodes[1].generate(1) + timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime'] transaction = self.nodes[1].gettransaction(transactionid) self.log.info("Should import a p2sh with respective redeem script and private keys") @@ -409,6 +410,24 @@ def run_test (self): assert_equal(address_assert['ismine'], False) assert_equal('timestamp' in address_assert, False) + + # Importing existing watch only address with new timestamp should replace saved timestamp. + assert_greater_than(timestamp, watchonly_timestamp) + print("Should replace previously saved watch only timestamp.") + result = self.nodes[1].importmulti([{ + "scriptPubKey": { + "address": watchonly_address, + }, + "timestamp": "now", + }]) + assert_equal(result[0]['success'], True) + address_assert = self.nodes[1].validateaddress(watchonly_address) + assert_equal(address_assert['iswatchonly'], True) + assert_equal(address_assert['ismine'], False) + assert_equal(address_assert['timestamp'], timestamp) + watchonly_timestamp = timestamp + + # restart nodes to check for proper serialization/deserialization of watch only address stop_nodes(self.nodes) self.nodes = start_nodes(2, self.options.tmpdir) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 10e6127b4382..a054c09f465b 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -958,7 +958,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6 pwallet->MarkDirty(); - if (!pwallet->HaveWatchOnly(redeemScript) && !pwallet->AddWatchOnly(redeemScript, timestamp)) { + if (!pwallet->AddWatchOnly(redeemScript, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -975,7 +975,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6 pwallet->MarkDirty(); - if (!pwallet->HaveWatchOnly(redeemDestination) && !pwallet->AddWatchOnly(redeemDestination, timestamp)) { + if (!pwallet->AddWatchOnly(redeemDestination, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -1068,7 +1068,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6 pwallet->MarkDirty(); - if (!pwallet->HaveWatchOnly(pubKeyScript) && !pwallet->AddWatchOnly(pubKeyScript, timestamp)) { + if (!pwallet->AddWatchOnly(pubKeyScript, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -1086,7 +1086,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6 pwallet->MarkDirty(); - if (!pwallet->HaveWatchOnly(scriptRawPubKey) && !pwallet->AddWatchOnly(scriptRawPubKey, timestamp)) { + if (!pwallet->AddWatchOnly(scriptRawPubKey, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -1160,7 +1160,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6 pwallet->MarkDirty(); - if (!pwallet->HaveWatchOnly(script) && !pwallet->AddWatchOnly(script, timestamp)) { + if (!pwallet->AddWatchOnly(script, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } From eea802738052cc754f1fc88dc1758107be5a4702 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 18 Mar 2017 10:10:00 +0100 Subject: [PATCH 08/20] Merge #9987: Remove unused code 8dc957a Remove unused code (practicalswift) Tree-SHA512: c7bb286e3b92e42fec8aa1ac2491fd38be36602efca16b4bdc4e9d5ada75c11d99e7713092ec13794abd69d5ef2c732b86209a6d01710e5ebf6fc51b8a65c92a resolve usage of `MiningRequiresPeers()` remove `fMiningRequiresPeers` --- src/chainparams.cpp | 4 ---- src/chainparams.h | 3 --- src/coins.h | 1 - src/dash-tx.cpp | 16 ---------------- src/httpserver.cpp | 7 ------- src/net.cpp | 5 ----- src/net.h | 1 - src/rpc/mining.cpp | 10 ++++------ src/rpc/server.h | 1 - src/sync.cpp | 2 -- src/sync.h | 1 - src/test/key_tests.cpp | 28 ---------------------------- src/test/script_tests.cpp | 5 ----- 13 files changed, 4 insertions(+), 80 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 7336c92d9568..8c0b43b94514 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -313,7 +313,6 @@ class CMainParams : public CChainParams { consensus.llmqChainLocks = Consensus::LLMQ_400_60; consensus.llmqForInstantSend = Consensus::LLMQ_50_60; - fMiningRequiresPeers = true; fDefaultConsistencyChecks = false; fRequireStandard = true; fRequireRoutableExternalIP = true; @@ -492,7 +491,6 @@ class CTestNetParams : public CChainParams { consensus.llmqChainLocks = Consensus::LLMQ_50_60; consensus.llmqForInstantSend = Consensus::LLMQ_50_60; - fMiningRequiresPeers = true; fDefaultConsistencyChecks = false; fRequireStandard = false; fRequireRoutableExternalIP = true; @@ -650,7 +648,6 @@ class CDevNetParams : public CChainParams { consensus.llmqChainLocks = Consensus::LLMQ_50_60; consensus.llmqForInstantSend = Consensus::LLMQ_50_60; - fMiningRequiresPeers = true; fDefaultConsistencyChecks = false; fRequireStandard = false; fMineBlocksOnDemand = false; @@ -774,7 +771,6 @@ class CRegTestParams : public CChainParams { vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds. vSeeds.clear(); //!< Regtest mode doesn't have any DNS seeds. - fMiningRequiresPeers = false; fDefaultConsistencyChecks = true; fRequireStandard = false; fRequireRoutableExternalIP = false; diff --git a/src/chainparams.h b/src/chainparams.h index f59ba102cd48..edcaeabfe574 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -63,8 +63,6 @@ class CChainParams const CBlock& GenesisBlock() const { return genesis; } const CBlock& DevNetGenesisBlock() const { return devnetGenesis; } - /** Make miner wait to have peers to avoid wasting work */ - bool MiningRequiresPeers() const { return fMiningRequiresPeers; } /** Default value for -checkmempool and -checkblockindex argument */ bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; } /** Policy: Filter transactions that do not match well-defined patterns */ @@ -108,7 +106,6 @@ class CChainParams CBlock genesis; CBlock devnetGenesis; std::vector vFixedSeeds; - bool fMiningRequiresPeers; bool fDefaultConsistencyChecks; bool fRequireStandard; bool fRequireRoutableExternalIP; diff --git a/src/coins.h b/src/coins.h index e2606c7c21be..faa7632b347a 100644 --- a/src/coins.h +++ b/src/coins.h @@ -128,7 +128,6 @@ class CCoinsViewCursor virtual bool GetKey(COutPoint &key) const = 0; virtual bool GetValue(Coin &coin) const = 0; - /* Don't care about GetKeySize here */ virtual unsigned int GetValueSize() const = 0; virtual bool Valid() const = 0; diff --git a/src/dash-tx.cpp b/src/dash-tx.cpp index 5c3348e706c8..3af107e818db 100644 --- a/src/dash-tx.cpp +++ b/src/dash-tx.cpp @@ -471,22 +471,6 @@ static bool findSighashFlags(int& flags, const std::string& flagStr) return false; } -uint256 ParseHashUO(std::map& o, std::string strKey) -{ - if (!o.count(strKey)) - return uint256(); - return ParseHashUV(o[strKey], strKey); -} - -std::vector ParseHexUO(std::map& o, std::string strKey) -{ - if (!o.count(strKey)) { - std::vector emptyVec; - return emptyVec; - } - return ParseHexUV(o[strKey], strKey); -} - static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr) { int nHashType = SIGHASH_ALL; diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 17fc4d9771bd..216fc811795c 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -147,13 +147,6 @@ class WorkQueue cond.wait(lock); } } - - /** Return current depth of queue */ - size_t Depth() - { - std::unique_lock lock(cs); - return queue.size(); - } }; struct HTTPPathHandler diff --git a/src/net.cpp b/src/net.cpp index 00cab7b419b5..e65a35fabca0 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2686,11 +2686,6 @@ void CConnman::MarkAddressGood(const CAddress& addr) addrman.Good(addr); } -void CConnman::AddNewAddress(const CAddress& addr, const CAddress& addrFrom, int64_t nTimePenalty) -{ - addrman.Add(addr, addrFrom, nTimePenalty); -} - void CConnman::AddNewAddresses(const std::vector& vAddr, const CAddress& addrFrom, int64_t nTimePenalty) { addrman.Add(vAddr, addrFrom, nTimePenalty); diff --git a/src/net.h b/src/net.h index 4bf1a8206f59..57a8b07d7c66 100644 --- a/src/net.h +++ b/src/net.h @@ -336,7 +336,6 @@ class CConnman size_t GetAddressCount() const; void SetServices(const CService &addr, ServiceFlags nServices); void MarkAddressGood(const CAddress& addr); - void AddNewAddress(const CAddress& addr, const CAddress& addrFrom, int64_t nTimePenalty = 0); void AddNewAddresses(const std::vector& vAddr, const CAddress& addrFrom, int64_t nTimePenalty = 0); std::vector GetAddresses(); diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 3b65ca11ad1c..1d3ea083f35a 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -488,13 +488,11 @@ UniValue getblocktemplate(const JSONRPCRequest& request) if(!g_connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); - if (Params().MiningRequiresPeers()) { - if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0) - throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Dash Core is not connected!"); + if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0) + throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Dash Core is not connected!"); - if (IsInitialBlockDownload()) - throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Dash Core is downloading blocks..."); - } + if (IsInitialBlockDownload()) + throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Dash Core is downloading blocks..."); // Get expected MN/superblock payees. The call to GetBlockTxOuts might fail on regtest/devnet or when // testnet is reset. This is fine and we ignore failure (blocks will be accepted) diff --git a/src/rpc/server.h b/src/rpc/server.h index e613eaf43af6..10d4a94f4d34 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -26,7 +26,6 @@ namespace RPCServer void OnStarted(boost::function slot); void OnStopped(boost::function slot); void OnPreCommand(boost::function slot); - void OnPostCommand(boost::function slot); } class CBlockIndex; diff --git a/src/sync.cpp b/src/sync.cpp index 3995d12a8d7f..924223630ee8 100644 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -45,8 +45,6 @@ struct CLockLocation { return mutexName + " " + sourceFile + ":" + itostr(sourceLine) + (fTry ? " (TRY)" : ""); } - std::string MutexName() const { return mutexName; } - bool fTry; private: std::string mutexName; diff --git a/src/sync.h b/src/sync.h index ce14d6410029..ea34f1c4e2b1 100644 --- a/src/sync.h +++ b/src/sync.h @@ -100,7 +100,6 @@ class CCriticalSection : public AnnotatedMixin } }; -typedef CCriticalSection CDynamicCriticalSection; /** Wrapped boost mutex: supports waiting but not recursive locking */ typedef AnnotatedMixin CWaitableCriticalSection; diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 1af3dfd60695..813411d09a0c 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -29,34 +29,6 @@ static const CBitcoinAddress addr2C("Xn7ZrYdExuk79Dm7CJCw7sfUWi2qWJSbRy"); static const std::string strAddressBad("Xta1praZQjyELweyMByXyiREw1ZRsjXzVP"); -#ifdef KEY_TESTS_DUMPINFO -void dumpKeyInfo(uint256 privkey) -{ - CKey key; - key.resize(32); - memcpy(&secret[0], &privkey, 32); - std::vector sec; - sec.resize(32); - memcpy(&sec[0], &secret[0], 32); - printf(" * secret (hex): %s\n", HexStr(sec).c_str()); - - for (int nCompressed=0; nCompressed<2; nCompressed++) - { - bool fCompressed = nCompressed == 1; - printf(" * %s:\n", fCompressed ? "compressed" : "uncompressed"); - CBitcoinSecret bsecret; - bsecret.SetSecret(secret, fCompressed); - printf(" * secret (base58): %s\n", bsecret.ToString().c_str()); - CKey key; - key.SetSecret(secret, fCompressed); - std::vector vchPubKey = key.GetPubKey(); - printf(" * pubkey (hex): %s\n", HexStr(vchPubKey).c_str()); - printf(" * address (base58): %s\n", CBitcoinAddress(vchPubKey).ToString().c_str()); - } -} -#endif - - BOOST_FIXTURE_TEST_SUITE(key_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(key_test1) diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index cad83e2d215a..4ec18cf0ced6 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -381,11 +381,6 @@ class TestBuilder { return comment; } - - const CScript& GetScriptPubKey() - { - return creditTx->vout[0].scriptPubKey; - } }; std::string JSONPrettyPrint(const UniValue& univalue) From dd91bd7b3a35dd9b15a857937350057021557806 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Sat, 18 Mar 2017 11:00:00 +0100 Subject: [PATCH 09/20] Merge #9911: Wshadow: various gcc fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit d7f80b6 Rename first iterator to prevent shadowing. (Pavel Janík) b42ff60 Fix shadowing of local variables. (Pavel Janík) c4b60b3 Make some global variables less-global (static) (Pavel Janík) bb2aaee Prevent -Wshadow warnings with gcc versions 4.8.5, 5.3.1 and 6.2.1. (Pavel Janík) Tree-SHA512: 3aea4e28146c8f2a31351c6e2b0cce88b6f1e567a0ea0e6131624453e7193d0904e30d81b1439d8c69e281cf0e369b895851fb882ae48d5967b5c2e2c227404e --- src/streams.h | 4 ++-- src/test/checkqueue_tests.cpp | 8 ++++---- src/test/script_tests.cpp | 28 ++++++++++++++-------------- src/torcontrol.cpp | 24 ++++++++++++------------ src/wallet/db.cpp | 8 ++++---- 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/streams.h b/src/streams.h index 088a87c72d2c..57fa9a879b3f 100644 --- a/src/streams.h +++ b/src/streams.h @@ -365,8 +365,8 @@ class CDataStream return (*this); } - void GetAndClear(CSerializeData &data) { - data.insert(data.end(), begin(), end()); + void GetAndClear(CSerializeData &d) { + d.insert(d.end(), begin(), end()); clear(); } diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp index fe866dc3d5fb..cac968212e3e 100644 --- a/src/test/checkqueue_tests.cpp +++ b/src/test/checkqueue_tests.cpp @@ -46,7 +46,7 @@ struct FakeCheckCheckCompletion { struct FailingCheck { bool fails; - FailingCheck(bool fails) : fails(fails){}; + FailingCheck(bool _fails) : fails(_fails){}; FailingCheck() : fails(true){}; bool operator()() { @@ -411,15 +411,15 @@ BOOST_AUTO_TEST_CASE(test_CheckQueueControl_Locks) std::unique_lock l(m); tg.create_thread([&]{ CCheckQueueControl control(queue.get()); - std::unique_lock l(m); + std::unique_lock ll(m); has_lock = true; cv.notify_one(); - cv.wait(l, [&]{return has_tried;}); + cv.wait(ll, [&]{return has_tried;}); done = true; cv.notify_one(); // Wait until the done is acknowledged // - cv.wait(l, [&]{return done_ack;}); + cv.wait(ll, [&]{return done_ack;}); }); // Wait for thread to get the lock cv.wait(l, [&](){return has_lock;}); diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 4ec18cf0ced6..13a996499be1 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -31,7 +31,7 @@ // Uncomment if you want to output updated JSON tests. // #define UPDATE_JSON_TESTS -static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; +static const unsigned int gFlags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; unsigned int ParseScriptFlags(std::string strFlags); std::string FormatScriptFlags(unsigned int flags); @@ -801,18 +801,18 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12); CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, gFlags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); txTo12.vout[0].nValue = 2; - BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, gFlags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, gFlags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, gFlags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } @@ -834,54 +834,54 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) std::vector keys; keys.push_back(key1); keys.push_back(key2); CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key3); CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key3); CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key2); // Can't re-use sig CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); // Must have signatures CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); } diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 952149c06698..453cb1f170c1 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -662,26 +662,26 @@ void TorController::reconnect_cb(evutil_socket_t fd, short what, void *arg) } /****** Thread ********/ -struct event_base *base; -boost::thread torControlThread; +static struct event_base *gBase; +static boost::thread torControlThread; static void TorControlThread() { - TorController ctrl(base, GetArg("-torcontrol", DEFAULT_TOR_CONTROL)); + TorController ctrl(gBase, GetArg("-torcontrol", DEFAULT_TOR_CONTROL)); - event_base_dispatch(base); + event_base_dispatch(gBase); } void StartTorControl(boost::thread_group& threadGroup, CScheduler& scheduler) { - assert(!base); + assert(!gBase); #ifdef WIN32 evthread_use_windows_threads(); #else evthread_use_pthreads(); #endif - base = event_base_new(); - if (!base) { + gBase = event_base_new(); + if (!gBase) { LogPrintf("tor: Unable to create event_base\n"); return; } @@ -691,9 +691,9 @@ void StartTorControl(boost::thread_group& threadGroup, CScheduler& scheduler) void InterruptTorControl() { - if (base) { + if (gBase) { LogPrintf("tor: Thread interrupt\n"); - event_base_loopbreak(base); + event_base_loopbreak(gBase); } } @@ -701,13 +701,13 @@ void StopTorControl() { // timed_join() avoids the wallet not closing during a repair-restart. For a 'normal' wallet exit // it behaves for our cases exactly like the normal join() - if (base) { + if (gBase) { #if BOOST_VERSION >= 105000 torControlThread.try_join_for(boost::chrono::seconds(1)); #else torControlThread.timed_join(boost::posix_time::seconds(1)); #endif - event_base_free(base); - base = 0; + event_base_free(gBase); + gBase = 0; } } diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 9605c1cf81d0..4d85d445ee3c 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -604,11 +604,11 @@ bool CDB::PeriodicFlush(std::string strFile) { // Don't do this if any databases are in use int nRefCount = 0; - std::map::iterator mi = bitdb.mapFileUseCount.begin(); - while (mi != bitdb.mapFileUseCount.end()) + std::map::iterator mit = bitdb.mapFileUseCount.begin(); + while (mit != bitdb.mapFileUseCount.end()) { - nRefCount += (*mi).second; - mi++; + nRefCount += (*mit).second; + mit++; } if (nRefCount == 0) From 22563f3698f9d04b4b8f72b86b508090a195779b Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 19 Mar 2017 10:13:45 +0100 Subject: [PATCH 10/20] Merge #10024: [trivial] Use log.info() instead of print() in remaining functional test cases. e722777 fix logging in nulldummy and proxy_test (John Newbery) 1f70653 Use log.info() instead of print() in importmulti.py (John Newbery) Tree-SHA512: 0e58f0a970cd93bc1e9d73c6f53ca0671b0c5135cbf92e97d8563bd8a063679bf04f8bde511c275d5f84036aed32f70d3d03679a92688952b46dc97929e0405c --- qa/rpc-tests/importmulti.py | 2 +- qa/rpc-tests/nulldummy.py | 2 +- qa/rpc-tests/proxy_test.py | 4 ++-- qa/rpc-tests/test_framework/socks5.py | 7 +++++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/qa/rpc-tests/importmulti.py b/qa/rpc-tests/importmulti.py index ca5d42eced8d..aa03c6780a20 100755 --- a/qa/rpc-tests/importmulti.py +++ b/qa/rpc-tests/importmulti.py @@ -413,7 +413,7 @@ def run_test (self): # Importing existing watch only address with new timestamp should replace saved timestamp. assert_greater_than(timestamp, watchonly_timestamp) - print("Should replace previously saved watch only timestamp.") + self.log.info("Should replace previously saved watch only timestamp.") result = self.nodes[1].importmulti([{ "scriptPubKey": { "address": watchonly_address, diff --git a/qa/rpc-tests/nulldummy.py b/qa/rpc-tests/nulldummy.py index 492f358e1aae..736fed5fc914 100755 --- a/qa/rpc-tests/nulldummy.py +++ b/qa/rpc-tests/nulldummy.py @@ -76,7 +76,7 @@ def run_test(self): self.log.info("Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [431]") self.block_submit(self.nodes[0], [test2tx], True) - self.log.info ("Test 4: Non-NULLDUMMY base multisig transaction is invalid after activation") + self.log.info("Test 4: Non-NULLDUMMY base multisig transaction is invalid after activation") test4tx = self.create_transaction(self.nodes[0], test2tx.hash, self.address, 46) test6txs=[CTransaction(test4tx)] trueDummy(test4tx) diff --git a/qa/rpc-tests/proxy_test.py b/qa/rpc-tests/proxy_test.py index 6b2a8ed1c7cf..748e3e69f681 100755 --- a/qa/rpc-tests/proxy_test.py +++ b/qa/rpc-tests/proxy_test.py @@ -49,6 +49,7 @@ def __init__(self): self.num_nodes = 4 self.setup_clean_chain = False + def setup_nodes(self): self.have_ipv6 = test_ipv6_local() # Create two proxies on different ports # ... one unauthenticated @@ -69,7 +70,7 @@ def __init__(self): self.conf3.unauth = True self.conf3.auth = True else: - print("Warning: testing without local IPv6 support") + self.log.warning("Testing without local IPv6 support") self.serv1 = Socks5Server(self.conf1) self.serv1.start() @@ -79,7 +80,6 @@ def __init__(self): 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 args = [ diff --git a/qa/rpc-tests/test_framework/socks5.py b/qa/rpc-tests/test_framework/socks5.py index 450bf3775eaa..dd7624d4540e 100644 --- a/qa/rpc-tests/test_framework/socks5.py +++ b/qa/rpc-tests/test_framework/socks5.py @@ -6,6 +6,9 @@ import socket, threading, queue import traceback, sys +import logging + +logger = logging.getLogger("TestFramework.socks5") ### Protocol constants class Command: @@ -112,10 +115,10 @@ def handle(self): cmdin = Socks5Command(cmd, atyp, addr, port, username, password) self.serv.queue.put(cmdin) - print('Proxy: ', cmdin) + logger.info('Proxy: %s', cmdin) # Fall through to disconnect except Exception as e: - traceback.print_exc(file=sys.stderr) + logger.exception("socks5 request handling failed.") self.serv.queue.put(e) finally: self.conn.close() From d563222854e7070bcd25205cebb6a9a3a574a320 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 19 Mar 2017 11:26:31 +0100 Subject: [PATCH 11/20] Merge #10033: Trivial: Fix typo in key.h comment f490dae Trivial: Fix typo in key.h comment (Michael Goldstein) Tree-SHA512: 4b79bfa88313d3558edb9ab1c6d27bd45659355e81f224ba75c05ff069ebae4c9f443efd70ae274814bbb7cca8a9057942b9b867055c48e93822ac73e38a51ce --- src/key.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/key.h b/src/key.h index ff5252b7a0fd..b218f2cb7222 100644 --- a/src/key.h +++ b/src/key.h @@ -45,7 +45,7 @@ class CKey //! The actual byte data std::vector > keydata; - //! Check whether the 32-byte array pointed to be vch is valid keydata. + //! Check whether the 32-byte array pointed to by vch is valid keydata. bool static Check(const unsigned char* vch); public: From de0919220b1d4289b25dc38c59894e83bdf7a644 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 20 Mar 2017 08:39:13 +0100 Subject: [PATCH 12/20] Merge #10027: Set to nullptr after delete d93b97f Set to nullptr after delete (practicalswift) Tree-SHA512: 7201cef4541557ffe31f52ce7527c4b08a2ff5aa1eae5268bdfee5b4843881f8fd115257bef6d1b4dfb71166951950a912ce87aef160ca89c2ca2ae264cfab1b set dash pointers to nullptr after deletion --- src/httpserver.cpp | 1 + src/qt/test/rpcnestedtests.cpp | 2 ++ src/test/dbwrapper_tests.cpp | 2 ++ 3 files changed, 5 insertions(+) diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 216fc811795c..21b3bd090403 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -482,6 +482,7 @@ void StopHTTPServer() workQueue->WaitExit(); #endif delete workQueue; + workQueue = nullptr; } if (eventBase) { LogPrint("http", "Waiting for HTTP event thread to exit\n"); diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp index 30b9c9233072..cacfa5f69de6 100644 --- a/src/qt/test/rpcnestedtests.cpp +++ b/src/qt/test/rpcnestedtests.cpp @@ -160,11 +160,13 @@ void RPCNestedTests::rpcNestedTests() pcoinsTip = nullptr; llmq::DestroyLLMQSystem(); delete deterministicMNManager; + deterministicMNManager = nullptr; delete pcoinsdbview; pcoinsdbview = nullptr; delete pblocktree; pblocktree = nullptr; delete evoDb; + evoDb = nullptr; boost::filesystem::remove_all(boost::filesystem::path(path)); } diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index ca55dccf423d..371d103c7d35 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -141,6 +141,7 @@ BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) // Call the destructor to free leveldb LOCK delete dbw; + dbw = nullptr; // Now, set up another wrapper that wants to obfuscate the same directory CDBWrapper odbw(ph, (1 << 10), false, false, true); @@ -182,6 +183,7 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex) // Call the destructor to free leveldb LOCK delete dbw; + dbw = nullptr; // Simulate a -reindex by wiping the existing data store CDBWrapper odbw(ph, (1 << 10), false, true, true); From 1914c2d7888b1d9bb6b325b313f64b4153cb7910 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 20 Mar 2017 15:04:59 +0100 Subject: [PATCH 13/20] Merge #10038: Add mallocinfo mode to `getmemoryinfo` RPC e141aa4 Add mallocinfo mode to `getmemoryinfo` RPC (Wladimir J. van der Laan) Tree-SHA512: e778631765c29b3b5fb94eb66e5f50a8f108a234891bdcc4883f1e6e2fdd223f7660fad987eb2d7cbda5b800482d78adc1a309a3f6f83a84c556af43ebee2ed7 --- configure.ac | 8 +++++++ src/rpc/misc.cpp | 54 +++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 830c3ba88213..b76ac1e816d0 100644 --- a/configure.ac +++ b/configure.ac @@ -619,6 +619,14 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [ AC_MSG_RESULT(no)] ) +dnl Check for malloc_info (for memory statistics information in getmemoryinfo) +AC_MSG_CHECKING(for getmemoryinfo) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[ int f = malloc_info(0, NULL); ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_MALLOC_INFO, 1,[Define this symbol if you have malloc_info]) ], + [ AC_MSG_RESULT(no)] +) + AC_MSG_CHECKING([for visibility attribute]) AC_LINK_IFELSE([AC_LANG_SOURCE([ int foo_def( void ) __attribute__((visibility("default"))); diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 5fc2f612bf08..7810d4a6bb7d 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -25,6 +25,9 @@ #include "spork.h" #include +#ifdef HAVE_MALLOC_INFO +#include +#endif #include #include @@ -1117,16 +1120,39 @@ static UniValue RPCLockedMemoryInfo() return obj; } +#ifdef HAVE_MALLOC_INFO +static std::string RPCMallocInfo() +{ + char *ptr = nullptr; + size_t size = 0; + FILE *f = open_memstream(&ptr, &size); + if (f) { + malloc_info(0, f); + fclose(f); + if (ptr) { + std::string rv(ptr, size); + free(ptr); + return rv; + } + } + return ""; +} +#endif + UniValue getmemoryinfo(const JSONRPCRequest& request) { /* Please, avoid using the word "pool" here in the RPC interface or help, * as users will undoubtedly confuse it with the other "memory pool" */ - if (request.fHelp || request.params.size() != 0) + if (request.fHelp || request.params.size() > 1) throw std::runtime_error( - "getmemoryinfo\n" + "getmemoryinfo (\"mode\")\n" "Returns an object containing information about memory usage.\n" - "\nResult:\n" + "Arguments:\n" + "1. \"mode\" determines what kind of information is returned. This argument is optional, the default mode is \"stats\".\n" + " - \"stats\" returns general statistics about memory usage in the daemon.\n" + " - \"mallocinfo\" returns an XML string describing low-level heap state (only available if compiled with glibc 2.10+).\n" + "\nResult (mode \"stats\"):\n" "{\n" " \"locked\": { (json object) Information about locked memory manager\n" " \"used\": xxxxx, (numeric) Number of bytes used\n" @@ -1137,13 +1163,27 @@ UniValue getmemoryinfo(const JSONRPCRequest& request) " \"chunks_free\": xxxxx, (numeric) Number unused chunks\n" " }\n" "}\n" + "\nResult (mode \"mallocinfo\"):\n" + "\"...\"\n" "\nExamples:\n" + HelpExampleCli("getmemoryinfo", "") + HelpExampleRpc("getmemoryinfo", "") ); - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("locked", RPCLockedMemoryInfo())); - return obj; + + std::string mode = (request.params.size() < 1 || request.params[0].isNull()) ? "stats" : request.params[0].get_str(); + if (mode == "stats") { + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("locked", RPCLockedMemoryInfo())); + return obj; + } else if (mode == "mallocinfo") { +#ifdef HAVE_MALLOC_INFO + return RPCMallocInfo(); +#else + throw JSONRPCError(RPC_INVALID_PARAMETER, "mallocinfo is only available when compiled with glibc 2.10+"); +#endif + } else { + throw JSONRPCError(RPC_INVALID_PARAMETER, "unknown mode " + mode); + } } UniValue echo(const JSONRPCRequest& request) @@ -1164,7 +1204,7 @@ static const CRPCCommand commands[] = // --------------------- ------------------------ ----------------------- ---------- { "control", "debug", &debug, true, {} }, { "control", "getinfo", &getinfo, true, {} }, /* uses wallet if enabled */ - { "control", "getmemoryinfo", &getmemoryinfo, true, {} }, + { "control", "getmemoryinfo", &getmemoryinfo, true, {"mode"} }, { "util", "validateaddress", &validateaddress, true, {"address"} }, /* uses wallet if enabled */ { "util", "createmultisig", &createmultisig, true, {"nrequired","keys"} }, { "util", "verifymessage", &verifymessage, true, {"address","signature","message"} }, From 5f45198045749eb0dff9ad86ed531f1752184977 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 20 Mar 2017 17:58:40 +0100 Subject: [PATCH 14/20] Merge #9734: Add updating of chainTxData to release process 41b8821 Add updating of chainTxData to release process (Pieter Wuille) Tree-SHA512: f7d6e72b19aa83fc4851a9316d6c6a236e0e914d637525cda42c0b15a94543b8072ce67b57d6b12141332a03b64b6c715dff4d61e6e58e0197b22305b35ad65d --- doc/release-process.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/release-process.md b/doc/release-process.md index 255c2c05a37f..b6ab2b2e1e09 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -21,6 +21,7 @@ Before every major release: * Update hardcoded [seeds](/contrib/seeds/README.md). TODO: Give example PR for Dash * Update [`BLOCK_CHAIN_SIZE`](/src/qt/intro.cpp) to the current size plus some overhead. +* Update `src/chainparams.cpp` chainTxData with statistics about the transaction count and rate. ### First time / New builders From 720f13d6942f6cd7e2ea82fc03d6156ab5d6f8ae Mon Sep 17 00:00:00 2001 From: pasta Date: Fri, 15 Mar 2019 14:23:30 -0500 Subject: [PATCH 15/20] add a comment linking to xvfb documentation --- ci/test_unittests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/test_unittests.sh b/ci/test_unittests.sh index 9b0516a5517b..9c88ee0fc66e 100755 --- a/ci/test_unittests.sh +++ b/ci/test_unittests.sh @@ -22,6 +22,7 @@ cd build-ci/dashcore-$BUILD_TARGET if [ "$RUN_TESTS" = "true" -a "${DEP_OPTS#*NO_QT=1}" = "$DEP_OPTS" ]; then export DISPLAY=:99.0; + # Start xvfb if needed, as documented at https://docs.travis-ci.com/user/gui-and-headless-browsers/#Using-xvfb-to-Run-Tests-That-Require-a-GUI /sbin/start-stop-daemon --start --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac; fi From 9cef545acab912aa53db3308d505b78c9fb3abea Mon Sep 17 00:00:00 2001 From: Pasta Date: Wed, 3 Apr 2019 07:40:18 -0500 Subject: [PATCH 16/20] code review Signed-off-by: Pasta --- qa/rpc-tests/__init__.py | 0 qa/rpc-tests/nulldummy.py | 2 +- qa/rpc-tests/prioritise_transaction.py | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 qa/rpc-tests/__init__.py diff --git a/qa/rpc-tests/__init__.py b/qa/rpc-tests/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/qa/rpc-tests/nulldummy.py b/qa/rpc-tests/nulldummy.py index 736fed5fc914..3ad8a3235f31 100755 --- a/qa/rpc-tests/nulldummy.py +++ b/qa/rpc-tests/nulldummy.py @@ -101,7 +101,7 @@ def create_transaction(self, node, txid, to_address, amount): def block_submit(self, node, txs, accept = False): - dip4_activated = self.lastblockheight + 1 >= 432 + dip4_activated = self.lastblockheight + 1 >= 432 block = create_block(self.tip, create_coinbase(self.lastblockheight + 1, dip4_activated=dip4_activated), self.lastblocktime + 1) block.nVersion = 4 for tx in txs: diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py index ac74ca73a923..85d43a713c68 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -110,8 +110,8 @@ def run_test(self): tx_id = self.nodes[0].decoderawtransaction(tx_hex)["txid"] # This will raise an exception due to min relay fee not being met - assert_raises_jsonrpc(-26, "66: insufficient priority", self.nodes[0].sendrawtransaction, tx2_hex) - assert(tx2_id not in self.nodes[0].getrawmempool()) + assert_raises_jsonrpc(-26, "66: min relay fee not met", self.nodes[0].sendrawtransaction, tx2_hex) + assert(tx_id not in self.nodes[0].getrawmempool()) # 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 From 826846f154a7ea747ed4a845e14308f53c0a484f Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Sat, 6 Apr 2019 12:44:43 +0300 Subject: [PATCH 17/20] Review suggestions --- qa/rpc-tests/__init__.py | 0 qa/rpc-tests/mempool_spendcoinbase.py | 2 +- qa/rpc-tests/prioritise_transaction.py | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 qa/rpc-tests/__init__.py diff --git a/qa/rpc-tests/__init__.py b/qa/rpc-tests/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/qa/rpc-tests/mempool_spendcoinbase.py index 08ca626e71a8..1dbf8ae2581a 100755 --- a/qa/rpc-tests/mempool_spendcoinbase.py +++ b/qa/rpc-tests/mempool_spendcoinbase.py @@ -45,7 +45,7 @@ def run_test(self): spend_101_id = self.nodes[0].sendrawtransaction(spends_raw[0]) # coinbase at height 102 should be too immature to spend - assert_raises_jsonrpc(-26,"bad-txns-premature-spend-of-coinbase", self.nodes[0].sendrawtransaction, spends_raw[1], False, False, True) + assert_raises_jsonrpc(-26,"bad-txns-premature-spend-of-coinbase", self.nodes[0].sendrawtransaction, spends_raw[1]) # mempool should have just spend_101: assert_equal(self.nodes[0].getrawmempool(), [ spend_101_id ]) diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py index 85d43a713c68..0da13e5ebd95 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -110,7 +110,7 @@ def run_test(self): tx_id = self.nodes[0].decoderawtransaction(tx_hex)["txid"] # This will raise an exception due to min relay fee not being met - assert_raises_jsonrpc(-26, "66: min relay fee not met", self.nodes[0].sendrawtransaction, tx2_hex) + assert_raises_jsonrpc(-26, "66: min relay fee not met", self.nodes[0].sendrawtransaction, tx_hex) assert(tx_id not in self.nodes[0].getrawmempool()) # This is a less than 1000-byte transaction, so just set the fee From f8c3f9f7d10eb74b033a0e7fb8377803070ee381 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Mon, 10 Apr 2017 08:57:26 +0200 Subject: [PATCH 18/20] Merge #10142: Run bitcoin_test-qt under minimal QPA platform bf10264 Run bitcoin_test-qt under minimal QPA platform (Russell Yanofsky) Tree-SHA512: 35782f0d7e4dcdc27d991d5a10fcffbd2d201139293fe7917ef6f7cd7ae4d3a162ebc21f83266d821ae3bad86f62d947b047bb317f6c5899df4d6bcb4c957157 --- build-aux/m4/bitcoin_qt.m4 | 2 ++ src/qt/test/test_main.cpp | 8 ++++++++ src/qt/test/wallettests.cpp | 12 ++++++++++++ 3 files changed, 22 insertions(+) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index e11c9b90ea6b..c3785bdcf3b7 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -130,6 +130,8 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ if test "x$bitcoin_cv_need_acc_widget" = "xyes"; then _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(AccessibleFactory)], [-lqtaccessiblewidgets]) fi + _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QMinimalIntegrationPlugin)],[-lqminimal]) + AC_DEFINE(QT_QPA_PLATFORM_MINIMAL, 1, [Define this symbol if the minimal qt platform exists]) if test x$TARGET_OS = xwindows; then _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)],[-lqwindows]) AC_DEFINE(QT_QPA_PLATFORM_WINDOWS, 1, [Define this symbol if the qt platform is windows]) diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index c73459b3aa58..dc6a92bb3535 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -33,6 +33,9 @@ Q_IMPORT_PLUGIN(qjpcodecs) Q_IMPORT_PLUGIN(qtwcodecs) Q_IMPORT_PLUGIN(qkrcodecs) #else +#if defined(QT_QPA_PLATFORM_MINIMAL) +Q_IMPORT_PLUGIN(QMinimalIntegrationPlugin); +#endif #if defined(QT_QPA_PLATFORM_XCB) Q_IMPORT_PLUGIN(QXcbIntegrationPlugin); #elif defined(QT_QPA_PLATFORM_WINDOWS) @@ -55,6 +58,11 @@ int main(int argc, char *argv[]) bool fInvalid = false; + // Prefer the "minimal" platform for the test instead of the normal default + // platform ("xcb", "windows", or "cocoa") so tests can't unintentially + // interfere with any background GUIs and don't require extra resources. + setenv("QT_QPA_PLATFORM", "minimal", 0); + // Don't remove this, it's needed to access // QApplication:: and QCoreApplication:: in the tests QApplication app(argc, argv); diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp index 79c685582801..5851175860da 100644 --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -66,6 +66,18 @@ QModelIndex FindTx(const QAbstractItemModel& model, const uint256& txid) } //! Simple qt wallet tests. +// +// Test widgets can be debugged interactively calling show() on them and +// manually running the event loop, e.g.: +// +// sendCoinsDialog.show(); +// QEventLoop().exec(); +// +// This also requires overriding the default minimal Qt platform: +// +// src/qt/test/test_bitcoin-qt -platform xcb # Linux +// src/qt/test/test_bitcoin-qt -platform windows # Windows +// src/qt/test/test_bitcoin-qt -platform cocoa # macOS void WalletTests::walletTests() { // Set up wallet and chain with 101 blocks (1 mature block for spending). From fc1b3772d5dbfe8666220980c7a05a96056b0807 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 26 Jul 2017 08:11:42 +0200 Subject: [PATCH 19/20] Merge #10899: [test] Qt: Use _putenv_s instead of setenv on Windows builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 0be03c7 Qt: Use _putenv_s instead of setenv on Windows builds (Brian McMichael) Pull request description: Fixes https://github.com/bitcoin/bitcoin/issues/10836 Error message I would get on `make`: ``` ... CXXLD bench/bench_bitcoin.exe OBJCXXLD qt/bitcoin-qt.exe qt/test/test_main.cpp: In function ‘int main(int, char**)’: qt/test/test_main.cpp:64:43: error: ‘setenv’ was not declared in this scope setenv("QT_QPA_PLATFORM", "minimal", 0); ^ make[2]: *** [qt/test/qt_test_test_bitcoin_qt-test_main.o] Error 1 make[2]: *** Waiting for unfinished jobs.... make[2]: Leaving directory `/home/bmcmichael/Projects/bcoin/src' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/home/bmcmichael/Projects/bcoin/src' make: *** [all-recursive] Error 1 ``` `setenv` function is not available from the Microsoft runtime library. Need to use `_putenv_s` instead. This solution tells the compiler to use `_putenv_s` on `WIN32` compilation (Note: this also works on 64-bit Windows instances.) and `setenv` everywhere else. I've tested builds on Windows 10 x64 and Ubuntu 16.04 with this code. Tree-SHA512: d53c996c890e3c6f22b4f2dcca718bef9168f19a6d4a29b8ff13391bfc0c8ea9c1cd16782b47c25b156dcbdff18bb19e23bfd5f6fefb1f373c9d5454a13fc969 --- src/qt/test/test_main.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index dc6a92bb3535..44efc9092212 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -61,7 +61,11 @@ int main(int argc, char *argv[]) // Prefer the "minimal" platform for the test instead of the normal default // platform ("xcb", "windows", or "cocoa") so tests can't unintentially // interfere with any background GUIs and don't require extra resources. - setenv("QT_QPA_PLATFORM", "minimal", 0); + #if defined(WIN32) + _putenv_s("QT_QPA_PLATFORM", "minimal"); + #else + setenv("QT_QPA_PLATFORM", "minimal", 0); + #endif // Don't remove this, it's needed to access // QApplication:: and QCoreApplication:: in the tests From ace96a941aacc2e93af81f69909b4242582b76da Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Sat, 6 Apr 2019 16:58:25 +0300 Subject: [PATCH 20/20] Drop xvfb and run tests in linux64_nowallet --- ci/matrix.sh | 3 ++- ci/test_unittests.sh | 6 ------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/ci/matrix.sh b/ci/matrix.sh index 91ce9658c026..e033ee3d5ef1 100755 --- a/ci/matrix.sh +++ b/ci/matrix.sh @@ -66,9 +66,10 @@ elif [ "$BUILD_TARGET" = "linux64" ]; then export RUN_TESTS=true elif [ "$BUILD_TARGET" = "linux64_nowallet" ]; then export HOST=x86_64-unknown-linux-gnu - export PACKAGES="python3 xvfb" + export PACKAGES="python3" export DEP_OPTS="NO_WALLET=1" export BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" + export RUN_TESTS=true elif [ "$BUILD_TARGET" = "linux64_release" ]; then export HOST=x86_64-unknown-linux-gnu export PACKAGES="bc python3-zmq" diff --git a/ci/test_unittests.sh b/ci/test_unittests.sh index 9c88ee0fc66e..2d221c66b683 100755 --- a/ci/test_unittests.sh +++ b/ci/test_unittests.sh @@ -20,12 +20,6 @@ export BOOST_TEST_LOG_LEVEL=test_suite cd build-ci/dashcore-$BUILD_TARGET -if [ "$RUN_TESTS" = "true" -a "${DEP_OPTS#*NO_QT=1}" = "$DEP_OPTS" ]; then - export DISPLAY=:99.0; - # Start xvfb if needed, as documented at https://docs.travis-ci.com/user/gui-and-headless-browsers/#Using-xvfb-to-Run-Tests-That-Require-a-GUI - /sbin/start-stop-daemon --start --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac; -fi - if [ "$DIRECT_WINE_EXEC_TESTS" = "true" ]; then # Inside Docker, binfmt isn't working so we can't trust in make invoking windows binaries correctly wine ./src/test/test_dash.exe