[tests] Fix flake8 warnings in several wallet functional tests
This commit fixes flake8 warnings in the following functional tests: - wallet_listreceivedby.py - wallet_basic.py - wallet_txn_clone.py - wallet_listsinceblock.py - wallet_import_rescan.py - wallet_listtransactions.py - wallet_importprunedfunds.py - wallet_txn_doublspend.py
This commit is contained in:
parent
3186ad4a81
commit
a533834d50
8 changed files with 231 additions and 211 deletions
|
@ -3,8 +3,20 @@
|
||||||
# Distributed under the MIT software license, see the accompanying
|
# Distributed under the MIT software license, see the accompanying
|
||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
"""Test the wallet."""
|
"""Test the wallet."""
|
||||||
|
from decimal import Decimal
|
||||||
|
import time
|
||||||
|
|
||||||
from test_framework.test_framework import BitcoinTestFramework
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
from test_framework.util import *
|
from test_framework.util import (
|
||||||
|
assert_array_result,
|
||||||
|
assert_equal,
|
||||||
|
assert_fee_amount,
|
||||||
|
assert_raises_rpc_error,
|
||||||
|
connect_nodes_bi,
|
||||||
|
sync_blocks,
|
||||||
|
sync_mempools,
|
||||||
|
wait_until,
|
||||||
|
)
|
||||||
|
|
||||||
class WalletTest(BitcoinTestFramework):
|
class WalletTest(BitcoinTestFramework):
|
||||||
def set_test_params(self):
|
def set_test_params(self):
|
||||||
|
@ -17,9 +29,9 @@ class WalletTest(BitcoinTestFramework):
|
||||||
self.start_node(0)
|
self.start_node(0)
|
||||||
self.start_node(1)
|
self.start_node(1)
|
||||||
self.start_node(2)
|
self.start_node(2)
|
||||||
connect_nodes_bi(self.nodes,0,1)
|
connect_nodes_bi(self.nodes, 0, 1)
|
||||||
connect_nodes_bi(self.nodes,1,2)
|
connect_nodes_bi(self.nodes, 1, 2)
|
||||||
connect_nodes_bi(self.nodes,0,2)
|
connect_nodes_bi(self.nodes, 0, 2)
|
||||||
self.sync_all([self.nodes[0:3]])
|
self.sync_all([self.nodes[0:3]])
|
||||||
|
|
||||||
def check_fee_amount(self, curr_balance, balance_with_fee, fee_per_byte, tx_size):
|
def check_fee_amount(self, curr_balance, balance_with_fee, fee_per_byte, tx_size):
|
||||||
|
@ -112,11 +124,11 @@ class WalletTest(BitcoinTestFramework):
|
||||||
self.nodes[2].lockunspent(True, [unspent_0])
|
self.nodes[2].lockunspent(True, [unspent_0])
|
||||||
assert_equal(len(self.nodes[2].listlockunspent()), 0)
|
assert_equal(len(self.nodes[2].listlockunspent()), 0)
|
||||||
assert_raises_rpc_error(-8, "Invalid parameter, unknown transaction",
|
assert_raises_rpc_error(-8, "Invalid parameter, unknown transaction",
|
||||||
self.nodes[2].lockunspent, False,
|
self.nodes[2].lockunspent, False,
|
||||||
[{"txid": "0000000000000000000000000000000000", "vout": 0}])
|
[{"txid": "0000000000000000000000000000000000", "vout": 0}])
|
||||||
assert_raises_rpc_error(-8, "Invalid parameter, vout index out of bounds",
|
assert_raises_rpc_error(-8, "Invalid parameter, vout index out of bounds",
|
||||||
self.nodes[2].lockunspent, False,
|
self.nodes[2].lockunspent, False,
|
||||||
[{"txid": unspent_0["txid"], "vout": 999}])
|
[{"txid": unspent_0["txid"], "vout": 999}])
|
||||||
|
|
||||||
# Have node1 generate 100 blocks (so node0 can recover the fee)
|
# Have node1 generate 100 blocks (so node0 can recover the fee)
|
||||||
self.nodes[1].generate(100)
|
self.nodes[1].generate(100)
|
||||||
|
@ -124,7 +136,7 @@ class WalletTest(BitcoinTestFramework):
|
||||||
|
|
||||||
# node0 should end up with 100 btc in block rewards plus fees, but
|
# node0 should end up with 100 btc in block rewards plus fees, but
|
||||||
# minus the 21 plus fees sent to node2
|
# minus the 21 plus fees sent to node2
|
||||||
assert_equal(self.nodes[0].getbalance(), 100-21)
|
assert_equal(self.nodes[0].getbalance(), 100 - 21)
|
||||||
assert_equal(self.nodes[2].getbalance(), 21)
|
assert_equal(self.nodes[2].getbalance(), 21)
|
||||||
|
|
||||||
# Node0 should have two unspent outputs.
|
# Node0 should have two unspent outputs.
|
||||||
|
@ -138,7 +150,7 @@ class WalletTest(BitcoinTestFramework):
|
||||||
for utxo in node0utxos:
|
for utxo in node0utxos:
|
||||||
inputs = []
|
inputs = []
|
||||||
outputs = {}
|
outputs = {}
|
||||||
inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]})
|
inputs.append({"txid": utxo["txid"], "vout": utxo["vout"]})
|
||||||
outputs[self.nodes[2].getnewaddress("from1")] = utxo["amount"] - 3
|
outputs[self.nodes[2].getnewaddress("from1")] = utxo["amount"] - 3
|
||||||
raw_tx = self.nodes[0].createrawtransaction(inputs, outputs)
|
raw_tx = self.nodes[0].createrawtransaction(inputs, outputs)
|
||||||
txns_to_send.append(self.nodes[0].signrawtransactionwithwallet(raw_tx))
|
txns_to_send.append(self.nodes[0].signrawtransactionwithwallet(raw_tx))
|
||||||
|
@ -153,7 +165,7 @@ class WalletTest(BitcoinTestFramework):
|
||||||
|
|
||||||
assert_equal(self.nodes[0].getbalance(), 0)
|
assert_equal(self.nodes[0].getbalance(), 0)
|
||||||
assert_equal(self.nodes[2].getbalance(), 94)
|
assert_equal(self.nodes[2].getbalance(), 94)
|
||||||
assert_equal(self.nodes[2].getbalance("from1"), 94-21)
|
assert_equal(self.nodes[2].getbalance("from1"), 94 - 21)
|
||||||
|
|
||||||
# Verify that a spent output cannot be locked anymore
|
# Verify that a spent output cannot be locked anymore
|
||||||
spent_0 = {"txid": node0utxos[0]["txid"], "vout": node0utxos[0]["vout"]}
|
spent_0 = {"txid": node0utxos[0]["txid"], "vout": node0utxos[0]["vout"]}
|
||||||
|
@ -215,91 +227,90 @@ class WalletTest(BitcoinTestFramework):
|
||||||
assert_equal(self.nodes[0].getwalletinfo()["unconfirmed_balance"], 1)
|
assert_equal(self.nodes[0].getwalletinfo()["unconfirmed_balance"], 1)
|
||||||
assert_equal(self.nodes[0].getunconfirmedbalance(), 1)
|
assert_equal(self.nodes[0].getunconfirmedbalance(), 1)
|
||||||
|
|
||||||
#check if we can list zero value tx as available coins
|
# check if we can list zero value tx as available coins
|
||||||
#1. create rawtx
|
# 1. create raw_tx
|
||||||
#2. hex-changed one output to 0.0
|
# 2. hex-changed one output to 0.0
|
||||||
#3. sign and send
|
# 3. sign and send
|
||||||
#4. check if recipient (node0) can list the zero value tx
|
# 4. check if recipient (node0) can list the zero value tx
|
||||||
usp = self.nodes[1].listunspent()
|
usp = self.nodes[1].listunspent()
|
||||||
inputs = [{"txid":usp[0]['txid'], "vout":usp[0]['vout']}]
|
inputs = [{"txid": usp[0]['txid'], "vout": usp[0]['vout']}]
|
||||||
outputs = {self.nodes[1].getnewaddress(): 49.998, self.nodes[0].getnewaddress(): 11.11}
|
outputs = {self.nodes[1].getnewaddress(): 49.998, self.nodes[0].getnewaddress(): 11.11}
|
||||||
|
|
||||||
rawTx = self.nodes[1].createrawtransaction(inputs, outputs).replace("c0833842", "00000000") #replace 11.11 with 0.0 (int32)
|
raw_tx = self.nodes[1].createrawtransaction(inputs, outputs).replace("c0833842", "00000000") # replace 11.11 with 0.0 (int32)
|
||||||
decRawTx = self.nodes[1].decoderawtransaction(rawTx)
|
signed_raw_tx = self.nodes[1].signrawtransactionwithwallet(raw_tx)
|
||||||
signedRawTx = self.nodes[1].signrawtransactionwithwallet(rawTx)
|
decoded_raw_tx = self.nodes[1].decoderawtransaction(signed_raw_tx['hex'])
|
||||||
decRawTx = self.nodes[1].decoderawtransaction(signedRawTx['hex'])
|
zero_value_txid = decoded_raw_tx['txid']
|
||||||
zeroValueTxid= decRawTx['txid']
|
self.nodes[1].sendrawtransaction(signed_raw_tx['hex'])
|
||||||
self.nodes[1].sendrawtransaction(signedRawTx['hex'])
|
|
||||||
|
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
self.nodes[1].generate(1) #mine a block
|
self.nodes[1].generate(1) # mine a block
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
|
|
||||||
unspentTxs = self.nodes[0].listunspent() #zero value tx must be in listunspents output
|
unspent_txs = self.nodes[0].listunspent() # zero value tx must be in listunspents output
|
||||||
found = False
|
found = False
|
||||||
for uTx in unspentTxs:
|
for uTx in unspent_txs:
|
||||||
if uTx['txid'] == zeroValueTxid:
|
if uTx['txid'] == zero_value_txid:
|
||||||
found = True
|
found = True
|
||||||
assert_equal(uTx['amount'], Decimal('0'))
|
assert_equal(uTx['amount'], Decimal('0'))
|
||||||
assert(found)
|
assert(found)
|
||||||
|
|
||||||
#do some -walletbroadcast tests
|
# do some -walletbroadcast tests
|
||||||
self.stop_nodes()
|
self.stop_nodes()
|
||||||
self.start_node(0, ["-walletbroadcast=0"])
|
self.start_node(0, ["-walletbroadcast=0"])
|
||||||
self.start_node(1, ["-walletbroadcast=0"])
|
self.start_node(1, ["-walletbroadcast=0"])
|
||||||
self.start_node(2, ["-walletbroadcast=0"])
|
self.start_node(2, ["-walletbroadcast=0"])
|
||||||
connect_nodes_bi(self.nodes,0,1)
|
connect_nodes_bi(self.nodes, 0, 1)
|
||||||
connect_nodes_bi(self.nodes,1,2)
|
connect_nodes_bi(self.nodes, 1, 2)
|
||||||
connect_nodes_bi(self.nodes,0,2)
|
connect_nodes_bi(self.nodes, 0, 2)
|
||||||
self.sync_all([self.nodes[0:3]])
|
self.sync_all([self.nodes[0:3]])
|
||||||
|
|
||||||
txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2)
|
txid_not_broadcast = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2)
|
||||||
txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted)
|
tx_obj_not_broadcast = self.nodes[0].gettransaction(txid_not_broadcast)
|
||||||
self.nodes[1].generate(1) #mine a block, tx should not be in there
|
self.nodes[1].generate(1) # mine a block, tx should not be in there
|
||||||
self.sync_all([self.nodes[0:3]])
|
self.sync_all([self.nodes[0:3]])
|
||||||
assert_equal(self.nodes[2].getbalance(), node_2_bal) #should not be changed because tx was not broadcasted
|
assert_equal(self.nodes[2].getbalance(), node_2_bal) # should not be changed because tx was not broadcasted
|
||||||
|
|
||||||
#now broadcast from another node, mine a block, sync, and check the balance
|
# now broadcast from another node, mine a block, sync, and check the balance
|
||||||
self.nodes[1].sendrawtransaction(txObjNotBroadcasted['hex'])
|
self.nodes[1].sendrawtransaction(tx_obj_not_broadcast['hex'])
|
||||||
self.nodes[1].generate(1)
|
self.nodes[1].generate(1)
|
||||||
self.sync_all([self.nodes[0:3]])
|
self.sync_all([self.nodes[0:3]])
|
||||||
node_2_bal += 2
|
node_2_bal += 2
|
||||||
txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted)
|
tx_obj_not_broadcast = self.nodes[0].gettransaction(txid_not_broadcast)
|
||||||
assert_equal(self.nodes[2].getbalance(), node_2_bal)
|
assert_equal(self.nodes[2].getbalance(), node_2_bal)
|
||||||
|
|
||||||
#create another tx
|
# create another tx
|
||||||
txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2)
|
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 2)
|
||||||
|
|
||||||
#restart the nodes with -walletbroadcast=1
|
# restart the nodes with -walletbroadcast=1
|
||||||
self.stop_nodes()
|
self.stop_nodes()
|
||||||
self.start_node(0)
|
self.start_node(0)
|
||||||
self.start_node(1)
|
self.start_node(1)
|
||||||
self.start_node(2)
|
self.start_node(2)
|
||||||
connect_nodes_bi(self.nodes,0,1)
|
connect_nodes_bi(self.nodes, 0, 1)
|
||||||
connect_nodes_bi(self.nodes,1,2)
|
connect_nodes_bi(self.nodes, 1, 2)
|
||||||
connect_nodes_bi(self.nodes,0,2)
|
connect_nodes_bi(self.nodes, 0, 2)
|
||||||
sync_blocks(self.nodes[0:3])
|
sync_blocks(self.nodes[0:3])
|
||||||
|
|
||||||
self.nodes[0].generate(1)
|
self.nodes[0].generate(1)
|
||||||
sync_blocks(self.nodes[0:3])
|
sync_blocks(self.nodes[0:3])
|
||||||
node_2_bal += 2
|
node_2_bal += 2
|
||||||
|
|
||||||
#tx should be added to balance because after restarting the nodes tx should be broadcast
|
# tx should be added to balance because after restarting the nodes tx should be broadcast
|
||||||
assert_equal(self.nodes[2].getbalance(), node_2_bal)
|
assert_equal(self.nodes[2].getbalance(), node_2_bal)
|
||||||
|
|
||||||
#send a tx with value in a string (PR#6380 +)
|
# send a tx with value in a string (PR#6380 +)
|
||||||
txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "2")
|
txid = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "2")
|
||||||
txObj = self.nodes[0].gettransaction(txId)
|
tx_obj = self.nodes[0].gettransaction(txid)
|
||||||
assert_equal(txObj['amount'], Decimal('-2'))
|
assert_equal(tx_obj['amount'], Decimal('-2'))
|
||||||
|
|
||||||
txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "0.0001")
|
txid = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "0.0001")
|
||||||
txObj = self.nodes[0].gettransaction(txId)
|
tx_obj = self.nodes[0].gettransaction(txid)
|
||||||
assert_equal(txObj['amount'], Decimal('-0.0001'))
|
assert_equal(tx_obj['amount'], Decimal('-0.0001'))
|
||||||
|
|
||||||
#check if JSON parser can handle scientific notation in strings
|
# check if JSON parser can handle scientific notation in strings
|
||||||
txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1e-4")
|
txid = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1e-4")
|
||||||
txObj = self.nodes[0].gettransaction(txId)
|
tx_obj = self.nodes[0].gettransaction(txid)
|
||||||
assert_equal(txObj['amount'], Decimal('-0.0001'))
|
assert_equal(tx_obj['amount'], Decimal('-0.0001'))
|
||||||
|
|
||||||
# This will raise an exception because the amount type is wrong
|
# This will raise an exception because the amount type is wrong
|
||||||
assert_raises_rpc_error(-3, "Invalid amount", self.nodes[0].sendtoaddress, self.nodes[2].getnewaddress(), "1f-4")
|
assert_raises_rpc_error(-3, "Invalid amount", self.nodes[0].sendtoaddress, self.nodes[2].getnewaddress(), "1f-4")
|
||||||
|
@ -322,8 +333,8 @@ class WalletTest(BitcoinTestFramework):
|
||||||
|
|
||||||
# 4. Check that the unspents after import are not spendable
|
# 4. Check that the unspents after import are not spendable
|
||||||
assert_array_result(self.nodes[1].listunspent(),
|
assert_array_result(self.nodes[1].listunspent(),
|
||||||
{"address": address_to_import},
|
{"address": address_to_import},
|
||||||
{"spendable": False})
|
{"spendable": False})
|
||||||
|
|
||||||
# 5. Import private key of the previously imported address on node1
|
# 5. Import private key of the previously imported address on node1
|
||||||
priv_key = self.nodes[2].dumpprivkey(address_to_import)
|
priv_key = self.nodes[2].dumpprivkey(address_to_import)
|
||||||
|
@ -331,17 +342,17 @@ class WalletTest(BitcoinTestFramework):
|
||||||
|
|
||||||
# 6. Check that the unspents are now spendable on node1
|
# 6. Check that the unspents are now spendable on node1
|
||||||
assert_array_result(self.nodes[1].listunspent(),
|
assert_array_result(self.nodes[1].listunspent(),
|
||||||
{"address": address_to_import},
|
{"address": address_to_import},
|
||||||
{"spendable": True})
|
{"spendable": True})
|
||||||
|
|
||||||
# Mine a block from node0 to an address from node1
|
# Mine a block from node0 to an address from node1
|
||||||
cbAddr = self.nodes[1].getnewaddress()
|
coinbase_addr = self.nodes[1].getnewaddress()
|
||||||
blkHash = self.nodes[0].generatetoaddress(1, cbAddr)[0]
|
block_hash = self.nodes[0].generatetoaddress(1, coinbase_addr)[0]
|
||||||
cbTxId = self.nodes[0].getblock(blkHash)['tx'][0]
|
coinbase_txid = self.nodes[0].getblock(block_hash)['tx'][0]
|
||||||
self.sync_all([self.nodes[0:3]])
|
self.sync_all([self.nodes[0:3]])
|
||||||
|
|
||||||
# Check that the txid and balance is found by node1
|
# Check that the txid and balance is found by node1
|
||||||
self.nodes[1].gettransaction(cbTxId)
|
self.nodes[1].gettransaction(coinbase_txid)
|
||||||
|
|
||||||
# check if wallet or blockchain maintenance changes the balance
|
# check if wallet or blockchain maintenance changes the balance
|
||||||
self.sync_all([self.nodes[0:3]])
|
self.sync_all([self.nodes[0:3]])
|
||||||
|
@ -361,7 +372,7 @@ class WalletTest(BitcoinTestFramework):
|
||||||
label = self.nodes[0].getaccount(addr)
|
label = self.nodes[0].getaccount(addr)
|
||||||
assert_equal(label, s)
|
assert_equal(label, s)
|
||||||
assert(s in self.nodes[0].listaccounts().keys())
|
assert(s in self.nodes[0].listaccounts().keys())
|
||||||
self.nodes[0].ensure_ascii = True # restore to default
|
self.nodes[0].ensure_ascii = True # restore to default
|
||||||
|
|
||||||
# maintenance tests
|
# maintenance tests
|
||||||
maintenance = [
|
maintenance = [
|
||||||
|
@ -377,9 +388,9 @@ class WalletTest(BitcoinTestFramework):
|
||||||
self.log.info("check " + m)
|
self.log.info("check " + m)
|
||||||
self.stop_nodes()
|
self.stop_nodes()
|
||||||
# set lower ancestor limit for later
|
# set lower ancestor limit for later
|
||||||
self.start_node(0, [m, "-deprecatedrpc=accounts", "-limitancestorcount="+str(chainlimit)])
|
self.start_node(0, [m, "-deprecatedrpc=accounts", "-limitancestorcount=" + str(chainlimit)])
|
||||||
self.start_node(1, [m, "-deprecatedrpc=accounts", "-limitancestorcount="+str(chainlimit)])
|
self.start_node(1, [m, "-deprecatedrpc=accounts", "-limitancestorcount=" + str(chainlimit)])
|
||||||
self.start_node(2, [m, "-deprecatedrpc=accounts", "-limitancestorcount="+str(chainlimit)])
|
self.start_node(2, [m, "-deprecatedrpc=accounts", "-limitancestorcount=" + str(chainlimit)])
|
||||||
if m == '-reindex':
|
if m == '-reindex':
|
||||||
# reindex will leave rpc warm up "early"; Wait for it to finish
|
# reindex will leave rpc warm up "early"; Wait for it to finish
|
||||||
wait_until(lambda: [block_count] * 3 == [self.nodes[i].getblockcount() for i in range(3)])
|
wait_until(lambda: [block_count] * 3 == [self.nodes[i].getblockcount() for i in range(3)])
|
||||||
|
@ -400,7 +411,7 @@ class WalletTest(BitcoinTestFramework):
|
||||||
self.nodes[0].generate(1)
|
self.nodes[0].generate(1)
|
||||||
node0_balance = self.nodes[0].getbalance()
|
node0_balance = self.nodes[0].getbalance()
|
||||||
# Split into two chains
|
# Split into two chains
|
||||||
rawtx = self.nodes[0].createrawtransaction([{"txid":singletxid, "vout":0}], {chain_addrs[0]:node0_balance/2-Decimal('0.01'), chain_addrs[1]:node0_balance/2-Decimal('0.01')})
|
rawtx = self.nodes[0].createrawtransaction([{"txid": singletxid, "vout": 0}], {chain_addrs[0]: node0_balance / 2 - Decimal('0.01'), chain_addrs[1]: node0_balance / 2 - Decimal('0.01')})
|
||||||
signedtx = self.nodes[0].signrawtransactionwithwallet(rawtx)
|
signedtx = self.nodes[0].signrawtransactionwithwallet(rawtx)
|
||||||
singletxid = self.nodes[0].sendrawtransaction(signedtx["hex"])
|
singletxid = self.nodes[0].sendrawtransaction(signedtx["hex"])
|
||||||
self.nodes[0].generate(1)
|
self.nodes[0].generate(1)
|
||||||
|
@ -411,10 +422,10 @@ class WalletTest(BitcoinTestFramework):
|
||||||
# So we should be able to generate exactly chainlimit txs for each original output
|
# So we should be able to generate exactly chainlimit txs for each original output
|
||||||
sending_addr = self.nodes[1].getnewaddress()
|
sending_addr = self.nodes[1].getnewaddress()
|
||||||
txid_list = []
|
txid_list = []
|
||||||
for i in range(chainlimit*2):
|
for i in range(chainlimit * 2):
|
||||||
txid_list.append(self.nodes[0].sendtoaddress(sending_addr, Decimal('0.0001')))
|
txid_list.append(self.nodes[0].sendtoaddress(sending_addr, Decimal('0.0001')))
|
||||||
assert_equal(self.nodes[0].getmempoolinfo()['size'], chainlimit*2)
|
assert_equal(self.nodes[0].getmempoolinfo()['size'], chainlimit * 2)
|
||||||
assert_equal(len(txid_list), chainlimit*2)
|
assert_equal(len(txid_list), chainlimit * 2)
|
||||||
|
|
||||||
# Without walletrejectlongchains, we will still generate a txid
|
# Without walletrejectlongchains, we will still generate a txid
|
||||||
# The tx will be stored in the wallet but not accepted to the mempool
|
# The tx will be stored in the wallet but not accepted to the mempool
|
||||||
|
@ -422,26 +433,26 @@ class WalletTest(BitcoinTestFramework):
|
||||||
assert(extra_txid not in self.nodes[0].getrawmempool())
|
assert(extra_txid not in self.nodes[0].getrawmempool())
|
||||||
assert(extra_txid in [tx["txid"] for tx in self.nodes[0].listtransactions()])
|
assert(extra_txid in [tx["txid"] for tx in self.nodes[0].listtransactions()])
|
||||||
self.nodes[0].abandontransaction(extra_txid)
|
self.nodes[0].abandontransaction(extra_txid)
|
||||||
total_txs = len(self.nodes[0].listtransactions("*",99999))
|
total_txs = len(self.nodes[0].listtransactions("*", 99999))
|
||||||
|
|
||||||
# Try with walletrejectlongchains
|
# Try with walletrejectlongchains
|
||||||
# Double chain limit but require combining inputs, so we pass SelectCoinsMinConf
|
# Double chain limit but require combining inputs, so we pass SelectCoinsMinConf
|
||||||
self.stop_node(0)
|
self.stop_node(0)
|
||||||
self.start_node(0, extra_args=["-deprecatedrpc=accounts", "-walletrejectlongchains", "-limitancestorcount="+str(2*chainlimit)])
|
self.start_node(0, extra_args=["-deprecatedrpc=accounts", "-walletrejectlongchains", "-limitancestorcount=" + str(2 * chainlimit)])
|
||||||
|
|
||||||
# wait for loadmempool
|
# wait for loadmempool
|
||||||
timeout = 10
|
timeout = 10
|
||||||
while (timeout > 0 and len(self.nodes[0].getrawmempool()) < chainlimit*2):
|
while (timeout > 0 and len(self.nodes[0].getrawmempool()) < chainlimit * 2):
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
timeout -= 0.5
|
timeout -= 0.5
|
||||||
assert_equal(len(self.nodes[0].getrawmempool()), chainlimit*2)
|
assert_equal(len(self.nodes[0].getrawmempool()), chainlimit * 2)
|
||||||
|
|
||||||
node0_balance = self.nodes[0].getbalance()
|
node0_balance = self.nodes[0].getbalance()
|
||||||
# With walletrejectlongchains we will not create the tx and store it in our wallet.
|
# With walletrejectlongchains we will not create the tx and store it in our wallet.
|
||||||
assert_raises_rpc_error(-4, "Transaction has too long of a mempool chain", self.nodes[0].sendtoaddress, sending_addr, node0_balance - Decimal('0.01'))
|
assert_raises_rpc_error(-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
|
# Verify nothing new in wallet
|
||||||
assert_equal(total_txs, len(self.nodes[0].listtransactions("*",99999)))
|
assert_equal(total_txs, len(self.nodes[0].listtransactions("*", 99999)))
|
||||||
|
|
||||||
# Test getaddressinfo. Note that these addresses are taken from disablewallet.py
|
# Test getaddressinfo. Note that these addresses are taken from disablewallet.py
|
||||||
assert_raises_rpc_error(-5, "Invalid address", self.nodes[0].getaddressinfo, "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy")
|
assert_raises_rpc_error(-5, "Invalid address", self.nodes[0].getaddressinfo, "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy")
|
||||||
|
|
|
@ -46,10 +46,10 @@ class Variant(collections.namedtuple("Variant", "call data rescan prune")):
|
||||||
if self.call == Call.single:
|
if self.call == Call.single:
|
||||||
if self.data == Data.address:
|
if self.data == Data.address:
|
||||||
response = self.try_rpc(self.node.importaddress, self.address["address"], self.label,
|
response = self.try_rpc(self.node.importaddress, self.address["address"], self.label,
|
||||||
self.rescan == Rescan.yes)
|
self.rescan == Rescan.yes)
|
||||||
elif self.data == Data.pub:
|
elif self.data == Data.pub:
|
||||||
response = self.try_rpc(self.node.importpubkey, self.address["pubkey"], self.label,
|
response = self.try_rpc(self.node.importpubkey, self.address["pubkey"], self.label,
|
||||||
self.rescan == Rescan.yes)
|
self.rescan == Rescan.yes)
|
||||||
elif self.data == Data.priv:
|
elif self.data == Data.priv:
|
||||||
response = self.try_rpc(self.node.importprivkey, self.key, self.label, self.rescan == Rescan.yes)
|
response = self.try_rpc(self.node.importprivkey, self.key, self.label, self.rescan == Rescan.yes)
|
||||||
assert_equal(response, None)
|
assert_equal(response, None)
|
||||||
|
|
|
@ -3,8 +3,13 @@
|
||||||
# Distributed under the MIT software license, see the accompanying
|
# Distributed under the MIT software license, see the accompanying
|
||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
"""Test the importprunedfunds and removeprunedfunds RPCs."""
|
"""Test the importprunedfunds and removeprunedfunds RPCs."""
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
from test_framework.test_framework import BitcoinTestFramework
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
from test_framework.util import *
|
from test_framework.util import (
|
||||||
|
assert_equal,
|
||||||
|
assert_raises_rpc_error,
|
||||||
|
)
|
||||||
|
|
||||||
class ImportPrunedFundsTest(BitcoinTestFramework):
|
class ImportPrunedFundsTest(BitcoinTestFramework):
|
||||||
def set_test_params(self):
|
def set_test_params(self):
|
||||||
|
@ -24,18 +29,18 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
|
||||||
address2 = self.nodes[0].getnewaddress()
|
address2 = self.nodes[0].getnewaddress()
|
||||||
# privkey
|
# privkey
|
||||||
address3 = self.nodes[0].getnewaddress()
|
address3 = self.nodes[0].getnewaddress()
|
||||||
address3_privkey = self.nodes[0].dumpprivkey(address3) # Using privkey
|
address3_privkey = self.nodes[0].dumpprivkey(address3) # Using privkey
|
||||||
|
|
||||||
#Check only one address
|
# Check only one address
|
||||||
address_info = self.nodes[0].getaddressinfo(address1)
|
address_info = self.nodes[0].getaddressinfo(address1)
|
||||||
assert_equal(address_info['ismine'], True)
|
assert_equal(address_info['ismine'], True)
|
||||||
|
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
|
|
||||||
#Node 1 sync test
|
# Node 1 sync test
|
||||||
assert_equal(self.nodes[1].getblockcount(),101)
|
assert_equal(self.nodes[1].getblockcount(), 101)
|
||||||
|
|
||||||
#Address Test - before import
|
# Address Test - before import
|
||||||
address_info = self.nodes[1].getaddressinfo(address1)
|
address_info = self.nodes[1].getaddressinfo(address1)
|
||||||
assert_equal(address_info['iswatchonly'], False)
|
assert_equal(address_info['iswatchonly'], False)
|
||||||
assert_equal(address_info['ismine'], False)
|
assert_equal(address_info['ismine'], False)
|
||||||
|
@ -48,7 +53,7 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
|
||||||
assert_equal(address_info['iswatchonly'], False)
|
assert_equal(address_info['iswatchonly'], False)
|
||||||
assert_equal(address_info['ismine'], False)
|
assert_equal(address_info['ismine'], False)
|
||||||
|
|
||||||
#Send funds to self
|
# Send funds to self
|
||||||
txnid1 = self.nodes[0].sendtoaddress(address1, 0.1)
|
txnid1 = self.nodes[0].sendtoaddress(address1, 0.1)
|
||||||
self.nodes[0].generate(1)
|
self.nodes[0].generate(1)
|
||||||
rawtxn1 = self.nodes[0].gettransaction(txnid1)['hex']
|
rawtxn1 = self.nodes[0].gettransaction(txnid1)['hex']
|
||||||
|
@ -66,19 +71,19 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
|
||||||
|
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
|
|
||||||
#Import with no affiliated address
|
# Import with no affiliated address
|
||||||
assert_raises_rpc_error(-5, "No addresses", self.nodes[1].importprunedfunds, rawtxn1, proof1)
|
assert_raises_rpc_error(-5, "No addresses", self.nodes[1].importprunedfunds, rawtxn1, proof1)
|
||||||
|
|
||||||
balance1 = self.nodes[1].getbalance("", 0, True)
|
balance1 = self.nodes[1].getbalance("", 0, True)
|
||||||
assert_equal(balance1, Decimal(0))
|
assert_equal(balance1, Decimal(0))
|
||||||
|
|
||||||
#Import with affiliated address with no rescan
|
# Import with affiliated address with no rescan
|
||||||
self.nodes[1].importaddress(address2, "add2", False)
|
self.nodes[1].importaddress(address2, "add2", False)
|
||||||
self.nodes[1].importprunedfunds(rawtxn2, proof2)
|
self.nodes[1].importprunedfunds(rawtxn2, proof2)
|
||||||
balance2 = self.nodes[1].getbalance("add2", 0, True)
|
balance2 = self.nodes[1].getbalance("add2", 0, True)
|
||||||
assert_equal(balance2, Decimal('0.05'))
|
assert_equal(balance2, Decimal('0.05'))
|
||||||
|
|
||||||
#Import with private key with no rescan
|
# Import with private key with no rescan
|
||||||
self.nodes[1].importprivkey(privkey=address3_privkey, label="add3", rescan=False)
|
self.nodes[1].importprivkey(privkey=address3_privkey, label="add3", rescan=False)
|
||||||
self.nodes[1].importprunedfunds(rawtxn3, proof3)
|
self.nodes[1].importprunedfunds(rawtxn3, proof3)
|
||||||
balance3 = self.nodes[1].getbalance("add3", 0, False)
|
balance3 = self.nodes[1].getbalance("add3", 0, False)
|
||||||
|
@ -86,7 +91,7 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
|
||||||
balance3 = self.nodes[1].getbalance("*", 0, True)
|
balance3 = self.nodes[1].getbalance("*", 0, True)
|
||||||
assert_equal(balance3, Decimal('0.075'))
|
assert_equal(balance3, Decimal('0.075'))
|
||||||
|
|
||||||
#Addresses Test - after import
|
# Addresses Test - after import
|
||||||
address_info = self.nodes[1].getaddressinfo(address1)
|
address_info = self.nodes[1].getaddressinfo(address1)
|
||||||
assert_equal(address_info['iswatchonly'], False)
|
assert_equal(address_info['iswatchonly'], False)
|
||||||
assert_equal(address_info['ismine'], False)
|
assert_equal(address_info['ismine'], False)
|
||||||
|
@ -97,7 +102,7 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
|
||||||
assert_equal(address_info['iswatchonly'], False)
|
assert_equal(address_info['iswatchonly'], False)
|
||||||
assert_equal(address_info['ismine'], True)
|
assert_equal(address_info['ismine'], True)
|
||||||
|
|
||||||
#Remove transactions
|
# Remove transactions
|
||||||
assert_raises_rpc_error(-8, "Transaction does not exist in wallet.", self.nodes[1].removeprunedfunds, txnid1)
|
assert_raises_rpc_error(-8, "Transaction does not exist in wallet.", self.nodes[1].removeprunedfunds, txnid1)
|
||||||
|
|
||||||
balance1 = self.nodes[1].getbalance("*", 0, True)
|
balance1 = self.nodes[1].getbalance("*", 0, True)
|
||||||
|
|
|
@ -51,37 +51,37 @@ class ReceivedByTest(BitcoinTestFramework):
|
||||||
{"address": empty_addr},
|
{"address": empty_addr},
|
||||||
{"address": empty_addr, "label": "", "amount": 0, "confirmations": 0, "txids": []})
|
{"address": empty_addr, "label": "", "amount": 0, "confirmations": 0, "txids": []})
|
||||||
|
|
||||||
#Test Address filtering
|
# Test Address filtering
|
||||||
#Only on addr
|
# Only on addr
|
||||||
expected = {"address":addr, "label":"", "amount":Decimal("0.1"), "confirmations":10, "txids":[txid,]}
|
expected = {"address": addr, "label": "", "amount": Decimal("0.1"), "confirmations": 10, "txids": [txid, ]}
|
||||||
res = self.nodes[1].listreceivedbyaddress(minconf=0, include_empty=True, include_watchonly=True, address_filter=addr)
|
res = self.nodes[1].listreceivedbyaddress(minconf=0, include_empty=True, include_watchonly=True, address_filter=addr)
|
||||||
assert_array_result(res, {"address":addr}, expected)
|
assert_array_result(res, {"address": addr}, expected)
|
||||||
assert_equal(len(res), 1)
|
assert_equal(len(res), 1)
|
||||||
#Error on invalid address
|
# Error on invalid address
|
||||||
assert_raises_rpc_error(-4, "address_filter parameter was invalid", self.nodes[1].listreceivedbyaddress, minconf=0, include_empty=True, include_watchonly=True, address_filter="bamboozling")
|
assert_raises_rpc_error(-4, "address_filter parameter was invalid", self.nodes[1].listreceivedbyaddress, minconf=0, include_empty=True, include_watchonly=True, address_filter="bamboozling")
|
||||||
#Another address receive money
|
# Another address receive money
|
||||||
res = self.nodes[1].listreceivedbyaddress(0, True, True)
|
res = self.nodes[1].listreceivedbyaddress(0, True, True)
|
||||||
assert_equal(len(res), 2) #Right now 2 entries
|
assert_equal(len(res), 2) # Right now 2 entries
|
||||||
other_addr = self.nodes[1].getnewaddress()
|
other_addr = self.nodes[1].getnewaddress()
|
||||||
txid2 = self.nodes[0].sendtoaddress(other_addr, 0.1)
|
txid2 = self.nodes[0].sendtoaddress(other_addr, 0.1)
|
||||||
self.nodes[0].generate(1)
|
self.nodes[0].generate(1)
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
#Same test as above should still pass
|
# Same test as above should still pass
|
||||||
expected = {"address":addr, "label":"", "amount":Decimal("0.1"), "confirmations":11, "txids":[txid,]}
|
expected = {"address": addr, "label": "", "amount": Decimal("0.1"), "confirmations": 11, "txids": [txid, ]}
|
||||||
res = self.nodes[1].listreceivedbyaddress(0, True, True, addr)
|
res = self.nodes[1].listreceivedbyaddress(0, True, True, addr)
|
||||||
assert_array_result(res, {"address":addr}, expected)
|
assert_array_result(res, {"address": addr}, expected)
|
||||||
assert_equal(len(res), 1)
|
assert_equal(len(res), 1)
|
||||||
#Same test as above but with other_addr should still pass
|
# Same test as above but with other_addr should still pass
|
||||||
expected = {"address":other_addr, "label":"", "amount":Decimal("0.1"), "confirmations":1, "txids":[txid2,]}
|
expected = {"address": other_addr, "label": "", "amount": Decimal("0.1"), "confirmations": 1, "txids": [txid2, ]}
|
||||||
res = self.nodes[1].listreceivedbyaddress(0, True, True, other_addr)
|
res = self.nodes[1].listreceivedbyaddress(0, True, True, other_addr)
|
||||||
assert_array_result(res, {"address":other_addr}, expected)
|
assert_array_result(res, {"address": other_addr}, expected)
|
||||||
assert_equal(len(res), 1)
|
assert_equal(len(res), 1)
|
||||||
#Should be two entries though without filter
|
# Should be two entries though without filter
|
||||||
res = self.nodes[1].listreceivedbyaddress(0, True, True)
|
res = self.nodes[1].listreceivedbyaddress(0, True, True)
|
||||||
assert_equal(len(res), 3) #Became 3 entries
|
assert_equal(len(res), 3) # Became 3 entries
|
||||||
|
|
||||||
#Not on random addr
|
# Not on random addr
|
||||||
other_addr = self.nodes[0].getnewaddress() # note on node[0]! just a random addr
|
other_addr = self.nodes[0].getnewaddress() # note on node[0]! just a random addr
|
||||||
res = self.nodes[1].listreceivedbyaddress(0, True, True, other_addr)
|
res = self.nodes[1].listreceivedbyaddress(0, True, True, other_addr)
|
||||||
assert_equal(len(res), 0)
|
assert_equal(len(res), 0)
|
||||||
|
|
||||||
|
@ -112,8 +112,8 @@ class ReceivedByTest(BitcoinTestFramework):
|
||||||
self.log.info("listreceivedbylabel + getreceivedbylabel Test")
|
self.log.info("listreceivedbylabel + getreceivedbylabel Test")
|
||||||
|
|
||||||
# set pre-state
|
# set pre-state
|
||||||
addrArr = self.nodes[1].getnewaddress()
|
address = self.nodes[1].getnewaddress()
|
||||||
label = self.nodes[1].getaccount(addrArr)
|
label = self.nodes[1].getaccount(address)
|
||||||
received_by_label_json = [r for r in self.nodes[1].listreceivedbylabel() if r["label"] == label][0]
|
received_by_label_json = [r for r in self.nodes[1].listreceivedbylabel() if r["label"] == label][0]
|
||||||
balance_by_label = self.nodes[1].getreceivedbylabel(label)
|
balance_by_label = self.nodes[1].getreceivedbylabel(label)
|
||||||
|
|
||||||
|
|
|
@ -150,26 +150,26 @@ class ListSinceBlockTest (BitcoinTestFramework):
|
||||||
|
|
||||||
# send from nodes[1] using utxo to nodes[0]
|
# send from nodes[1] using utxo to nodes[0]
|
||||||
change = '%.8f' % (float(utxo['amount']) - 1.0003)
|
change = '%.8f' % (float(utxo['amount']) - 1.0003)
|
||||||
recipientDict = {
|
recipient_dict = {
|
||||||
self.nodes[0].getnewaddress(): 1,
|
self.nodes[0].getnewaddress(): 1,
|
||||||
self.nodes[1].getnewaddress(): change,
|
self.nodes[1].getnewaddress(): change,
|
||||||
}
|
}
|
||||||
utxoDicts = [{
|
utxo_dicts = [{
|
||||||
'txid': utxo['txid'],
|
'txid': utxo['txid'],
|
||||||
'vout': utxo['vout'],
|
'vout': utxo['vout'],
|
||||||
}]
|
}]
|
||||||
txid1 = self.nodes[1].sendrawtransaction(
|
txid1 = self.nodes[1].sendrawtransaction(
|
||||||
self.nodes[1].signrawtransactionwithwallet(
|
self.nodes[1].signrawtransactionwithwallet(
|
||||||
self.nodes[1].createrawtransaction(utxoDicts, recipientDict))['hex'])
|
self.nodes[1].createrawtransaction(utxo_dicts, recipient_dict))['hex'])
|
||||||
|
|
||||||
# send from nodes[2] using utxo to nodes[3]
|
# send from nodes[2] using utxo to nodes[3]
|
||||||
recipientDict2 = {
|
recipient_dict2 = {
|
||||||
self.nodes[3].getnewaddress(): 1,
|
self.nodes[3].getnewaddress(): 1,
|
||||||
self.nodes[2].getnewaddress(): change,
|
self.nodes[2].getnewaddress(): change,
|
||||||
}
|
}
|
||||||
self.nodes[2].sendrawtransaction(
|
self.nodes[2].sendrawtransaction(
|
||||||
self.nodes[2].signrawtransactionwithwallet(
|
self.nodes[2].signrawtransactionwithwallet(
|
||||||
self.nodes[2].createrawtransaction(utxoDicts, recipientDict2))['hex'])
|
self.nodes[2].createrawtransaction(utxo_dicts, recipient_dict2))['hex'])
|
||||||
|
|
||||||
# generate on both sides
|
# generate on both sides
|
||||||
lastblockhash = self.nodes[1].generate(3)[2]
|
lastblockhash = self.nodes[1].generate(3)[2]
|
||||||
|
@ -225,16 +225,16 @@ class ListSinceBlockTest (BitcoinTestFramework):
|
||||||
utxos = self.nodes[2].listunspent()
|
utxos = self.nodes[2].listunspent()
|
||||||
utxo = utxos[0]
|
utxo = utxos[0]
|
||||||
change = '%.8f' % (float(utxo['amount']) - 1.0003)
|
change = '%.8f' % (float(utxo['amount']) - 1.0003)
|
||||||
recipientDict = {
|
recipient_dict = {
|
||||||
self.nodes[0].getnewaddress(): 1,
|
self.nodes[0].getnewaddress(): 1,
|
||||||
self.nodes[2].getnewaddress(): change,
|
self.nodes[2].getnewaddress(): change,
|
||||||
}
|
}
|
||||||
utxoDicts = [{
|
utxo_dicts = [{
|
||||||
'txid': utxo['txid'],
|
'txid': utxo['txid'],
|
||||||
'vout': utxo['vout'],
|
'vout': utxo['vout'],
|
||||||
}]
|
}]
|
||||||
signedtxres = self.nodes[2].signrawtransactionwithwallet(
|
signedtxres = self.nodes[2].signrawtransactionwithwallet(
|
||||||
self.nodes[2].createrawtransaction(utxoDicts, recipientDict))
|
self.nodes[2].createrawtransaction(utxo_dicts, recipient_dict))
|
||||||
assert signedtxres['complete']
|
assert signedtxres['complete']
|
||||||
|
|
||||||
signedtx = signedtxres['hex']
|
signedtx = signedtxres['hex']
|
||||||
|
|
|
@ -3,13 +3,20 @@
|
||||||
# Distributed under the MIT software license, see the accompanying
|
# Distributed under the MIT software license, see the accompanying
|
||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
"""Test the listtransactions API."""
|
"""Test the listtransactions API."""
|
||||||
|
from decimal import Decimal
|
||||||
from test_framework.test_framework import BitcoinTestFramework
|
|
||||||
from test_framework.util import *
|
|
||||||
from test_framework.mininode import CTransaction, COIN
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
def txFromHex(hexstring):
|
from test_framework.mininode import CTransaction, COIN
|
||||||
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
|
from test_framework.util import (
|
||||||
|
assert_array_result,
|
||||||
|
assert_equal,
|
||||||
|
bytes_to_hex_str,
|
||||||
|
hex_str_to_bytes,
|
||||||
|
sync_mempools,
|
||||||
|
)
|
||||||
|
|
||||||
|
def tx_from_hex(hexstring):
|
||||||
tx = CTransaction()
|
tx = CTransaction()
|
||||||
f = BytesIO(hex_str_to_bytes(hexstring))
|
f = BytesIO(hex_str_to_bytes(hexstring))
|
||||||
tx.deserialize(f)
|
tx.deserialize(f)
|
||||||
|
@ -26,61 +33,61 @@ class ListTransactionsTest(BitcoinTestFramework):
|
||||||
txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
|
txid = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.1)
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
assert_array_result(self.nodes[0].listtransactions(),
|
assert_array_result(self.nodes[0].listtransactions(),
|
||||||
{"txid":txid},
|
{"txid": txid},
|
||||||
{"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":0})
|
{"category": "send", "account": "", "amount": Decimal("-0.1"), "confirmations": 0})
|
||||||
assert_array_result(self.nodes[1].listtransactions(),
|
assert_array_result(self.nodes[1].listtransactions(),
|
||||||
{"txid":txid},
|
{"txid": txid},
|
||||||
{"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":0})
|
{"category": "receive", "account": "", "amount": Decimal("0.1"), "confirmations": 0})
|
||||||
# mine a block, confirmations should change:
|
# mine a block, confirmations should change:
|
||||||
self.nodes[0].generate(1)
|
self.nodes[0].generate(1)
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
assert_array_result(self.nodes[0].listtransactions(),
|
assert_array_result(self.nodes[0].listtransactions(),
|
||||||
{"txid":txid},
|
{"txid": txid},
|
||||||
{"category":"send","account":"","amount":Decimal("-0.1"),"confirmations":1})
|
{"category": "send", "account": "", "amount": Decimal("-0.1"), "confirmations": 1})
|
||||||
assert_array_result(self.nodes[1].listtransactions(),
|
assert_array_result(self.nodes[1].listtransactions(),
|
||||||
{"txid":txid},
|
{"txid": txid},
|
||||||
{"category":"receive","account":"","amount":Decimal("0.1"),"confirmations":1})
|
{"category": "receive", "account": "", "amount": Decimal("0.1"), "confirmations": 1})
|
||||||
|
|
||||||
# send-to-self:
|
# send-to-self:
|
||||||
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 0.2)
|
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 0.2)
|
||||||
assert_array_result(self.nodes[0].listtransactions(),
|
assert_array_result(self.nodes[0].listtransactions(),
|
||||||
{"txid":txid, "category":"send"},
|
{"txid": txid, "category": "send"},
|
||||||
{"amount":Decimal("-0.2")})
|
{"amount": Decimal("-0.2")})
|
||||||
assert_array_result(self.nodes[0].listtransactions(),
|
assert_array_result(self.nodes[0].listtransactions(),
|
||||||
{"txid":txid, "category":"receive"},
|
{"txid": txid, "category": "receive"},
|
||||||
{"amount":Decimal("0.2")})
|
{"amount": Decimal("0.2")})
|
||||||
|
|
||||||
# sendmany from node1: twice to self, twice to node2:
|
# sendmany from node1: twice to self, twice to node2:
|
||||||
send_to = { self.nodes[0].getnewaddress() : 0.11,
|
send_to = {self.nodes[0].getnewaddress(): 0.11,
|
||||||
self.nodes[1].getnewaddress() : 0.22,
|
self.nodes[1].getnewaddress(): 0.22,
|
||||||
self.nodes[0].getaccountaddress("from1") : 0.33,
|
self.nodes[0].getaccountaddress("from1"): 0.33,
|
||||||
self.nodes[1].getaccountaddress("toself") : 0.44 }
|
self.nodes[1].getaccountaddress("toself"): 0.44}
|
||||||
txid = self.nodes[1].sendmany("", send_to)
|
txid = self.nodes[1].sendmany("", send_to)
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
assert_array_result(self.nodes[1].listtransactions(),
|
assert_array_result(self.nodes[1].listtransactions(),
|
||||||
{"category":"send","amount":Decimal("-0.11")},
|
{"category": "send", "amount": Decimal("-0.11")},
|
||||||
{"txid":txid} )
|
{"txid": txid})
|
||||||
assert_array_result(self.nodes[0].listtransactions(),
|
assert_array_result(self.nodes[0].listtransactions(),
|
||||||
{"category":"receive","amount":Decimal("0.11")},
|
{"category": "receive", "amount": Decimal("0.11")},
|
||||||
{"txid":txid} )
|
{"txid": txid})
|
||||||
assert_array_result(self.nodes[1].listtransactions(),
|
assert_array_result(self.nodes[1].listtransactions(),
|
||||||
{"category":"send","amount":Decimal("-0.22")},
|
{"category": "send", "amount": Decimal("-0.22")},
|
||||||
{"txid":txid} )
|
{"txid": txid})
|
||||||
assert_array_result(self.nodes[1].listtransactions(),
|
assert_array_result(self.nodes[1].listtransactions(),
|
||||||
{"category":"receive","amount":Decimal("0.22")},
|
{"category": "receive", "amount": Decimal("0.22")},
|
||||||
{"txid":txid} )
|
{"txid": txid})
|
||||||
assert_array_result(self.nodes[1].listtransactions(),
|
assert_array_result(self.nodes[1].listtransactions(),
|
||||||
{"category":"send","amount":Decimal("-0.33")},
|
{"category": "send", "amount": Decimal("-0.33")},
|
||||||
{"txid":txid} )
|
{"txid": txid})
|
||||||
assert_array_result(self.nodes[0].listtransactions(),
|
assert_array_result(self.nodes[0].listtransactions(),
|
||||||
{"category":"receive","amount":Decimal("0.33")},
|
{"category": "receive", "amount": Decimal("0.33")},
|
||||||
{"txid":txid, "account" : "from1"} )
|
{"txid": txid, "account": "from1"})
|
||||||
assert_array_result(self.nodes[1].listtransactions(),
|
assert_array_result(self.nodes[1].listtransactions(),
|
||||||
{"category":"send","amount":Decimal("-0.44")},
|
{"category": "send", "amount": Decimal("-0.44")},
|
||||||
{"txid":txid, "account" : ""} )
|
{"txid": txid, "account": ""})
|
||||||
assert_array_result(self.nodes[1].listtransactions(),
|
assert_array_result(self.nodes[1].listtransactions(),
|
||||||
{"category":"receive","amount":Decimal("0.44")},
|
{"category": "receive", "amount": Decimal("0.44")},
|
||||||
{"txid":txid, "account" : "toself"} )
|
{"txid": txid, "account": "toself"})
|
||||||
|
|
||||||
pubkey = self.nodes[1].getaddressinfo(self.nodes[1].getnewaddress())['pubkey']
|
pubkey = self.nodes[1].getaddressinfo(self.nodes[1].getnewaddress())['pubkey']
|
||||||
multisig = self.nodes[1].createmultisig(1, [pubkey])
|
multisig = self.nodes[1].createmultisig(1, [pubkey])
|
||||||
|
@ -90,8 +97,8 @@ class ListTransactionsTest(BitcoinTestFramework):
|
||||||
self.sync_all()
|
self.sync_all()
|
||||||
assert(len(self.nodes[0].listtransactions("watchonly", 100, 0, False)) == 0)
|
assert(len(self.nodes[0].listtransactions("watchonly", 100, 0, False)) == 0)
|
||||||
assert_array_result(self.nodes[0].listtransactions("watchonly", 100, 0, True),
|
assert_array_result(self.nodes[0].listtransactions("watchonly", 100, 0, True),
|
||||||
{"category":"receive","amount":Decimal("0.1")},
|
{"category": "receive", "amount": Decimal("0.1")},
|
||||||
{"txid":txid, "account" : "watchonly"} )
|
{"txid": txid, "account": "watchonly"})
|
||||||
|
|
||||||
self.run_rbf_opt_in_test()
|
self.run_rbf_opt_in_test()
|
||||||
|
|
||||||
|
@ -117,9 +124,9 @@ class ListTransactionsTest(BitcoinTestFramework):
|
||||||
# 1. Chain a few transactions that don't opt-in.
|
# 1. Chain a few transactions that don't opt-in.
|
||||||
txid_1 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1)
|
txid_1 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1)
|
||||||
assert(not is_opt_in(self.nodes[0], txid_1))
|
assert(not is_opt_in(self.nodes[0], txid_1))
|
||||||
assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_1}, {"bip125-replaceable":"no"})
|
assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_1}, {"bip125-replaceable": "no"})
|
||||||
sync_mempools(self.nodes)
|
sync_mempools(self.nodes)
|
||||||
assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_1}, {"bip125-replaceable":"no"})
|
assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_1}, {"bip125-replaceable": "no"})
|
||||||
|
|
||||||
# Tx2 will build off txid_1, still not opting in to RBF.
|
# Tx2 will build off txid_1, still not opting in to RBF.
|
||||||
utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[0], txid_1)
|
utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[0], txid_1)
|
||||||
|
@ -129,7 +136,7 @@ class ListTransactionsTest(BitcoinTestFramework):
|
||||||
assert_equal(utxo_to_use["safe"], False)
|
assert_equal(utxo_to_use["safe"], False)
|
||||||
|
|
||||||
# Create tx2 using createrawtransaction
|
# Create tx2 using createrawtransaction
|
||||||
inputs = [{"txid":utxo_to_use["txid"], "vout":utxo_to_use["vout"]}]
|
inputs = [{"txid": utxo_to_use["txid"], "vout": utxo_to_use["vout"]}]
|
||||||
outputs = {self.nodes[0].getnewaddress(): 0.999}
|
outputs = {self.nodes[0].getnewaddress(): 0.999}
|
||||||
tx2 = self.nodes[1].createrawtransaction(inputs, outputs)
|
tx2 = self.nodes[1].createrawtransaction(inputs, outputs)
|
||||||
tx2_signed = self.nodes[1].signrawtransactionwithwallet(tx2)["hex"]
|
tx2_signed = self.nodes[1].signrawtransactionwithwallet(tx2)["hex"]
|
||||||
|
@ -137,51 +144,51 @@ class ListTransactionsTest(BitcoinTestFramework):
|
||||||
|
|
||||||
# ...and check the result
|
# ...and check the result
|
||||||
assert(not is_opt_in(self.nodes[1], txid_2))
|
assert(not is_opt_in(self.nodes[1], txid_2))
|
||||||
assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_2}, {"bip125-replaceable":"no"})
|
assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_2}, {"bip125-replaceable": "no"})
|
||||||
sync_mempools(self.nodes)
|
sync_mempools(self.nodes)
|
||||||
assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_2}, {"bip125-replaceable":"no"})
|
assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_2}, {"bip125-replaceable": "no"})
|
||||||
|
|
||||||
# Tx3 will opt-in to RBF
|
# Tx3 will opt-in to RBF
|
||||||
utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[0], txid_2)
|
utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[0], txid_2)
|
||||||
inputs = [{"txid": txid_2, "vout":utxo_to_use["vout"]}]
|
inputs = [{"txid": txid_2, "vout": utxo_to_use["vout"]}]
|
||||||
outputs = {self.nodes[1].getnewaddress(): 0.998}
|
outputs = {self.nodes[1].getnewaddress(): 0.998}
|
||||||
tx3 = self.nodes[0].createrawtransaction(inputs, outputs)
|
tx3 = self.nodes[0].createrawtransaction(inputs, outputs)
|
||||||
tx3_modified = txFromHex(tx3)
|
tx3_modified = tx_from_hex(tx3)
|
||||||
tx3_modified.vin[0].nSequence = 0
|
tx3_modified.vin[0].nSequence = 0
|
||||||
tx3 = bytes_to_hex_str(tx3_modified.serialize())
|
tx3 = bytes_to_hex_str(tx3_modified.serialize())
|
||||||
tx3_signed = self.nodes[0].signrawtransactionwithwallet(tx3)['hex']
|
tx3_signed = self.nodes[0].signrawtransactionwithwallet(tx3)['hex']
|
||||||
txid_3 = self.nodes[0].sendrawtransaction(tx3_signed)
|
txid_3 = self.nodes[0].sendrawtransaction(tx3_signed)
|
||||||
|
|
||||||
assert(is_opt_in(self.nodes[0], txid_3))
|
assert(is_opt_in(self.nodes[0], txid_3))
|
||||||
assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_3}, {"bip125-replaceable":"yes"})
|
assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_3}, {"bip125-replaceable": "yes"})
|
||||||
sync_mempools(self.nodes)
|
sync_mempools(self.nodes)
|
||||||
assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_3}, {"bip125-replaceable":"yes"})
|
assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_3}, {"bip125-replaceable": "yes"})
|
||||||
|
|
||||||
# Tx4 will chain off tx3. Doesn't signal itself, but depends on one
|
# Tx4 will chain off tx3. Doesn't signal itself, but depends on one
|
||||||
# that does.
|
# that does.
|
||||||
utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[1], txid_3)
|
utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[1], txid_3)
|
||||||
inputs = [{"txid": txid_3, "vout":utxo_to_use["vout"]}]
|
inputs = [{"txid": txid_3, "vout": utxo_to_use["vout"]}]
|
||||||
outputs = {self.nodes[0].getnewaddress(): 0.997}
|
outputs = {self.nodes[0].getnewaddress(): 0.997}
|
||||||
tx4 = self.nodes[1].createrawtransaction(inputs, outputs)
|
tx4 = self.nodes[1].createrawtransaction(inputs, outputs)
|
||||||
tx4_signed = self.nodes[1].signrawtransactionwithwallet(tx4)["hex"]
|
tx4_signed = self.nodes[1].signrawtransactionwithwallet(tx4)["hex"]
|
||||||
txid_4 = self.nodes[1].sendrawtransaction(tx4_signed)
|
txid_4 = self.nodes[1].sendrawtransaction(tx4_signed)
|
||||||
|
|
||||||
assert(not is_opt_in(self.nodes[1], txid_4))
|
assert(not is_opt_in(self.nodes[1], txid_4))
|
||||||
assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"yes"})
|
assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable": "yes"})
|
||||||
sync_mempools(self.nodes)
|
sync_mempools(self.nodes)
|
||||||
assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"yes"})
|
assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable": "yes"})
|
||||||
|
|
||||||
# Replace tx3, and check that tx4 becomes unknown
|
# Replace tx3, and check that tx4 becomes unknown
|
||||||
tx3_b = tx3_modified
|
tx3_b = tx3_modified
|
||||||
tx3_b.vout[0].nValue -= int(Decimal("0.004") * COIN) # bump the fee
|
tx3_b.vout[0].nValue -= int(Decimal("0.004") * COIN) # bump the fee
|
||||||
tx3_b = bytes_to_hex_str(tx3_b.serialize())
|
tx3_b = bytes_to_hex_str(tx3_b.serialize())
|
||||||
tx3_b_signed = self.nodes[0].signrawtransactionwithwallet(tx3_b)['hex']
|
tx3_b_signed = self.nodes[0].signrawtransactionwithwallet(tx3_b)['hex']
|
||||||
txid_3b = self.nodes[0].sendrawtransaction(tx3_b_signed, True)
|
txid_3b = self.nodes[0].sendrawtransaction(tx3_b_signed, True)
|
||||||
assert(is_opt_in(self.nodes[0], txid_3b))
|
assert(is_opt_in(self.nodes[0], txid_3b))
|
||||||
|
|
||||||
assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"unknown"})
|
assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable": "unknown"})
|
||||||
sync_mempools(self.nodes)
|
sync_mempools(self.nodes)
|
||||||
assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"unknown"})
|
assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable": "unknown"})
|
||||||
|
|
||||||
# Check gettransaction as well:
|
# Check gettransaction as well:
|
||||||
for n in self.nodes[0:2]:
|
for n in self.nodes[0:2]:
|
||||||
|
@ -197,7 +204,5 @@ class ListTransactionsTest(BitcoinTestFramework):
|
||||||
assert_equal(self.nodes[0].gettransaction(txid_3b)["bip125-replaceable"], "no")
|
assert_equal(self.nodes[0].gettransaction(txid_3b)["bip125-replaceable"], "no")
|
||||||
assert_equal(self.nodes[0].gettransaction(txid_4)["bip125-replaceable"], "unknown")
|
assert_equal(self.nodes[0].gettransaction(txid_4)["bip125-replaceable"], "unknown")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
ListTransactionsTest().main()
|
ListTransactionsTest().main()
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,12 @@
|
||||||
"""Test the wallet accounts properly when there are cloned transactions with malleated scriptsigs."""
|
"""Test the wallet accounts properly when there are cloned transactions with malleated scriptsigs."""
|
||||||
|
|
||||||
from test_framework.test_framework import BitcoinTestFramework
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
from test_framework.util import *
|
from test_framework.util import (
|
||||||
|
assert_equal,
|
||||||
|
connect_nodes,
|
||||||
|
disconnect_nodes,
|
||||||
|
sync_blocks,
|
||||||
|
)
|
||||||
|
|
||||||
class TxnMallTest(BitcoinTestFramework):
|
class TxnMallTest(BitcoinTestFramework):
|
||||||
def set_test_params(self):
|
def set_test_params(self):
|
||||||
|
@ -26,9 +31,9 @@ class TxnMallTest(BitcoinTestFramework):
|
||||||
|
|
||||||
def run_test(self):
|
def run_test(self):
|
||||||
if self.options.segwit:
|
if self.options.segwit:
|
||||||
output_type="p2sh-segwit"
|
output_type = "p2sh-segwit"
|
||||||
else:
|
else:
|
||||||
output_type="legacy"
|
output_type = "legacy"
|
||||||
|
|
||||||
# All nodes should start with 1,250 BTC:
|
# All nodes should start with 1,250 BTC:
|
||||||
starting_balance = 1250
|
starting_balance = 1250
|
||||||
|
@ -58,23 +63,22 @@ class TxnMallTest(BitcoinTestFramework):
|
||||||
txid2 = self.nodes[0].sendfrom("bar", node1_address, 20, 0)
|
txid2 = self.nodes[0].sendfrom("bar", node1_address, 20, 0)
|
||||||
|
|
||||||
# Construct a clone of tx1, to be malleated
|
# Construct a clone of tx1, to be malleated
|
||||||
rawtx1 = self.nodes[0].getrawtransaction(txid1,1)
|
rawtx1 = self.nodes[0].getrawtransaction(txid1, 1)
|
||||||
clone_inputs = [{"txid":rawtx1["vin"][0]["txid"],"vout":rawtx1["vin"][0]["vout"]}]
|
clone_inputs = [{"txid": rawtx1["vin"][0]["txid"], "vout": rawtx1["vin"][0]["vout"]}]
|
||||||
clone_outputs = {rawtx1["vout"][0]["scriptPubKey"]["addresses"][0]:rawtx1["vout"][0]["value"],
|
clone_outputs = {rawtx1["vout"][0]["scriptPubKey"]["addresses"][0]: rawtx1["vout"][0]["value"],
|
||||||
rawtx1["vout"][1]["scriptPubKey"]["addresses"][0]:rawtx1["vout"][1]["value"]}
|
rawtx1["vout"][1]["scriptPubKey"]["addresses"][0]: rawtx1["vout"][1]["value"]}
|
||||||
clone_locktime = rawtx1["locktime"]
|
clone_locktime = rawtx1["locktime"]
|
||||||
clone_raw = self.nodes[0].createrawtransaction(clone_inputs, clone_outputs, clone_locktime)
|
clone_raw = self.nodes[0].createrawtransaction(clone_inputs, clone_outputs, clone_locktime)
|
||||||
|
|
||||||
# createrawtransaction randomizes the order of its outputs, so swap them if necessary.
|
# createrawtransaction randomizes the order of its outputs, so swap them if necessary.
|
||||||
# output 0 is at version+#inputs+input+sigstub+sequence+#outputs
|
# output 0 is at version+#inputs+input+sigstub+sequence+#outputs
|
||||||
# 40 BTC serialized is 00286bee00000000
|
# 40 BTC serialized is 00286bee00000000
|
||||||
pos0 = 2*(4+1+36+1+4+1)
|
pos0 = 2 * (4 + 1 + 36 + 1 + 4 + 1)
|
||||||
hex40 = "00286bee00000000"
|
hex40 = "00286bee00000000"
|
||||||
output_len = 16 + 2 + 2 * int("0x" + clone_raw[pos0 + 16 : pos0 + 16 + 2], 0)
|
output_len = 16 + 2 + 2 * int("0x" + clone_raw[pos0 + 16:pos0 + 16 + 2], 0)
|
||||||
if (rawtx1["vout"][0]["value"] == 40 and clone_raw[pos0 : pos0 + 16] != hex40 or
|
if (rawtx1["vout"][0]["value"] == 40 and clone_raw[pos0:pos0 + 16] != hex40 or rawtx1["vout"][0]["value"] != 40 and clone_raw[pos0:pos0 + 16] == hex40):
|
||||||
rawtx1["vout"][0]["value"] != 40 and clone_raw[pos0 : pos0 + 16] == hex40):
|
output0 = clone_raw[pos0:pos0 + output_len]
|
||||||
output0 = clone_raw[pos0 : pos0 + output_len]
|
output1 = clone_raw[pos0 + output_len:pos0 + 2 * output_len]
|
||||||
output1 = clone_raw[pos0 + output_len : pos0 + 2 * output_len]
|
|
||||||
clone_raw = clone_raw[:pos0] + output1 + output0 + clone_raw[pos0 + 2 * output_len:]
|
clone_raw = clone_raw[:pos0] + output1 + output0 + clone_raw[pos0 + 2 * output_len:]
|
||||||
|
|
||||||
# Use a different signature hash type to sign. This creates an equivalent but malleated clone.
|
# Use a different signature hash type to sign. This creates an equivalent but malleated clone.
|
||||||
|
@ -153,16 +157,11 @@ class TxnMallTest(BitcoinTestFramework):
|
||||||
# "bar" should have been debited by (possibly unconfirmed) tx2
|
# "bar" should have been debited by (possibly unconfirmed) tx2
|
||||||
assert_equal(self.nodes[0].getbalance("bar", 0), 29 + tx2["amount"] + tx2["fee"])
|
assert_equal(self.nodes[0].getbalance("bar", 0), 29 + tx2["amount"] + tx2["fee"])
|
||||||
# "" should have starting balance, less funding txes, plus subsidies
|
# "" should have starting balance, less funding txes, plus subsidies
|
||||||
assert_equal(self.nodes[0].getbalance("", 0), starting_balance
|
assert_equal(self.nodes[0].getbalance("", 0),
|
||||||
- 1219
|
starting_balance - 1219 + fund_foo_tx["fee"] - 29 + fund_bar_tx["fee"] + 100)
|
||||||
+ fund_foo_tx["fee"]
|
|
||||||
- 29
|
|
||||||
+ fund_bar_tx["fee"]
|
|
||||||
+ 100)
|
|
||||||
|
|
||||||
# Node1's "from0" account balance
|
# Node1's "from0" account balance
|
||||||
assert_equal(self.nodes[1].getbalance("from0", 0), -(tx1["amount"] + tx2["amount"]))
|
assert_equal(self.nodes[1].getbalance("from0", 0), -(tx1["amount"] + tx2["amount"]))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
TxnMallTest().main()
|
TxnMallTest().main()
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,16 @@
|
||||||
# Distributed under the MIT software license, see the accompanying
|
# Distributed under the MIT software license, see the accompanying
|
||||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
"""Test the wallet accounts properly when there is a double-spend conflict."""
|
"""Test the wallet accounts properly when there is a double-spend conflict."""
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
from test_framework.test_framework import BitcoinTestFramework
|
from test_framework.test_framework import BitcoinTestFramework
|
||||||
from test_framework.util import *
|
from test_framework.util import (
|
||||||
|
assert_equal,
|
||||||
|
connect_nodes,
|
||||||
|
disconnect_nodes,
|
||||||
|
find_output,
|
||||||
|
sync_blocks,
|
||||||
|
)
|
||||||
|
|
||||||
class TxnMallTest(BitcoinTestFramework):
|
class TxnMallTest(BitcoinTestFramework):
|
||||||
def set_test_params(self):
|
def set_test_params(self):
|
||||||
|
@ -84,14 +91,14 @@ class TxnMallTest(BitcoinTestFramework):
|
||||||
assert_equal(self.nodes[0].getbalance(), expected)
|
assert_equal(self.nodes[0].getbalance(), expected)
|
||||||
|
|
||||||
# foo and bar accounts should be debited:
|
# foo and bar accounts should be debited:
|
||||||
assert_equal(self.nodes[0].getbalance("foo", 0), 1219+tx1["amount"]+tx1["fee"])
|
assert_equal(self.nodes[0].getbalance("foo", 0), 1219 + tx1["amount"] + tx1["fee"])
|
||||||
assert_equal(self.nodes[0].getbalance("bar", 0), 29+tx2["amount"]+tx2["fee"])
|
assert_equal(self.nodes[0].getbalance("bar", 0), 29 + tx2["amount"] + tx2["fee"])
|
||||||
|
|
||||||
if self.options.mine_block:
|
if self.options.mine_block:
|
||||||
assert_equal(tx1["confirmations"], 1)
|
assert_equal(tx1["confirmations"], 1)
|
||||||
assert_equal(tx2["confirmations"], 1)
|
assert_equal(tx2["confirmations"], 1)
|
||||||
# Node1's "from0" balance should be both transaction amounts:
|
# Node1's "from0" balance should be both transaction amounts:
|
||||||
assert_equal(self.nodes[1].getbalance("from0"), -(tx1["amount"]+tx2["amount"]))
|
assert_equal(self.nodes[1].getbalance("from0"), -(tx1["amount"] + tx2["amount"]))
|
||||||
else:
|
else:
|
||||||
assert_equal(tx1["confirmations"], 0)
|
assert_equal(tx1["confirmations"], 0)
|
||||||
assert_equal(tx2["confirmations"], 0)
|
assert_equal(tx2["confirmations"], 0)
|
||||||
|
@ -128,18 +135,11 @@ class TxnMallTest(BitcoinTestFramework):
|
||||||
# fees (which are negative)
|
# fees (which are negative)
|
||||||
assert_equal(self.nodes[0].getbalance("foo"), 1219)
|
assert_equal(self.nodes[0].getbalance("foo"), 1219)
|
||||||
assert_equal(self.nodes[0].getbalance("bar"), 29)
|
assert_equal(self.nodes[0].getbalance("bar"), 29)
|
||||||
assert_equal(self.nodes[0].getbalance(""), starting_balance
|
assert_equal(self.nodes[0].getbalance(""),
|
||||||
-1219
|
starting_balance - 1219 - 29 - 1240 + 100 + fund_foo_tx["fee"] + fund_bar_tx["fee"] + doublespend_fee)
|
||||||
- 29
|
|
||||||
-1240
|
|
||||||
+ 100
|
|
||||||
+ fund_foo_tx["fee"]
|
|
||||||
+ fund_bar_tx["fee"]
|
|
||||||
+ doublespend_fee)
|
|
||||||
|
|
||||||
# Node1's "from0" account balance should be just the doublespend:
|
# Node1's "from0" account balance should be just the doublespend:
|
||||||
assert_equal(self.nodes[1].getbalance("from0"), 1240)
|
assert_equal(self.nodes[1].getbalance("from0"), 1240)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
TxnMallTest().main()
|
TxnMallTest().main()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue