dogecoin/qa/rpc-tests/wallet.py
2015-08-02 20:08:42 +02:00

223 lines
9.3 KiB
Python
Executable file

#!/usr/bin/env python2
# Copyright (c) 2014 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
#
# Exercise the wallet. Ported from wallet.sh.
# Does the following:
# a) creates 3 nodes, with an empty chain (no blocks).
# b) node0 mines a block
# c) node1 mines 61 blocks, so now nodes 0 and 1 have 500.000 doge, node2 has none.
# d) node0 sends 210.000 doge to node2, in two transactions (110.000 doge, then 100.000 doge).
# e) node0 mines a block, collects the fee on the second transaction
# f) node1 mines 30 blocks, to mature node0's just-mined block
# g) check that node0 has 1.000.000-210.000, node2 has 210.000
# h) node0 should now have 2 unspent outputs; send these to node2 via raw tx broadcast by node1
# i) have node1 mine a block
# j) check balances - node0 should have 0, node2 should have 1.000.000
# k) test ResendWalletTransactions - create transactions, startup fourth node, make sure it syncs
#
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *
class WalletTest (BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
initialize_chain_clean(self.options.tmpdir, 4)
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):
print "Mining blocks..."
self.nodes[0].generate(1)
walletinfo = self.nodes[0].getwalletinfo()
assert_equal(walletinfo['immature_balance'], 500000)
assert_equal(walletinfo['balance'], 0)
self.sync_all()
self.nodes[1].generate(61)
self.sync_all()
assert_equal(self.nodes[0].getbalance(), 500000)
assert_equal(self.nodes[1].getbalance(), 500000)
assert_equal(self.nodes[2].getbalance(), 0)
# Send 210.000 DOGE from 0 to 2 using sendtoaddress call.
# Second transaction will be child of first, and will require a fee
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 110000)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 100000)
walletinfo = self.nodes[0].getwalletinfo()
assert_equal(walletinfo['immature_balance'], 0)
# Have node0 mine a block, thus it will collect its own fee.
self.nodes[0].generate(1)
self.sync_all()
# Have node1 generate 60 blocks (so node0 can recover the fee)
self.nodes[1].generate(60)
self.sync_all()
# node0 should end up with 1.000.000 doge in block rewards plus fees, but
# minus the 210.000 plus fees sent to node2
assert_equal(self.nodes[0].getbalance(), 1000000-210000)
assert_equal(self.nodes[2].getbalance(), 210000)
# Node0 should have two unspent outputs.
# 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:
node0utxos = self.nodes[0].listunspent(1)
assert_equal(len(node0utxos), 2)
# create both transactions
txns_to_send = []
for utxo in node0utxos:
inputs = []
outputs = {}
inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]})
outputs[self.nodes[2].getnewaddress("from1")] = utxo["amount"]
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)
# Have node1 mine a block to confirm transactions:
self.nodes[1].generate(1)
self.sync_all()
assert_equal(self.nodes[0].getbalance(), 0)
assert_equal(self.nodes[2].getbalance(), 1000000)
assert_equal(self.nodes[2].getbalance("from1"), 1000000-210000)
# Send 100000 DOGE normal
address = self.nodes[0].getnewaddress("test")
self.nodes[2].settxfee(1)
txid = self.nodes[2].sendtoaddress(address, 100000, "", "", False)
self.nodes[2].generate(1)
self.sync_all()
assert_equal(self.nodes[2].getbalance(), 899999)
assert_equal(self.nodes[0].getbalance(), 100000)
# Send 100000 DOGE with subtract fee from amount
txid = self.nodes[2].sendtoaddress(address, 100000, "", "", True)
self.nodes[2].generate(1)
self.sync_all()
assert_equal(self.nodes[2].getbalance(), 799999)
assert_equal(self.nodes[0].getbalance(), 199999)
# Sendmany 100000 DOGE
txid = self.nodes[2].sendmany('from1', {address: 100000}, 0, "", [])
self.nodes[2].generate(1)
self.sync_all()
assert_equal(self.nodes[2].getbalance(), 699998)
assert_equal(self.nodes[0].getbalance(), 299999)
# Sendmany 100000 with subtract fee from amount
txid = self.nodes[2].sendmany('from1', {address: 100000}, 0, "", [address])
self.nodes[2].generate(1)
self.sync_all()
assert_equal(self.nodes[2].getbalance(), 599998)
assert_equal(self.nodes[0].getbalance(), 399998)
# 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())
#check if we can list zero value tx as available coins
#1. create rawtx
#2. hex-changed one output to 0.0
#3. sign and send
#4. check if recipient (node0) can list the zero value tx
usp = self.nodes[1].listunspent()
inputs = [{"txid":usp[0]['txid'], "vout":usp[0]['vout']}]
outputs = {self.nodes[1].getnewaddress(): 499998, self.nodes[0].getnewaddress(): 11.11}
rawTx = self.nodes[1].createrawtransaction(inputs, outputs).replace("c0833842", "00000000") #replace 11.11 with 0.0 (int32)
decRawTx = self.nodes[1].decoderawtransaction(rawTx)
signedRawTx = self.nodes[1].signrawtransaction(rawTx)
decRawTx = self.nodes[1].decoderawtransaction(signedRawTx['hex'])
zeroValueTxid= decRawTx['txid']
sendResp = self.nodes[1].sendrawtransaction(signedRawTx['hex'])
self.sync_all()
self.nodes[1].generate(1) #mine a block
self.sync_all()
unspentTxs = self.nodes[0].listunspent() #zero value tx must be in listunspents output
found = False
for uTx in unspentTxs:
if uTx['txid'] == zeroValueTxid:
found = True
assert_equal(uTx['amount'], Decimal('0.00000000'));
assert(found)
#do some -walletbroadcast tests
stop_nodes(self.nodes)
wait_bitcoinds()
self.nodes = start_nodes(3, self.options.tmpdir, [["-walletbroadcast=0"],["-walletbroadcast=0"],["-walletbroadcast=0"]])
connect_nodes_bi(self.nodes,0,1)
connect_nodes_bi(self.nodes,1,2)
connect_nodes_bi(self.nodes,0,2)
self.sync_all()
txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 20000);
txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted)
self.nodes[1].generate(1) #mine a block, tx should not be in there
self.sync_all()
assert_equal(self.nodes[2].getbalance(), 599998); #should not be changed because tx was not broadcasted
#now broadcast from another node, mine a block, sync, and check the balance
self.nodes[1].sendrawtransaction(txObjNotBroadcasted['hex'])
self.nodes[1].generate(1)
self.sync_all()
txObjNotBroadcasted = self.nodes[0].gettransaction(txIdNotBroadcasted)
assert_equal(self.nodes[2].getbalance(), 619998); #should not be
#create another tx
txIdNotBroadcasted = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 20000);
#restart the nodes with -walletbroadcast=1
stop_nodes(self.nodes)
wait_bitcoinds()
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)
sync_blocks(self.nodes)
self.nodes[0].generate(1)
sync_blocks(self.nodes)
#tx should be added to balance because after restarting the nodes tx should be broadcastet
assert_equal(self.nodes[2].getbalance(), 639998); #should not be
if __name__ == '__main__':
WalletTest ().main ()