2019-12-04 07:29:16 -08:00
|
|
|
#!/usr/bin/env python3
|
2016-03-19 12:58:06 -07:00
|
|
|
# Copyright (c) 2014-2016 The Bitcoin Core developers
|
2014-12-12 20:09:33 -08:00
|
|
|
# Distributed under the MIT software license, see the accompanying
|
2019-07-18 07:16:09 -07:00
|
|
|
# file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
2014-11-19 12:55:40 -08:00
|
|
|
|
2015-05-02 03:53:35 -07:00
|
|
|
from test_framework.test_framework import BitcoinTestFramework
|
2017-06-20 13:09:33 -07:00
|
|
|
from test_framework.authproxy import JSONRPCException
|
2020-12-29 09:42:46 -08:00
|
|
|
from test_framework.util import assert_equal, start_nodes, start_node, \
|
|
|
|
connect_nodes_bi, sync_blocks, sync_mempools
|
2017-06-20 13:09:33 -07:00
|
|
|
|
|
|
|
from decimal import Decimal
|
2014-11-19 12:55:40 -08:00
|
|
|
|
|
|
|
class WalletTest (BitcoinTestFramework):
|
|
|
|
|
2016-05-14 04:01:31 -07:00
|
|
|
def __init__(self):
|
|
|
|
super().__init__()
|
|
|
|
self.setup_clean_chain = True
|
|
|
|
self.num_nodes = 4
|
2014-11-19 12:55:40 -08:00
|
|
|
|
|
|
|
def setup_network(self, split=False):
|
|
|
|
self.nodes = start_nodes(3, self.options.tmpdir)
|
|
|
|
connect_nodes_bi(self.nodes,0,1)
|
|
|
|
connect_nodes_bi(self.nodes,1,2)
|
|
|
|
connect_nodes_bi(self.nodes,0,2)
|
|
|
|
self.is_network_split=False
|
|
|
|
self.sync_all()
|
|
|
|
|
|
|
|
def run_test (self):
|
2019-12-04 07:29:16 -08:00
|
|
|
print("Mining blocks...")
|
2014-11-19 12:55:40 -08:00
|
|
|
|
2016-06-07 02:01:33 -07:00
|
|
|
self.nodes[0].generate(4)
|
2019-12-18 12:34:39 -08:00
|
|
|
self.sync_all()
|
2014-11-19 12:55:40 -08:00
|
|
|
|
2014-12-24 23:57:16 -08:00
|
|
|
walletinfo = self.nodes[0].getwalletinfo()
|
2016-04-08 16:27:27 -07:00
|
|
|
assert_equal(walletinfo['immature_balance'], 40)
|
2014-12-24 23:57:16 -08:00
|
|
|
assert_equal(walletinfo['balance'], 0)
|
|
|
|
|
2019-11-26 14:42:29 -08:00
|
|
|
blockchaininfo = self.nodes[0].getblockchaininfo()
|
|
|
|
assert_equal(blockchaininfo['estimatedheight'], 4)
|
|
|
|
|
2014-11-19 12:55:40 -08:00
|
|
|
self.sync_all()
|
2015-03-31 20:28:28 -07:00
|
|
|
self.nodes[1].generate(101)
|
2014-11-19 12:55:40 -08:00
|
|
|
self.sync_all()
|
|
|
|
|
2016-04-08 16:27:27 -07:00
|
|
|
assert_equal(self.nodes[0].getbalance(), 40)
|
2016-06-07 02:01:33 -07:00
|
|
|
assert_equal(self.nodes[1].getbalance(), 10)
|
2014-11-19 12:55:40 -08:00
|
|
|
assert_equal(self.nodes[2].getbalance(), 0)
|
2016-09-20 16:22:30 -07:00
|
|
|
assert_equal(self.nodes[0].getbalance("*"), 40)
|
|
|
|
assert_equal(self.nodes[1].getbalance("*"), 10)
|
|
|
|
assert_equal(self.nodes[2].getbalance("*"), 0)
|
2014-11-19 12:55:40 -08:00
|
|
|
|
2020-12-17 11:39:58 -08:00
|
|
|
# Send 21 ZEC from 0 to 2 using sendtoaddress call.
|
2014-11-19 12:55:40 -08:00
|
|
|
# Second transaction will be child of first, and will require a fee
|
|
|
|
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
|
|
|
|
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
|
|
|
|
|
2014-12-24 23:57:16 -08:00
|
|
|
walletinfo = self.nodes[0].getwalletinfo()
|
|
|
|
assert_equal(walletinfo['immature_balance'], 0)
|
|
|
|
|
2019-11-26 14:42:29 -08:00
|
|
|
blockchaininfo = self.nodes[0].getblockchaininfo()
|
|
|
|
assert_equal(blockchaininfo['estimatedheight'], 105)
|
|
|
|
|
2015-04-28 07:48:28 -07:00
|
|
|
# Have node0 mine a block, thus it will collect its own fee.
|
2016-10-21 16:37:14 -07:00
|
|
|
self.sync_all()
|
2015-03-31 20:28:28 -07:00
|
|
|
self.nodes[0].generate(1)
|
2014-11-19 12:55:40 -08:00
|
|
|
self.sync_all()
|
|
|
|
|
|
|
|
# Have node1 generate 100 blocks (so node0 can recover the fee)
|
2015-03-31 20:28:28 -07:00
|
|
|
self.nodes[1].generate(100)
|
2014-11-19 12:55:40 -08:00
|
|
|
self.sync_all()
|
|
|
|
|
2020-12-17 11:39:58 -08:00
|
|
|
# node0 should end up with 50 ZEC in block rewards plus fees, but
|
|
|
|
# minus the 21 ZEC plus fees sent to node2
|
2016-06-07 02:01:33 -07:00
|
|
|
assert_equal(self.nodes[0].getbalance(), 50-21)
|
2014-11-19 12:55:40 -08:00
|
|
|
assert_equal(self.nodes[2].getbalance(), 21)
|
2016-09-20 16:22:30 -07:00
|
|
|
assert_equal(self.nodes[0].getbalance("*"), 50-21)
|
|
|
|
assert_equal(self.nodes[2].getbalance("*"), 21)
|
2014-11-19 12:55:40 -08:00
|
|
|
|
2016-06-07 02:01:33 -07:00
|
|
|
# Node0 should have three unspent outputs.
|
2015-07-14 12:13:16 -07:00
|
|
|
# Create a couple of transactions to send them to node2, submit them through
|
|
|
|
# node1, and make sure both node0 and node2 pick them up properly:
|
2014-11-19 12:55:40 -08:00
|
|
|
node0utxos = self.nodes[0].listunspent(1)
|
2016-06-07 02:01:33 -07:00
|
|
|
assert_equal(len(node0utxos), 3)
|
2014-11-19 12:55:40 -08:00
|
|
|
|
2017-07-11 00:53:55 -07:00
|
|
|
# Check 'generated' field of listunspent
|
|
|
|
# Node 0: has one coinbase utxo and two regular utxos
|
|
|
|
assert_equal(sum(int(uxto["generated"] is True) for uxto in node0utxos), 1)
|
|
|
|
# Node 1: has 101 coinbase utxos and no regular utxos
|
|
|
|
node1utxos = self.nodes[1].listunspent(1)
|
|
|
|
assert_equal(len(node1utxos), 101)
|
|
|
|
assert_equal(sum(int(uxto["generated"] is True) for uxto in node1utxos), 101)
|
|
|
|
# Node 2: has no coinbase utxos and two regular utxos
|
|
|
|
node2utxos = self.nodes[2].listunspent(1)
|
|
|
|
assert_equal(len(node2utxos), 2)
|
|
|
|
assert_equal(sum(int(uxto["generated"] is True) for uxto in node2utxos), 0)
|
|
|
|
|
2018-03-27 10:23:24 -07:00
|
|
|
# Catch an attempt to send a transaction with an absurdly high fee.
|
2020-12-17 11:39:58 -08:00
|
|
|
# Send 1.0 ZEC from an utxo of value 10.0 ZEC but don't specify a change output, so then
|
|
|
|
# the change of 9.0 ZEC becomes the fee, which is greater than estimated fee of 0.0021 ZEC.
|
2018-03-27 10:23:24 -07:00
|
|
|
inputs = []
|
|
|
|
outputs = {}
|
|
|
|
for utxo in node2utxos:
|
|
|
|
if utxo["amount"] == Decimal("10.0"):
|
|
|
|
break
|
|
|
|
assert_equal(utxo["amount"], Decimal("10.0"))
|
|
|
|
inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]})
|
|
|
|
outputs[self.nodes[2].getnewaddress("")] = Decimal("1.0")
|
|
|
|
raw_tx = self.nodes[2].createrawtransaction(inputs, outputs)
|
|
|
|
signed_tx = self.nodes[2].signrawtransaction(raw_tx)
|
|
|
|
try:
|
|
|
|
self.nodes[2].sendrawtransaction(signed_tx["hex"])
|
2019-12-04 07:29:16 -08:00
|
|
|
except JSONRPCException as e:
|
2018-03-27 10:23:24 -07:00
|
|
|
errorString = e.error['message']
|
|
|
|
assert("absurdly high fees" in errorString)
|
2019-12-18 13:40:50 -08:00
|
|
|
assert("900000000 > 10000000" in errorString)
|
2018-03-27 10:23:24 -07:00
|
|
|
|
2014-11-19 12:55:40 -08:00
|
|
|
# create both transactions
|
|
|
|
txns_to_send = []
|
2015-07-14 12:13:16 -07:00
|
|
|
for utxo in node0utxos:
|
2014-11-19 12:55:40 -08:00
|
|
|
inputs = []
|
|
|
|
outputs = {}
|
|
|
|
inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]})
|
2016-10-10 12:26:52 -07:00
|
|
|
outputs[self.nodes[2].getnewaddress("")] = utxo["amount"]
|
2014-11-19 12:55:40 -08:00
|
|
|
raw_tx = self.nodes[0].createrawtransaction(inputs, outputs)
|
|
|
|
txns_to_send.append(self.nodes[0].signrawtransaction(raw_tx))
|
|
|
|
|
|
|
|
# Have node 1 (miner) send the transactions
|
|
|
|
self.nodes[1].sendrawtransaction(txns_to_send[0]["hex"], True)
|
|
|
|
self.nodes[1].sendrawtransaction(txns_to_send[1]["hex"], True)
|
2016-06-07 02:01:33 -07:00
|
|
|
self.nodes[1].sendrawtransaction(txns_to_send[2]["hex"], True)
|
2014-11-19 12:55:40 -08:00
|
|
|
|
|
|
|
# Have node1 mine a block to confirm transactions:
|
2016-10-21 16:37:14 -07:00
|
|
|
self.sync_all()
|
2015-03-31 20:28:28 -07:00
|
|
|
self.nodes[1].generate(1)
|
2014-11-19 12:55:40 -08:00
|
|
|
self.sync_all()
|
|
|
|
|
|
|
|
assert_equal(self.nodes[0].getbalance(), 0)
|
2016-06-07 02:01:33 -07:00
|
|
|
assert_equal(self.nodes[2].getbalance(), 50)
|
2016-09-20 16:22:30 -07:00
|
|
|
assert_equal(self.nodes[0].getbalance("*"), 0)
|
|
|
|
assert_equal(self.nodes[2].getbalance("*"), 50)
|
2014-11-19 12:55:40 -08:00
|
|
|
|
2020-12-17 11:39:58 -08:00
|
|
|
# Send 10 ZEC normally
|
2016-10-10 12:26:52 -07:00
|
|
|
address = self.nodes[0].getnewaddress("")
|
2020-12-17 11:39:58 -08:00
|
|
|
self.nodes[2].settxfee(Decimal('0.001')) # not the default
|
2017-06-20 13:20:50 -07:00
|
|
|
self.nodes[2].sendtoaddress(address, 10, "", "", False)
|
2016-10-21 16:37:14 -07:00
|
|
|
self.sync_all()
|
2015-03-31 20:28:28 -07:00
|
|
|
self.nodes[2].generate(1)
|
2014-07-23 05:34:36 -07:00
|
|
|
self.sync_all()
|
2016-06-07 02:01:33 -07:00
|
|
|
assert_equal(self.nodes[2].getbalance(), Decimal('39.99900000'))
|
2014-07-23 05:34:36 -07:00
|
|
|
assert_equal(self.nodes[0].getbalance(), Decimal('10.00000000'))
|
2016-09-20 16:22:30 -07:00
|
|
|
assert_equal(self.nodes[2].getbalance("*"), Decimal('39.99900000'))
|
|
|
|
assert_equal(self.nodes[0].getbalance("*"), Decimal('10.00000000'))
|
2014-07-23 05:34:36 -07:00
|
|
|
|
2020-12-17 11:39:58 -08:00
|
|
|
# Send 10 ZEC with subtract fee from amount
|
2017-06-20 13:20:50 -07:00
|
|
|
self.nodes[2].sendtoaddress(address, 10, "", "", True)
|
2016-10-21 16:37:14 -07:00
|
|
|
self.sync_all()
|
2015-03-31 20:28:28 -07:00
|
|
|
self.nodes[2].generate(1)
|
2014-07-23 05:34:36 -07:00
|
|
|
self.sync_all()
|
2016-06-07 02:01:33 -07:00
|
|
|
assert_equal(self.nodes[2].getbalance(), Decimal('29.99900000'))
|
2014-07-23 05:34:36 -07:00
|
|
|
assert_equal(self.nodes[0].getbalance(), Decimal('19.99900000'))
|
2016-09-20 16:22:30 -07:00
|
|
|
assert_equal(self.nodes[2].getbalance("*"), Decimal('29.99900000'))
|
|
|
|
assert_equal(self.nodes[0].getbalance("*"), Decimal('19.99900000'))
|
2014-11-19 12:55:40 -08:00
|
|
|
|
2020-12-17 11:39:58 -08:00
|
|
|
# Sendmany 10 ZEC
|
2017-06-20 13:20:50 -07:00
|
|
|
self.nodes[2].sendmany("", {address: 10}, 0, "", [])
|
2016-10-21 16:37:14 -07:00
|
|
|
self.sync_all()
|
2015-03-31 20:28:28 -07:00
|
|
|
self.nodes[2].generate(1)
|
2015-03-05 05:59:19 -08:00
|
|
|
self.sync_all()
|
2016-06-07 02:01:33 -07:00
|
|
|
assert_equal(self.nodes[2].getbalance(), Decimal('19.99800000'))
|
2015-03-05 05:59:19 -08:00
|
|
|
assert_equal(self.nodes[0].getbalance(), Decimal('29.99900000'))
|
2016-09-20 16:22:30 -07:00
|
|
|
assert_equal(self.nodes[2].getbalance("*"), Decimal('19.99800000'))
|
|
|
|
assert_equal(self.nodes[0].getbalance("*"), Decimal('29.99900000'))
|
2015-03-05 05:59:19 -08:00
|
|
|
|
2020-12-17 11:39:58 -08:00
|
|
|
# Sendmany 10 ZEC with subtract fee from amount
|
2017-06-20 13:20:50 -07:00
|
|
|
self.nodes[2].sendmany("", {address: 10}, 0, "", [address])
|
2016-10-21 16:37:14 -07:00
|
|
|
self.sync_all()
|
2015-03-31 20:28:28 -07:00
|
|
|
self.nodes[2].generate(1)
|
2015-03-05 05:59:19 -08:00
|
|
|
self.sync_all()
|
2016-06-07 02:01:33 -07:00
|
|
|
assert_equal(self.nodes[2].getbalance(), Decimal('9.99800000'))
|
2015-03-05 05:59:19 -08:00
|
|
|
assert_equal(self.nodes[0].getbalance(), Decimal('39.99800000'))
|
2016-09-20 16:22:30 -07:00
|
|
|
assert_equal(self.nodes[2].getbalance("*"), Decimal('9.99800000'))
|
|
|
|
assert_equal(self.nodes[0].getbalance("*"), Decimal('39.99800000'))
|
2015-03-05 05:59:19 -08:00
|
|
|
|
2015-03-23 10:47:18 -07:00
|
|
|
# Test ResendWalletTransactions:
|
|
|
|
# Create a couple of transactions, then start up a fourth
|
|
|
|
# node (nodes[3]) and ask nodes[0] to rebroadcast.
|
|
|
|
# EXPECT: nodes[3] should have those transactions in its mempool.
|
|
|
|
txid1 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1)
|
|
|
|
txid2 = self.nodes[1].sendtoaddress(self.nodes[0].getnewaddress(), 1)
|
|
|
|
sync_mempools(self.nodes)
|
|
|
|
|
|
|
|
self.nodes.append(start_node(3, self.options.tmpdir))
|
|
|
|
connect_nodes_bi(self.nodes, 0, 3)
|
|
|
|
sync_blocks(self.nodes)
|
|
|
|
|
|
|
|
relayed = self.nodes[0].resendwallettransactions()
|
|
|
|
assert_equal(set(relayed), set([txid1, txid2]))
|
|
|
|
sync_mempools(self.nodes)
|
|
|
|
|
|
|
|
assert(txid1 in self.nodes[3].getrawmempool())
|
2016-10-10 12:27:16 -07:00
|
|
|
|
2020-01-28 12:36:26 -08:00
|
|
|
# check integer balances from getbalance
|
2020-12-29 09:42:46 -08:00
|
|
|
assert_equal(self.nodes[2].getbalance("*", 1, False, True), 999800000)
|
2016-09-20 16:22:30 -07:00
|
|
|
|
|
|
|
# send from node 0 to node 2 taddr
|
2018-08-21 13:00:04 -07:00
|
|
|
mytaddr = self.nodes[2].getnewaddress()
|
|
|
|
mytxid = self.nodes[0].sendtoaddress(mytaddr, 10.0)
|
2016-10-21 16:37:14 -07:00
|
|
|
self.sync_all()
|
2016-09-20 16:22:30 -07:00
|
|
|
self.nodes[0].generate(1)
|
|
|
|
self.sync_all()
|
|
|
|
|
|
|
|
mybalance = self.nodes[2].z_getbalance(mytaddr)
|
2018-08-21 13:00:04 -07:00
|
|
|
assert_equal(mybalance, Decimal('10.0'))
|
2016-09-20 16:22:30 -07:00
|
|
|
|
2020-01-28 12:55:37 -08:00
|
|
|
# check integer balances from z_getbalance
|
2020-05-30 08:18:43 -07:00
|
|
|
assert_equal(self.nodes[2].z_getbalance(mytaddr, 1, True), 1000000000)
|
2020-01-28 12:55:37 -08:00
|
|
|
|
2016-10-06 18:55:14 -07:00
|
|
|
mytxdetails = self.nodes[2].gettransaction(mytxid)
|
|
|
|
myvjoinsplits = mytxdetails["vjoinsplit"]
|
|
|
|
assert_equal(0, len(myvjoinsplits))
|
2020-06-20 01:56:21 -07:00
|
|
|
assert("joinSplitPubKey" not in mytxdetails)
|
|
|
|
assert("joinSplitSig" not in mytxdetails)
|
2016-10-06 18:55:14 -07:00
|
|
|
|
2014-11-19 12:55:40 -08:00
|
|
|
if __name__ == '__main__':
|
|
|
|
WalletTest ().main ()
|