Changeset View
Changeset View
Standalone View
Standalone View
test/functional/wallet_basic.py
Show First 20 Lines • Show All 238 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
node_0_bal = self.check_fee_amount(self.nodes[0].getbalance( | node_0_bal = self.check_fee_amount(self.nodes[0].getbalance( | ||||
), node_0_bal + Decimal('10'), fee_per_byte, ctx.billable_size()) | ), node_0_bal + Decimal('10'), fee_per_byte, ctx.billable_size()) | ||||
self.start_node(3, self.extra_args[3]) | self.start_node(3, self.extra_args[3]) | ||||
connect_nodes(self.nodes[0], self.nodes[3]) | connect_nodes(self.nodes[0], self.nodes[3]) | ||||
self.sync_all() | self.sync_all() | ||||
# 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( | ||||
query_options={'minimumAmount': '49.998'})[0] | query_options={'minimumAmount': '49.998'})[0] | ||||
inputs = [{"txid": usp['txid'], "vout": usp['vout']}] | inputs = [{"txid": usp['txid'], "vout": usp['vout']}] | ||||
outputs = {self.nodes[1].getnewaddress(): 49.998, | outputs = {self.nodes[1].getnewaddress(): 49.998, | ||||
self.nodes[0].getnewaddress(): 11.11} | self.nodes[0].getnewaddress(): 11.11} | ||||
rawTx = self.nodes[1].createrawtransaction(inputs, outputs).replace( | rawTx = self.nodes[1].createrawtransaction(inputs, outputs).replace( | ||||
"c0833842", "00000000") # replace 11.11 with 0.0 (int32) | "c0833842", "00000000") # replace 11.11 with 0.0 (int32) | ||||
decRawTx = self.nodes[1].decoderawtransaction(rawTx) | signed_raw_tx = self.nodes[1].signrawtransactionwithwallet(rawTx) | ||||
signedRawTx = self.nodes[1].signrawtransactionwithwallet(rawTx) | decoded_raw_tx = self.nodes[1].decoderawtransaction( | ||||
decRawTx = self.nodes[1].decoderawtransaction(signedRawTx['hex']) | signed_raw_tx['hex']) | ||||
zeroValueTxid = decRawTx['txid'] | zero_value_txid = decoded_raw_tx['txid'] | ||||
self.nodes[1].sendrawtransaction(signedRawTx['hex']) | self.nodes[1].sendrawtransaction(signed_raw_tx['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() | ||||
# zero value tx must be in listunspents output | # zero value tx must be in listunspents output | ||||
unspentTxs = self.nodes[0].listunspent() | unspent_txs = self.nodes[0].listunspent() | ||||
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, self.extra_args[0] + ["-walletbroadcast=0"]) | self.start_node(0, self.extra_args[0] + ["-walletbroadcast=0"]) | ||||
self.start_node(1, self.extra_args[1] + ["-walletbroadcast=0"]) | self.start_node(1, self.extra_args[1] + ["-walletbroadcast=0"]) | ||||
self.start_node(2, self.extra_args[2] + ["-walletbroadcast=0"]) | self.start_node(2, self.extra_args[2] + ["-walletbroadcast=0"]) | ||||
connect_nodes(self.nodes[0], self.nodes[1]) | connect_nodes(self.nodes[0], self.nodes[1]) | ||||
connect_nodes(self.nodes[1], self.nodes[2]) | connect_nodes(self.nodes[1], self.nodes[2]) | ||||
connect_nodes(self.nodes[0], self.nodes[2]) | connect_nodes(self.nodes[0], self.nodes[2]) | ||||
self.sync_all(self.nodes[0:3]) | self.sync_all(self.nodes[0:3]) | ||||
txIdNotBroadcasted = self.nodes[0].sendtoaddress( | txid_not_broadcast = self.nodes[0].sendtoaddress( | ||||
self.nodes[2].getnewaddress(), 2) | 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]) | ||||
# should not be changed because tx was not broadcasted | # should not be changed because tx was not broadcasted | ||||
assert_equal(self.nodes[2].getbalance(), node_2_bal) | assert_equal(self.nodes[2].getbalance(), node_2_bal) | ||||
# now broadcast from another node, mine a block, sync, and check the | # now broadcast from another node, mine a block, sync, and check the | ||||
# balance | # 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( | txid_not_broadcast = self.nodes[0].sendtoaddress( | ||||
self.nodes[2].getnewaddress(), 2) | 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.extra_args[0]) | self.start_node(0, self.extra_args[0]) | ||||
self.start_node(1, self.extra_args[1]) | self.start_node(1, self.extra_args[1]) | ||||
self.start_node(2, self.extra_args[2]) | self.start_node(2, self.extra_args[2]) | ||||
connect_nodes(self.nodes[0], self.nodes[1]) | connect_nodes(self.nodes[0], self.nodes[1]) | ||||
connect_nodes(self.nodes[1], self.nodes[2]) | connect_nodes(self.nodes[1], self.nodes[2]) | ||||
connect_nodes(self.nodes[0], self.nodes[2]) | connect_nodes(self.nodes[0], self.nodes[2]) | ||||
self.sync_blocks(self.nodes[0:3]) | self.sync_blocks(self.nodes[0:3]) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
self.sync_blocks(self.nodes[0:3]) | self.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 | # tx should be added to balance because after restarting the nodes tx | ||||
# should be broadcasted | # should be broadcasted | ||||
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( | txid = self.nodes[0].sendtoaddress( | ||||
self.nodes[2].getnewaddress(), "0.0001") | 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( | txid = self.nodes[0].sendtoaddress( | ||||
self.nodes[2].getnewaddress(), "1e-4") | 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')) | ||||
# General checks for errors from incorrect inputs | # General checks for errors from incorrect inputs | ||||
# 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", | assert_raises_rpc_error(-3, "Invalid amount", | ||||
self.nodes[0].sendtoaddress, self.nodes[2].getnewaddress(), "1f-4") | self.nodes[0].sendtoaddress, self.nodes[2].getnewaddress(), "1f-4") | ||||
# This will raise an exception since generate does not accept a string | # This will raise an exception since generate does not accept a string | ||||
assert_raises_rpc_error(-1, "not an integer", | assert_raises_rpc_error(-1, "not an integer", | ||||
▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
self.nodes[1].importprivkey(priv_key) | self.nodes[1].importprivkey(priv_key) | ||||
# 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]) | ||||
blocks = self.nodes[0].generate(2) | blocks = self.nodes[0].generate(2) | ||||
self.sync_all(self.nodes[0:3]) | self.sync_all(self.nodes[0:3]) | ||||
balance_nodes = [self.nodes[i].getbalance() for i in range(3)] | balance_nodes = [self.nodes[i].getbalance() for i in range(3)] | ||||
block_count = self.nodes[0].getblockcount() | block_count = self.nodes[0].getblockcount() | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
# Get all non-zero utxos together | # Get all non-zero utxos together | ||||
chain_addrs = [self.nodes[0].getnewaddress( | chain_addrs = [self.nodes[0].getnewaddress( | ||||
), self.nodes[0].getnewaddress()] | ), self.nodes[0].getnewaddress()] | ||||
singletxid = self.nodes[0].sendtoaddress( | singletxid = self.nodes[0].sendtoaddress( | ||||
chain_addrs[0], self.nodes[0].getbalance(), "", "", True) | chain_addrs[0], self.nodes[0].getbalance(), "", "", True) | ||||
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}], { | raw_tx = 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')}) | 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(raw_tx) | ||||
singletxid = self.nodes[0].sendrawtransaction(signedtx["hex"]) | singletxid = self.nodes[0].sendrawtransaction(signedtx["hex"]) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
# Make a long chain of unconfirmed payments without hitting mempool limit | # Make a long chain of unconfirmed payments without hitting mempool limit | ||||
# Each tx we make leaves only one output of change on a chain 1 longer | # Each tx we make leaves only one output of change on a chain 1 longer | ||||
# Since the amount to send is always much less than the outputs, we only ever need one output | # Since the amount to send is always much less than the outputs, we only ever need one output | ||||
# So we should be able to generate exactly chainlimit txs for each | # So we should be able to generate exactly chainlimit txs for each | ||||
# original output | # original output | ||||
▲ Show 20 Lines • Show All 129 Lines • Show Last 20 Lines |