aboutsummaryrefslogtreecommitdiff
path: root/qa/rpc-tests
diff options
context:
space:
mode:
Diffstat (limited to 'qa/rpc-tests')
-rwxr-xr-xqa/rpc-tests/bip65-cltv.py8
-rwxr-xr-xqa/rpc-tests/bip68-sequence.py46
-rwxr-xr-xqa/rpc-tests/bipdersig.py8
-rwxr-xr-xqa/rpc-tests/blockchain.py6
-rwxr-xr-xqa/rpc-tests/bumpfee.py2
-rwxr-xr-xqa/rpc-tests/disablewallet.py17
-rwxr-xr-xqa/rpc-tests/getblocktemplate_longpoll.py4
-rwxr-xr-xqa/rpc-tests/getblocktemplate_proposals.py4
-rwxr-xr-xqa/rpc-tests/importmulti.py19
-rwxr-xr-xqa/rpc-tests/keypool.py18
-rwxr-xr-xqa/rpc-tests/mempool_packages.py29
-rwxr-xr-xqa/rpc-tests/mempool_reorg.py16
-rwxr-xr-xqa/rpc-tests/mempool_spendcoinbase.py2
-rwxr-xr-xqa/rpc-tests/nulldummy.py31
-rwxr-xr-xqa/rpc-tests/p2p-segwit.py8
-rwxr-xr-xqa/rpc-tests/prioritise_transaction.py10
-rwxr-xr-xqa/rpc-tests/replace-by-fee.py105
-rwxr-xr-xqa/rpc-tests/rpcbind_test.py6
-rwxr-xr-xqa/rpc-tests/segwit.py191
-rwxr-xr-xqa/rpc-tests/smartfees.py60
-rwxr-xr-xqa/rpc-tests/wallet.py20
21 files changed, 266 insertions, 344 deletions
diff --git a/qa/rpc-tests/bip65-cltv.py b/qa/rpc-tests/bip65-cltv.py
index c9d02a98f3..7f13bb9952 100755
--- a/qa/rpc-tests/bip65-cltv.py
+++ b/qa/rpc-tests/bip65-cltv.py
@@ -69,12 +69,8 @@ class BIP65Test(BitcoinTestFramework):
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 ffd461ccb0..3ed6ebe044 100755
--- a/qa/rpc-tests/bip68-sequence.py
+++ b/qa/rpc-tests/bip68-sequence.py
@@ -90,12 +90,7 @@ class BIP68Test(BitcoinTestFramework):
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 @@ class BIP68Test(BitcoinTestFramework):
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 @@ class BIP68Test(BitcoinTestFramework):
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 @@ class BIP68Test(BitcoinTestFramework):
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 @@ class BIP68Test(BitcoinTestFramework):
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 fa54bc2749..371cc41bb7 100755
--- a/qa/rpc-tests/bipdersig.py
+++ b/qa/rpc-tests/bipdersig.py
@@ -68,12 +68,8 @@ class BIP66Test(BitcoinTestFramework):
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 67b5826840..596aed50ec 100755
--- a/qa/rpc-tests/blockchain.py
+++ b/qa/rpc-tests/blockchain.py
@@ -14,10 +14,9 @@ Tests correspond to code in rpc/blockchain.cpp.
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,
@@ -58,8 +57,7 @@ class BlockchainTest(BitcoinTestFramework):
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/bumpfee.py b/qa/rpc-tests/bumpfee.py
index 69db197e7a..8f75e9ed4d 100755
--- a/qa/rpc-tests/bumpfee.py
+++ b/qa/rpc-tests/bumpfee.py
@@ -102,7 +102,7 @@ def test_segwit_bumpfee_succeeds(rbf_node, dest_address):
segwit_out = rbf_node.validateaddress(rbf_node.getnewaddress())
rbf_node.addwitnessaddress(segwit_out["address"])
segwitid = send_to_witness(
- version=0,
+ use_p2wsh=False,
node=rbf_node,
utxo=segwit_in,
pubkey=segwit_out["pubkey"],
diff --git a/qa/rpc-tests/disablewallet.py b/qa/rpc-tests/disablewallet.py
index ff7121659b..2f729e19bf 100755
--- a/qa/rpc-tests/disablewallet.py
+++ b/qa/rpc-tests/disablewallet.py
@@ -30,19 +30,10 @@ class DisableWalletTest (BitcoinTestFramework):
x = self.nodes[0].validateaddress('mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ')
assert(x['isvalid'] == True)
- # Checking mining to an address without a wallet
- try:
- self.nodes[0].generatetoaddress(1, 'mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ')
- 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, '3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy')
- 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, 'mneYUmWYsuk7kySiURxCi3AGxrAqZxLgPZ')
+ assert_raises_jsonrpc(-5, "Invalid address", self.nodes[0].generatetoaddress, 1, '3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy')
if __name__ == '__main__':
DisableWalletTest ().main ()
diff --git a/qa/rpc-tests/getblocktemplate_longpoll.py b/qa/rpc-tests/getblocktemplate_longpoll.py
index dc17bbd7b3..bbe1dda5f7 100755
--- a/qa/rpc-tests/getblocktemplate_longpoll.py
+++ b/qa/rpc-tests/getblocktemplate_longpoll.py
@@ -61,7 +61,9 @@ class GetBlockTemplateLPTest(BitcoinTestFramework):
thr = LongpollThread(self.nodes[0])
thr.start()
# generate a random transaction and submit it
- (txid, txhex, fee) = random_transaction(self.nodes, Decimal("1.1"), Decimal("0.0"), Decimal("0.001"), 20)
+ min_relay_fee = self.nodes[0].getnetworkinfo()["relayfee"]
+ # min_relay_fee is fee per 1000 bytes, which should be more than enough.
+ (txid, txhex, fee) = random_transaction(self.nodes, Decimal("1.1"), min_relay_fee, Decimal("0.001"), 20)
# after one minute, every 10 seconds the mempool is probed, so in 80 seconds it should have returned
thr.join(60 + 20)
assert(not thr.is_alive())
diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py
index 3b17dfcfb5..67745f77d1 100755
--- a/qa/rpc-tests/getblocktemplate_proposals.py
+++ b/qa/rpc-tests/getblocktemplate_proposals.py
@@ -105,7 +105,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
# 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)
@@ -126,7 +126,7 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
# 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/importmulti.py b/qa/rpc-tests/importmulti.py
index 298b6e9b86..ca5d42eced 100755
--- a/qa/rpc-tests/importmulti.py
+++ b/qa/rpc-tests/importmulti.py
@@ -314,6 +314,7 @@ class ImportMultiTest (BitcoinTestFramework):
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 @@ class ImportMultiTest (BitcoinTestFramework):
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/qa/rpc-tests/keypool.py b/qa/rpc-tests/keypool.py
index 4b9936a1fd..cee58563f0 100755
--- a/qa/rpc-tests/keypool.py
+++ b/qa/rpc-tests/keypool.py
@@ -28,11 +28,7 @@ class KeyPoolTest(BitcoinTestFramework):
assert(addr_before_encrypting_data['hdmasterkeyid'] != wallet_info['hdmasterkeyid'])
assert(addr_data['hdmasterkeyid'] == wallet_info['hdmasterkeyid'])
- 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)
@@ -48,11 +44,7 @@ class KeyPoolTest(BitcoinTestFramework):
# assert that four unique addresses were returned
assert(len(addr) == 4)
# 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)
@@ -66,11 +58,7 @@ class KeyPoolTest(BitcoinTestFramework):
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 __init__(self):
super().__init__()
diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py
index 915d174052..17e3a9a967 100755
--- a/qa/rpc-tests/mempool_packages.py
+++ b/qa/rpc-tests/mempool_packages.py
@@ -112,10 +112,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
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.
@@ -155,19 +152,19 @@ class MempoolPackagesTest(BitcoinTestFramework):
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 585e4147b2..812b54ffcb 100755
--- a/qa/rpc-tests/mempool_reorg.py
+++ b/qa/rpc-tests/mempool_reorg.py
@@ -30,9 +30,10 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
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 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
spend_102_raw = create_tx(self.nodes[0], coinbase_txids[2], node0_address, 49.99)
spend_103_raw = create_tx(self.nodes[0], coinbase_txids[3], node0_address, 49.99)
- # 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: 49.99})
# 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, 49.98)
@@ -73,6 +76,7 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
# 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 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
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 4818ad8bda..f562a93d86 100755
--- a/qa/rpc-tests/mempool_spendcoinbase.py
+++ b/qa/rpc-tests/mempool_spendcoinbase.py
@@ -45,7 +45,7 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework):
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])
# 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 4b215a70b0..7b19fbfd82 100755
--- a/qa/rpc-tests/nulldummy.py
+++ b/qa/rpc-tests/nulldummy.py
@@ -66,38 +66,38 @@ class NULLDUMMYTest(BitcoinTestFramework):
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_with_witness()), 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_with_witness()), True)
test1txs.append(self.create_transaction(self.nodes[0], coinbase_txid[1], self.wit_ms_address, 49))
- txid3 = self.tx_submit(self.nodes[0], test1txs[2])
+ txid3 = self.nodes[0].sendrawtransaction(bytes_to_hex_str(test1txs[2].serialize_with_witness()), True)
self.block_submit(self.nodes[0], test1txs, False, 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_with_witness()), 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], False, 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_with_witness()), True)
self.block_submit(self.nodes[0], [test4tx])
- self.log.info("Test 5: Non-NULLDUMMY P2WSH multisig transaction invalid after activation")
+ print ("Test 5: Non-NULLDUMMY P2WSH multisig transaction invalid after activation")
test5tx = self.create_transaction(self.nodes[0], txid3, self.wit_address, 48)
test6txs.append(CTransaction(test5tx))
test5tx.wit.vtxinwit[0].scriptWitness.stack[0] = b'\x01'
- self.tx_submit(self.nodes[0], test5tx, NULLDUMMY_ERROR)
+ assert_raises_jsonrpc(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, bytes_to_hex_str(test5tx.serialize_with_witness()), True)
self.block_submit(self.nodes[0], [test5tx], True)
self.log.info("Test 6: NULLDUMMY compliant base/witness 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_with_witness()), True)
self.block_submit(self.nodes[0], test6txs, True, True)
@@ -112,17 +112,6 @@ class NULLDUMMYTest(BitcoinTestFramework):
return tx
- def tx_submit(self, node, tx, msg = ""):
- tx.rehash()
- try:
- node.sendrawtransaction(bytes_to_hex_str(tx.serialize_with_witness()), True)
- except JSONRPCException as exp:
- assert_equal(exp.error["message"], msg)
- else:
- assert_equal('', msg)
- return tx.hash
-
-
def block_submit(self, node, txs, witness = False, accept = False):
block = create_block(self.tip, create_coinbase(self.lastblockheight + 1), self.lastblocktime + 1)
block.nVersion = 4
diff --git a/qa/rpc-tests/p2p-segwit.py b/qa/rpc-tests/p2p-segwit.py
index 0f844883b1..dcf2b9a7de 100755
--- a/qa/rpc-tests/p2p-segwit.py
+++ b/qa/rpc-tests/p2p-segwit.py
@@ -1698,9 +1698,11 @@ class SegWitTest(BitcoinTestFramework):
for node in [self.nodes[0], self.nodes[2]]:
gbt_results = node.getblocktemplate()
block_version = gbt_results['version']
- # If we're not indicating segwit support, we should not be signalling
- # for segwit activation, nor should we get a witness commitment.
- assert_equal(block_version & (1 << VB_WITNESS_BIT), 0)
+ # If we're not indicating segwit support, we will still be
+ # signalling for segwit activation.
+ assert_equal((block_version & (1 << VB_WITNESS_BIT) != 0), node == self.nodes[0])
+ # If we don't specify the segwit rule, then we won't get a default
+ # commitment.
assert('default_witness_commitment' not in gbt_results)
# Workaround:
diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py
index 10f596b2cb..0b04ad17ab 100755
--- a/qa/rpc-tests/prioritise_transaction.py
+++ b/qa/rpc-tests/prioritise_transaction.py
@@ -107,13 +107,9 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
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, tx_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
diff --git a/qa/rpc-tests/replace-by-fee.py b/qa/rpc-tests/replace-by-fee.py
index 8e2abea6a5..163c304eba 100755
--- a/qa/rpc-tests/replace-by-fee.py
+++ b/qa/rpc-tests/replace-by-fee.py
@@ -125,12 +125,8 @@ class ReplaceByFeeTest(BitcoinTestFramework):
tx1b.vout = [CTxOut(1*COIN, CScript([b'b']))]
tx1b_hex = txToHex(tx1b)
- try:
- tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
- except JSONRPCException as exp:
- assert_equal(exp.error['code'], -26) # insufficient fee
- else:
- assert(False)
+ # This will raise an exception due to insufficient fee
+ assert_raises_jsonrpc(-26, "insufficient fee", self.nodes[0].sendrawtransaction, tx1b_hex, True)
# Extra 0.1 BTC fee
tx1b = CTransaction()
@@ -172,12 +168,8 @@ class ReplaceByFeeTest(BitcoinTestFramework):
dbl_tx.vout = [CTxOut(initial_nValue - 30*COIN, CScript([1]))]
dbl_tx_hex = txToHex(dbl_tx)
- try:
- self.nodes[0].sendrawtransaction(dbl_tx_hex, True)
- except JSONRPCException as exp:
- assert_equal(exp.error['code'], -26) # insufficient fee
- else:
- assert(False) # transaction mistakenly accepted!
+ # This will raise an exception due to insufficient fee
+ assert_raises_jsonrpc(-26, "insufficient fee", self.nodes[0].sendrawtransaction, dbl_tx_hex, True)
# Accepted with sufficient fee
dbl_tx = CTransaction()
@@ -237,12 +229,8 @@ class ReplaceByFeeTest(BitcoinTestFramework):
dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)]
dbl_tx.vout = [CTxOut(initial_nValue - fee*n, CScript([1]))]
dbl_tx_hex = txToHex(dbl_tx)
- try:
- self.nodes[0].sendrawtransaction(dbl_tx_hex, True)
- except JSONRPCException as exp:
- assert_equal(exp.error['code'], -26) # insufficient fee
- else:
- assert(False)
+ # This will raise an exception due to insufficient fee
+ assert_raises_jsonrpc(-26, "insufficient fee", self.nodes[0].sendrawtransaction, dbl_tx_hex, True)
# 1 BTC fee is enough
dbl_tx = CTransaction()
@@ -269,13 +257,8 @@ class ReplaceByFeeTest(BitcoinTestFramework):
dbl_tx.vin = [CTxIn(tx0_outpoint, nSequence=0)]
dbl_tx.vout = [CTxOut(initial_nValue - 2*fee*n, CScript([1]))]
dbl_tx_hex = txToHex(dbl_tx)
- try:
- self.nodes[0].sendrawtransaction(dbl_tx_hex, True)
- except JSONRPCException as exp:
- assert_equal(exp.error['code'], -26)
- assert_equal("too many potential replacements" in exp.error['message'], True)
- else:
- assert(False)
+ # This will raise an exception
+ assert_raises_jsonrpc(-26, "too many potential replacements", self.nodes[0].sendrawtransaction, dbl_tx_hex, True)
for tx in tree_txs:
tx.rehash()
@@ -298,12 +281,8 @@ class ReplaceByFeeTest(BitcoinTestFramework):
tx1b.vout = [CTxOut(int(0.001*COIN), CScript([b'a'*999000]))]
tx1b_hex = txToHex(tx1b)
- try:
- tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
- except JSONRPCException as exp:
- assert_equal(exp.error['code'], -26) # insufficient fee
- else:
- assert(False)
+ # This will raise an exception due to insufficient fee
+ assert_raises_jsonrpc(-26, "insufficient fee", self.nodes[0].sendrawtransaction, tx1b_hex, True)
def test_spends_of_conflicting_outputs(self):
"""Replacements that spend conflicting tx outputs are rejected"""
@@ -325,12 +304,8 @@ class ReplaceByFeeTest(BitcoinTestFramework):
tx2.vout = tx1a.vout
tx2_hex = txToHex(tx2)
- try:
- tx2_txid = self.nodes[0].sendrawtransaction(tx2_hex, True)
- except JSONRPCException as exp:
- assert_equal(exp.error['code'], -26)
- else:
- assert(False)
+ # This will raise an exception
+ assert_raises_jsonrpc(-26, "bad-txns-spends-conflicting-tx", self.nodes[0].sendrawtransaction, tx2_hex, True)
# Spend tx1a's output to test the indirect case.
tx1b = CTransaction()
@@ -346,12 +321,8 @@ class ReplaceByFeeTest(BitcoinTestFramework):
tx2.vout = tx1a.vout
tx2_hex = txToHex(tx2)
- try:
- tx2_txid = self.nodes[0].sendrawtransaction(tx2_hex, True)
- except JSONRPCException as exp:
- assert_equal(exp.error['code'], -26)
- else:
- assert(False)
+ # This will raise an exception
+ assert_raises_jsonrpc(-26, "bad-txns-spends-conflicting-tx", self.nodes[0].sendrawtransaction, tx2_hex, True)
def test_new_unconfirmed_inputs(self):
"""Replacements that add new unconfirmed inputs are rejected"""
@@ -369,12 +340,8 @@ class ReplaceByFeeTest(BitcoinTestFramework):
tx2.vout = tx1.vout
tx2_hex = txToHex(tx2)
- try:
- tx2_txid = self.nodes[0].sendrawtransaction(tx2_hex, True)
- except JSONRPCException as exp:
- assert_equal(exp.error['code'], -26)
- else:
- assert(False)
+ # This will raise an exception
+ assert_raises_jsonrpc(-26, "replacement-adds-unconfirmed", self.nodes[0].sendrawtransaction, tx2_hex, True)
def test_too_many_replacements(self):
"""Replacements that evict too many transactions are rejected"""
@@ -419,13 +386,8 @@ class ReplaceByFeeTest(BitcoinTestFramework):
double_tx.vout = [CTxOut(double_spend_value, CScript([b'a']))]
double_tx_hex = txToHex(double_tx)
- try:
- self.nodes[0].sendrawtransaction(double_tx_hex, True)
- except JSONRPCException as exp:
- assert_equal(exp.error['code'], -26)
- assert_equal("too many potential replacements" in exp.error['message'], True)
- else:
- assert(False)
+ # This will raise an exception
+ assert_raises_jsonrpc(-26, "too many potential replacements", self.nodes[0].sendrawtransaction, double_tx_hex, True)
# If we remove an input, it should pass
double_tx = CTransaction()
@@ -451,13 +413,8 @@ class ReplaceByFeeTest(BitcoinTestFramework):
tx1b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))]
tx1b_hex = txToHex(tx1b)
- try:
- tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
- except JSONRPCException as exp:
- assert_equal(exp.error['code'], -26)
- else:
- self.log.info(tx1b_txid)
- assert(False)
+ # This will raise an exception
+ assert_raises_jsonrpc(-26, "txn-mempool-conflict", self.nodes[0].sendrawtransaction, tx1b_hex, True)
tx1_outpoint = make_utxo(self.nodes[0], int(1.1*COIN))
@@ -474,12 +431,8 @@ class ReplaceByFeeTest(BitcoinTestFramework):
tx2b.vout = [CTxOut(int(0.9*COIN), CScript([b'b']))]
tx2b_hex = txToHex(tx2b)
- try:
- tx2b_txid = self.nodes[0].sendrawtransaction(tx2b_hex, True)
- except JSONRPCException as exp:
- assert_equal(exp.error['code'], -26)
- else:
- assert(False)
+ # This will raise an exception
+ assert_raises_jsonrpc(-26, "txn-mempool-conflict", self.nodes[0].sendrawtransaction, tx2b_hex, True)
# Now create a new transaction that spends from tx1a and tx2a
# opt-in on one of the inputs
@@ -531,12 +484,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
tx1b_hex = txToHex(tx1b)
# Verify tx1b cannot replace tx1a.
- try:
- tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
- except JSONRPCException as exp:
- assert_equal(exp.error['code'], -26)
- else:
- assert(False)
+ assert_raises_jsonrpc(-26, "insufficient fee", self.nodes[0].sendrawtransaction, tx1b_hex, True)
# Use prioritisetransaction to set tx1a's fee to 0.
self.nodes[0].prioritisetransaction(tx1a_txid, int(-0.1*COIN))
@@ -563,12 +511,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
tx2b_hex = txToHex(tx2b)
# Verify tx2b cannot replace tx2a.
- try:
- tx2b_txid = self.nodes[0].sendrawtransaction(tx2b_hex, True)
- except JSONRPCException as exp:
- assert_equal(exp.error['code'], -26)
- else:
- assert(False)
+ assert_raises_jsonrpc(-26, "insufficient fee", self.nodes[0].sendrawtransaction, tx2b_hex, True)
# Now prioritise tx2b to have a higher modified fee
self.nodes[0].prioritisetransaction(tx2b.hash, int(0.1*COIN))
diff --git a/qa/rpc-tests/rpcbind_test.py b/qa/rpc-tests/rpcbind_test.py
index 220bf4ddd0..8720a345ce 100755
--- a/qa/rpc-tests/rpcbind_test.py
+++ b/qa/rpc-tests/rpcbind_test.py
@@ -92,11 +92,7 @@ class RPCBindTest(BitcoinTestFramework):
# 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/segwit.py b/qa/rpc-tests/segwit.py
index f480e5c3f9..5b1fba8eec 100755
--- a/qa/rpc-tests/segwit.py
+++ b/qa/rpc-tests/segwit.py
@@ -6,11 +6,11 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
-from test_framework.mininode import sha256, ripemd160, CTransaction, CTxIn, COutPoint, CTxOut
+from test_framework.mininode import sha256, ripemd160, CTransaction, CTxIn, COutPoint, CTxOut, COIN
from test_framework.address import script_to_p2sh, key_to_p2pkh
-from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG
+from test_framework.script import CScript, OP_HASH160, OP_CHECKSIG, OP_0, hash160, OP_EQUAL, OP_DUP, OP_EQUALVERIFY, OP_1, OP_2, OP_CHECKMULTISIG, hash160, OP_TRUE
from io import BytesIO
-from test_framework.mininode import FromHex
+from test_framework.mininode import ToHex, FromHex, COIN
NODE_0 = 0
NODE_1 = 1
@@ -18,47 +18,49 @@ NODE_2 = 2
WIT_V0 = 0
WIT_V1 = 1
-def witness_script(version, pubkey):
- if (version == 0):
- pubkeyhash = bytes_to_hex_str(ripemd160(sha256(hex_str_to_bytes(pubkey))))
- pkscript = "0014" + pubkeyhash
- elif (version == 1):
- # 1-of-1 multisig
- scripthash = bytes_to_hex_str(sha256(hex_str_to_bytes("5121" + pubkey + "51ae")))
- pkscript = "0020" + scripthash
+# Create a scriptPubKey corresponding to either a P2WPKH output for the
+# given pubkey, or a P2WSH output of a 1-of-1 multisig for the given
+# pubkey. Returns the hex encoding of the scriptPubKey.
+def witness_script(use_p2wsh, pubkey):
+ if (use_p2wsh == False):
+ # P2WPKH instead
+ pubkeyhash = hash160(hex_str_to_bytes(pubkey))
+ pkscript = CScript([OP_0, pubkeyhash])
else:
- assert("Wrong version" == "0 or 1")
- return pkscript
-
-def addlength(script):
- scriptlen = format(len(script)//2, 'x')
- assert(len(scriptlen) == 2)
- return scriptlen + script
-
-def create_witnessprogram(version, node, utxo, pubkey, encode_p2sh, amount):
- pkscript = witness_script(version, pubkey)
+ # 1-of-1 multisig
+ witness_program = CScript([OP_1, hex_str_to_bytes(pubkey), OP_1, OP_CHECKMULTISIG])
+ scripthash = sha256(witness_program)
+ pkscript = CScript([OP_0, scripthash])
+ return bytes_to_hex_str(pkscript)
+
+# Return a transaction (in hex) that spends the given utxo to a segwit output,
+# optionally wrapping the segwit output using P2SH.
+def create_witnessprogram(use_p2wsh, utxo, pubkey, encode_p2sh, amount):
+ pkscript = hex_str_to_bytes(witness_script(use_p2wsh, pubkey))
if (encode_p2sh):
- p2sh_hash = bytes_to_hex_str(ripemd160(sha256(hex_str_to_bytes(pkscript))))
- pkscript = "a914"+p2sh_hash+"87"
- inputs = []
- outputs = {}
- inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]} )
- DUMMY_P2SH = "2MySexEGVzZpRgNQ1JdjdP5bRETznm3roQ2" # P2SH of "OP_1 OP_DROP"
- outputs[DUMMY_P2SH] = amount
- tx_to_witness = node.createrawtransaction(inputs,outputs)
- #replace dummy output with our own
- tx_to_witness = tx_to_witness[0:110] + addlength(pkscript) + tx_to_witness[-8:]
- return tx_to_witness
-
-def send_to_witness(version, node, utxo, pubkey, encode_p2sh, amount, sign=True, insert_redeem_script=""):
- tx_to_witness = create_witnessprogram(version, node, utxo, pubkey, encode_p2sh, amount)
+ p2sh_hash = hash160(pkscript)
+ pkscript = CScript([OP_HASH160, p2sh_hash, OP_EQUAL])
+ tx = CTransaction()
+ tx.vin.append(CTxIn(COutPoint(int(utxo["txid"], 16), utxo["vout"]), b""))
+ tx.vout.append(CTxOut(int(amount*COIN), pkscript))
+ return ToHex(tx)
+
+# Create a transaction spending a given utxo to a segwit output corresponding
+# to the given pubkey: use_p2wsh determines whether to use P2WPKH or P2WSH;
+# encode_p2sh determines whether to wrap in P2SH.
+# sign=True will have the given node sign the transaction.
+# insert_redeem_script will be added to the scriptSig, if given.
+def send_to_witness(use_p2wsh, node, utxo, pubkey, encode_p2sh, amount, sign=True, insert_redeem_script=""):
+ tx_to_witness = create_witnessprogram(use_p2wsh, utxo, pubkey, encode_p2sh, amount)
if (sign):
signed = node.signrawtransaction(tx_to_witness)
assert("errors" not in signed or len(["errors"]) == 0)
return node.sendrawtransaction(signed["hex"])
else:
if (insert_redeem_script):
- tx_to_witness = tx_to_witness[0:82] + addlength(insert_redeem_script) + tx_to_witness[84:]
+ tx = FromHex(CTransaction(), tx_to_witness)
+ tx.vin[0].scriptSig += CScript([hex_str_to_bytes(insert_redeem_script)])
+ tx_to_witness = ToHex(tx)
return node.sendrawtransaction(tx_to_witness)
@@ -103,22 +105,12 @@ class SegWitTest(BitcoinTestFramework):
assert_equal(len(node.getblock(block[0])["tx"]), 1)
sync_blocks(self.nodes)
- def fail_accept(self, node, txid, sign, redeem_script=""):
- try:
- send_to_witness(1, node, getutxo(txid), self.pubkey[0], False, Decimal("49.998"), sign, redeem_script)
- except JSONRPCException as exp:
- assert(exp.error["code"] == -26)
- else:
- raise AssertionError("Tx should not have been accepted")
+ def fail_accept(self, node, error_msg, txid, sign, redeem_script=""):
+ assert_raises_jsonrpc(-26, error_msg, send_to_witness, 1, node, getutxo(txid), self.pubkey[0], False, Decimal("49.998"), sign, redeem_script)
def fail_mine(self, node, txid, sign, redeem_script=""):
send_to_witness(1, node, getutxo(txid), self.pubkey[0], False, Decimal("49.998"), sign, redeem_script)
- try:
- node.generate(1)
- except JSONRPCException as exp:
- assert(exp.error["code"] == -1)
- else:
- raise AssertionError("Created valid block when TestBlockValidity should have failed")
+ assert_raises_jsonrpc(-1, "CreateNewBlock: TestBlockValidity failed", node.generate, 1)
sync_blocks(self.nodes)
def run_test(self):
@@ -175,18 +167,18 @@ class SegWitTest(BitcoinTestFramework):
self.log.info("Verify default node can't accept any witness format txs before fork")
# unsigned, no scriptsig
- self.fail_accept(self.nodes[0], wit_ids[NODE_0][WIT_V0][0], False)
- self.fail_accept(self.nodes[0], wit_ids[NODE_0][WIT_V1][0], False)
- self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], False)
- self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], False)
+ self.fail_accept(self.nodes[0], "mandatory-script-verify-flag", wit_ids[NODE_0][WIT_V0][0], False)
+ self.fail_accept(self.nodes[0], "mandatory-script-verify-flag", wit_ids[NODE_0][WIT_V1][0], False)
+ self.fail_accept(self.nodes[0], "mandatory-script-verify-flag", p2sh_ids[NODE_0][WIT_V0][0], False)
+ self.fail_accept(self.nodes[0], "mandatory-script-verify-flag", p2sh_ids[NODE_0][WIT_V1][0], False)
# unsigned with redeem script
- self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], False, addlength(witness_script(0, self.pubkey[0])))
- self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], False, addlength(witness_script(1, self.pubkey[0])))
+ self.fail_accept(self.nodes[0], "mandatory-script-verify-flag", p2sh_ids[NODE_0][WIT_V0][0], False, witness_script(False, self.pubkey[0]))
+ self.fail_accept(self.nodes[0], "mandatory-script-verify-flag", p2sh_ids[NODE_0][WIT_V1][0], False, witness_script(True, self.pubkey[0]))
# signed
- self.fail_accept(self.nodes[0], wit_ids[NODE_0][WIT_V0][0], True)
- self.fail_accept(self.nodes[0], wit_ids[NODE_0][WIT_V1][0], True)
- self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V0][0], True)
- self.fail_accept(self.nodes[0], p2sh_ids[NODE_0][WIT_V1][0], True)
+ self.fail_accept(self.nodes[0], "no-witness-yet", wit_ids[NODE_0][WIT_V0][0], True)
+ self.fail_accept(self.nodes[0], "no-witness-yet", wit_ids[NODE_0][WIT_V1][0], True)
+ self.fail_accept(self.nodes[0], "no-witness-yet", p2sh_ids[NODE_0][WIT_V0][0], True)
+ self.fail_accept(self.nodes[0], "no-witness-yet", p2sh_ids[NODE_0][WIT_V1][0], True)
self.log.info("Verify witness txs are skipped for mining before the fork")
self.skip_mine(self.nodes[2], wit_ids[NODE_2][WIT_V0][0], True) #block 424
@@ -201,12 +193,12 @@ class SegWitTest(BitcoinTestFramework):
self.success_mine(self.nodes[2], wit_ids[NODE_2][WIT_V1][1], False) #block 429
self.log.info("Verify unsigned p2sh witness txs without a redeem script are invalid")
- self.fail_accept(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][1], False)
- self.fail_accept(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][1], False)
+ self.fail_accept(self.nodes[2], "mandatory-script-verify-flag", p2sh_ids[NODE_2][WIT_V0][1], False)
+ self.fail_accept(self.nodes[2], "mandatory-script-verify-flag", p2sh_ids[NODE_2][WIT_V1][1], False)
self.log.info("Verify unsigned p2sh witness txs with a redeem script in versionbits-settings blocks are valid before the fork")
- self.success_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][1], False, addlength(witness_script(0, self.pubkey[2]))) #block 430
- self.success_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][1], False, addlength(witness_script(1, self.pubkey[2]))) #block 431
+ self.success_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][1], False, witness_script(False, self.pubkey[2])) #block 430
+ self.success_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][1], False, witness_script(True, self.pubkey[2])) #block 431
self.log.info("Verify previous witness txs skipped for mining can now be mined")
assert_equal(len(self.nodes[2].getrawmempool()), 4)
@@ -230,8 +222,8 @@ class SegWitTest(BitcoinTestFramework):
self.log.info("Verify witness txs without witness data are invalid after the fork")
self.fail_mine(self.nodes[2], wit_ids[NODE_2][WIT_V0][2], False)
self.fail_mine(self.nodes[2], wit_ids[NODE_2][WIT_V1][2], False)
- self.fail_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][2], False, addlength(witness_script(0, self.pubkey[2])))
- self.fail_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][2], False, addlength(witness_script(1, self.pubkey[2])))
+ self.fail_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V0][2], False, witness_script(False, self.pubkey[2]))
+ self.fail_mine(self.nodes[2], p2sh_ids[NODE_2][WIT_V1][2], False, witness_script(True, self.pubkey[2]))
self.log.info("Verify default node can now use witness txs")
self.success_mine(self.nodes[0], wit_ids[NODE_0][WIT_V0][0], True) #block 432
@@ -248,9 +240,54 @@ class SegWitTest(BitcoinTestFramework):
assert(tmpl['transactions'][0]['txid'] == txid)
assert(tmpl['transactions'][0]['sigops'] == 8)
- self.log.info("Non-segwit miners are not able to use GBT response after activation.")
- send_to_witness(1, self.nodes[0], find_unspent(self.nodes[0], 50), self.pubkey[0], False, Decimal("49.998"))
- assert_raises_jsonrpc(-8, "Support for 'segwit' rule requires explicit client support", self.nodes[0].getblocktemplate, {})
+ self.nodes[0].generate(1) # Mine a block to clear the gbt cache
+
+ self.log.info("Non-segwit miners are able to use GBT response after activation.")
+ # Create a 3-tx chain: tx1 (non-segwit input, paying to a segwit output) ->
+ # tx2 (segwit input, paying to a non-segwit output) ->
+ # tx3 (non-segwit input, paying to a non-segwit output).
+ # tx1 is allowed to appear in the block, but no others.
+ txid1 = send_to_witness(1, self.nodes[0], find_unspent(self.nodes[0], 50), self.pubkey[0], False, Decimal("49.996"))
+ hex_tx = self.nodes[0].gettransaction(txid)['hex']
+ tx = FromHex(CTransaction(), hex_tx)
+ assert(tx.wit.is_null()) # This should not be a segwit input
+ assert(txid1 in self.nodes[0].getrawmempool())
+
+ # Now create tx2, which will spend from txid1.
+ tx = CTransaction()
+ tx.vin.append(CTxIn(COutPoint(int(txid1, 16), 0), b''))
+ tx.vout.append(CTxOut(int(49.99*COIN), CScript([OP_TRUE])))
+ tx2_hex = self.nodes[0].signrawtransaction(ToHex(tx))['hex']
+ txid2 = self.nodes[0].sendrawtransaction(tx2_hex)
+ tx = FromHex(CTransaction(), tx2_hex)
+ assert(not tx.wit.is_null())
+
+ # Now create tx3, which will spend from txid2
+ tx = CTransaction()
+ tx.vin.append(CTxIn(COutPoint(int(txid2, 16), 0), b""))
+ tx.vout.append(CTxOut(int(49.95*COIN), CScript([OP_TRUE]))) # Huge fee
+ tx.calc_sha256()
+ txid3 = self.nodes[0].sendrawtransaction(ToHex(tx))
+ assert(tx.wit.is_null())
+ assert(txid3 in self.nodes[0].getrawmempool())
+
+ # Now try calling getblocktemplate() without segwit support.
+ template = self.nodes[0].getblocktemplate()
+
+ # Check that tx1 is the only transaction of the 3 in the template.
+ template_txids = [ t['txid'] for t in template['transactions'] ]
+ assert(txid2 not in template_txids and txid3 not in template_txids)
+ assert(txid1 in template_txids)
+
+ # Check that running with segwit support results in all 3 being included.
+ template = self.nodes[0].getblocktemplate({"rules": ["segwit"]})
+ template_txids = [ t['txid'] for t in template['transactions'] ]
+ assert(txid1 in template_txids)
+ assert(txid2 in template_txids)
+ assert(txid3 in template_txids)
+
+ # Mine a block to clear the gbt cache again.
+ self.nodes[0].generate(1)
self.log.info("Verify behaviour of importaddress, addwitnessaddress and listunspent")
@@ -410,10 +447,13 @@ class SegWitTest(BitcoinTestFramework):
importlist.append(bytes_to_hex_str(p2wshop1))
for i in importlist:
+ # import all generated addresses. The wallet already has the private keys for some of these, so catch JSON RPC
+ # exceptions and continue.
try:
self.nodes[0].importaddress(i,"",False,True)
except JSONRPCException as exp:
assert_equal(exp.error["message"], "The wallet already contains the private key for this address or script")
+ assert_equal(exp.error["code"], -4)
self.nodes[0].importaddress(script_to_p2sh(op0)) # import OP_0 as address only
self.nodes[0].importaddress(multisig_without_privkey_address) # Test multisig_without_privkey
@@ -428,12 +468,7 @@ class SegWitTest(BitcoinTestFramework):
# note that no witness address should be returned by unsolvable addresses
# the multisig_without_privkey_address will fail because its keys were not added with importpubkey
for i in uncompressed_spendable_address + uncompressed_solvable_address + unknown_address + unsolvable_address + [multisig_without_privkey_address]:
- try:
- self.nodes[0].addwitnessaddress(i)
- except JSONRPCException as exp:
- assert_equal(exp.error["message"], "Public key or redeemscript not known to wallet, or the key is uncompressed")
- else:
- assert(False)
+ assert_raises_jsonrpc(-4, "Public key or redeemscript not known to wallet, or the key is uncompressed", self.nodes[0].addwitnessaddress, i)
for i in compressed_spendable_address + compressed_solvable_address:
witaddress = self.nodes[0].addwitnessaddress(i)
@@ -512,12 +547,8 @@ class SegWitTest(BitcoinTestFramework):
# note that a multisig address returned by addmultisigaddress is not solvable until it is added with importaddress
# premature_witaddress are not accepted until the script is added with addwitnessaddress first
for i in uncompressed_spendable_address + uncompressed_solvable_address + premature_witaddress + [compressed_solvable_address[1]]:
- try:
- self.nodes[0].addwitnessaddress(i)
- except JSONRPCException as exp:
- assert_equal(exp.error["message"], "Public key or redeemscript not known to wallet, or the key is uncompressed")
- else:
- assert(False)
+ # This will raise an exception
+ assert_raises_jsonrpc(-4, "Public key or redeemscript not known to wallet, or the key is uncompressed", self.nodes[0].addwitnessaddress, i)
# after importaddress it should pass addwitnessaddress
v = self.nodes[0].validateaddress(compressed_solvable_address[1])
diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py
index 6fcfd0caac..49f2df5c37 100755
--- a/qa/rpc-tests/smartfees.py
+++ b/qa/rpc-tests/smartfees.py
@@ -7,15 +7,19 @@
from collections import OrderedDict
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
+from test_framework.script import CScript, OP_1, OP_DROP, OP_2, OP_HASH160, OP_EQUAL, hash160, OP_TRUE
+from test_framework.mininode import CTransaction, CTxIn, CTxOut, COutPoint, ToHex, FromHex, COIN
# Construct 2 trivial P2SH's and the ScriptSigs that spend them
# So we can create many many transactions without needing to spend
# time signing.
-P2SH_1 = "2MySexEGVzZpRgNQ1JdjdP5bRETznm3roQ2" # P2SH of "OP_1 OP_DROP"
-P2SH_2 = "2NBdpwq8Aoo1EEKEXPNrKvr5xQr3M9UfcZA" # P2SH of "OP_2 OP_DROP"
+redeem_script_1 = CScript([OP_1, OP_DROP])
+redeem_script_2 = CScript([OP_2, OP_DROP])
+P2SH_1 = CScript([OP_HASH160, hash160(redeem_script_1), OP_EQUAL])
+P2SH_2 = CScript([OP_HASH160, hash160(redeem_script_2), OP_EQUAL])
+
# Associated ScriptSig's to spend satisfy P2SH_1 and P2SH_2
-# 4 bytes of OP_TRUE and push 2-byte redeem script of "OP_1 OP_DROP" or "OP_2 OP_DROP"
-SCRIPT_SIG = ["0451025175", "0451025275"]
+SCRIPT_SIG = [CScript([OP_TRUE, redeem_script_1]), CScript([OP_TRUE, redeem_script_2])]
global log
@@ -35,39 +39,30 @@ def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee
rand_fee = float(fee_increment)*(1.1892**random.randint(0,28))
# Total fee ranges from min_fee to min_fee + 127*fee_increment
fee = min_fee - fee_increment + satoshi_round(rand_fee)
- inputs = []
+ tx = CTransaction()
total_in = Decimal("0.00000000")
while total_in <= (amount + fee) and len(conflist) > 0:
t = conflist.pop(0)
total_in += t["amount"]
- inputs.append({ "txid" : t["txid"], "vout" : t["vout"]} )
+ tx.vin.append(CTxIn(COutPoint(int(t["txid"], 16), t["vout"]), b""))
if total_in <= amount + fee:
while total_in <= (amount + fee) and len(unconflist) > 0:
t = unconflist.pop(0)
total_in += t["amount"]
- inputs.append({ "txid" : t["txid"], "vout" : t["vout"]} )
+ tx.vin.append(CTxIn(COutPoint(int(t["txid"], 16), t["vout"]), b""))
if total_in <= amount + fee:
raise RuntimeError("Insufficient funds: need %d, have %d"%(amount+fee, total_in))
- outputs = {}
- outputs = OrderedDict([(P2SH_1, total_in - amount - fee),
- (P2SH_2, amount)])
- rawtx = from_node.createrawtransaction(inputs, outputs)
- # createrawtransaction constructs a transaction that is ready to be signed.
- # These transactions don't need to be signed, but we still have to insert the ScriptSig
- # that will satisfy the ScriptPubKey.
- completetx = rawtx[0:10]
- inputnum = 0
- for inp in inputs:
- completetx += rawtx[10+82*inputnum:82+82*inputnum]
- completetx += SCRIPT_SIG[inp["vout"]]
- completetx += rawtx[84+82*inputnum:92+82*inputnum]
- inputnum += 1
- completetx += rawtx[10+82*inputnum:]
- txid = from_node.sendrawtransaction(completetx, True)
+ tx.vout.append(CTxOut(int((total_in - amount - fee)*COIN), P2SH_1))
+ tx.vout.append(CTxOut(int(amount*COIN), P2SH_2))
+ # These transactions don't need to be signed, but we still have to insert
+ # the ScriptSig that will satisfy the ScriptPubKey.
+ for inp in tx.vin:
+ inp.scriptSig = SCRIPT_SIG[inp.prevout.n]
+ txid = from_node.sendrawtransaction(ToHex(tx), True)
unconflist.append({ "txid" : txid, "vout" : 0 , "amount" : total_in - amount - fee})
unconflist.append({ "txid" : txid, "vout" : 1 , "amount" : amount})
- return (completetx, fee)
+ return (ToHex(tx), fee)
def split_inputs(from_node, txins, txouts, initial_split = False):
"""
@@ -78,18 +73,21 @@ def split_inputs(from_node, txins, txouts, initial_split = False):
a high coin age when the notion of priority still existed.
"""
prevtxout = txins.pop()
- inputs = []
- inputs.append({ "txid" : prevtxout["txid"], "vout" : prevtxout["vout"] })
+ tx = CTransaction()
+ tx.vin.append(CTxIn(COutPoint(int(prevtxout["txid"], 16), prevtxout["vout"]), b""))
+
half_change = satoshi_round(prevtxout["amount"]/2)
rem_change = prevtxout["amount"] - half_change - Decimal("0.00001000")
- outputs = OrderedDict([(P2SH_1, half_change), (P2SH_2, rem_change)])
- rawtx = from_node.createrawtransaction(inputs, outputs)
+ tx.vout.append(CTxOut(int(half_change*COIN), P2SH_1))
+ tx.vout.append(CTxOut(int(rem_change*COIN), P2SH_2))
+
# If this is the initial split we actually need to sign the transaction
- # Otherwise we just need to insert the property ScriptSig
+ # Otherwise we just need to insert the proper ScriptSig
if (initial_split) :
- completetx = from_node.signrawtransaction(rawtx)["hex"]
+ completetx = from_node.signrawtransaction(ToHex(tx))["hex"]
else :
- completetx = rawtx[0:82] + SCRIPT_SIG[prevtxout["vout"]] + rawtx[84:]
+ tx.vin[0].scriptSig = SCRIPT_SIG[prevtxout["vout"]]
+ completetx = ToHex(tx)
txid = from_node.sendrawtransaction(completetx, True)
txouts.append({ "txid" : txid, "vout" : 0 , "amount" : half_change})
txouts.append({ "txid" : txid, "vout" : 1 , "amount" : rem_change})
diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py
index 00fe37563b..80f74fa108 100755
--- a/qa/rpc-tests/wallet.py
+++ b/qa/rpc-tests/wallet.py
@@ -71,7 +71,7 @@ class WalletTest (BitcoinTestFramework):
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(), 20)
+ assert_raises_jsonrpc(-4, "Insufficient funds", self.nodes[2].sendtoaddress, self.nodes[2].getnewaddress(), 20)
assert_equal([unspent_0], self.nodes[2].listlockunspent())
self.nodes[2].lockunspent(True, [unspent_0])
assert_equal(len(self.nodes[2].listlockunspent()), 0)
@@ -251,19 +251,11 @@ class WalletTest (BitcoinTestFramework):
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
@@ -394,7 +386,7 @@ class WalletTest (BitcoinTestFramework):
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)))