aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrbandrews <bandrewsny@gmail.com>2014-11-19 15:55:40 -0500
committermrbandrews <bandrewsny@gmail.com>2014-11-20 14:11:44 -0500
commit189fb526f188e90eed24840b826b6c6b97f3e479 (patch)
tree7502e79afc0f0d4255df729cf0fff132b4a1f92e
parentb5d1b1092998bc95313856d535c632ea5a8f9104 (diff)
Port of wallet.sh to python (wallet.py).
Also included are minor edits to util.py to create a clean blockchain and add a parameter to gather_inputs to specify number of confirmations.
-rw-r--r--qa/rpc-tests/util.py16
-rwxr-xr-xqa/rpc-tests/wallet.py100
-rwxr-xr-xqa/rpc-tests/wallet.sh118
3 files changed, 113 insertions, 121 deletions
diff --git a/qa/rpc-tests/util.py b/qa/rpc-tests/util.py
index c6d918a81c..bed7fed8ca 100644
--- a/qa/rpc-tests/util.py
+++ b/qa/rpc-tests/util.py
@@ -57,7 +57,6 @@ def sync_mempools(rpc_connections):
if num_match == len(rpc_connections):
break
time.sleep(1)
-
bitcoind_processes = {}
@@ -130,6 +129,15 @@ def initialize_chain(test_dir):
shutil.copytree(from_dir, to_dir)
initialize_datadir(test_dir, i) # Overwrite port/rpcport in bitcoin.conf
+def initialize_chain_clean(test_dir, num_nodes):
+ """
+ Create an empty blockchain and num_nodes wallets.
+ Useful if a test case wants complete control over initialization.
+ """
+ for i in range(num_nodes):
+ datadir=initialize_datadir(test_dir, i)
+
+
def _rpchost_to_args(rpchost):
'''Convert optional IP:port spec to rpcconnect/rpcport args'''
if rpchost is None:
@@ -221,11 +229,13 @@ def find_output(node, txid, amount):
return i
raise RuntimeError("find_output txid %s : %s not found"%(txid,str(amount)))
-def gather_inputs(from_node, amount_needed):
+
+def gather_inputs(from_node, amount_needed, confirmations_required=1):
"""
Return a random set of unspent txouts that are enough to pay amount_needed
"""
- utxo = from_node.listunspent(1)
+ assert(confirmations_required >=0)
+ utxo = from_node.listunspent(confirmations_required)
random.shuffle(utxo)
inputs = []
total_in = Decimal("0.00000000")
diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py
new file mode 100755
index 0000000000..4271d96be7
--- /dev/null
+++ b/qa/rpc-tests/wallet.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+# Copyright (c) 2014 The Bitcoin Core developers
+# Distributed under the MIT/X11 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 101 blocks, so now nodes 0 and 1 have 50btc, node2 has none.
+# d) node0 sends 21 btc to node2, in two transactions (11 btc, then 10 btc).
+# e) node0 mines a block, collects the fee on the second transaction
+# f) node1 mines 100 blocks, to mature node0's just-mined block
+# g) check that node0 has 100-21, node2 has 21
+# 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 100
+#
+
+from test_framework import BitcoinTestFramework
+from util import *
+
+
+class WalletTest (BitcoinTestFramework):
+
+ def setup_chain(self):
+ print("Initializing test directory "+self.options.tmpdir)
+ initialize_chain_clean(self.options.tmpdir, 3)
+
+ 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].setgenerate(True, 1)
+
+ self.sync_all()
+ self.nodes[1].setgenerate(True, 101)
+ self.sync_all()
+
+ assert_equal(self.nodes[0].getbalance(), 50)
+ assert_equal(self.nodes[1].getbalance(), 50)
+ assert_equal(self.nodes[2].getbalance(), 0)
+
+ # Send 21 BTC 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(), 11)
+ self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
+
+ # Have node0 mine a block, thus he will collect his own fee.
+ self.nodes[0].setgenerate(True, 1)
+ self.sync_all()
+
+ # Have node1 generate 100 blocks (so node0 can recover the fee)
+ self.nodes[1].setgenerate(True, 100)
+ self.sync_all()
+
+ # node0 should end up with 100 btc in block rewards plus fees, but
+ # minus the 21 plus fees sent to node2
+ assert_equal(self.nodes[0].getbalance(), 100-21)
+ assert_equal(self.nodes[2].getbalance(), 21)
+
+ # 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].setgenerate(True, 1)
+ self.sync_all()
+
+ assert_equal(self.nodes[0].getbalance(), 0)
+ assert_equal(self.nodes[2].getbalance(), 100)
+ assert_equal(self.nodes[2].getbalance("from1"), 100-21)
+
+
+if __name__ == '__main__':
+ WalletTest ().main ()
diff --git a/qa/rpc-tests/wallet.sh b/qa/rpc-tests/wallet.sh
deleted file mode 100755
index c9ad0f2a78..0000000000
--- a/qa/rpc-tests/wallet.sh
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/usr/bin/env bash
-# Copyright (c) 2013-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.
-
-# Test block generation and basic wallet sending
-
-if [ $# -lt 1 ]; then
- echo "Usage: $0 path_to_binaries"
- echo "e.g. $0 ../../src"
- echo "Env vars BITCOIND and BITCOINCLI may be used to specify the exact binaries used"
- exit 1
-fi
-
-set -f
-
-BITCOIND=${BITCOIND:-${1}/bitcoind}
-CLI=${BITCOINCLI:-${1}/bitcoin-cli}
-
-DIR="${BASH_SOURCE%/*}"
-SENDANDWAIT="${DIR}/send.sh"
-if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
-. "$DIR/util.sh"
-
-D=$(mktemp -d test.XXXXX)
-
-D1=${D}/node1
-CreateDataDir "$D1" port=11000 rpcport=11001
-B1ARGS="-datadir=$D1"
-$BITCOIND $B1ARGS &
-B1PID=$!
-
-D2=${D}/node2
-CreateDataDir "$D2" port=11010 rpcport=11011 connect=127.0.0.1:11000
-B2ARGS="-datadir=$D2"
-$BITCOIND $B2ARGS &
-B2PID=$!
-
-D3=${D}/node3
-CreateDataDir "$D3" port=11020 rpcport=11021 connect=127.0.0.1:11000
-B3ARGS="-datadir=$D3"
-$BITCOIND $BITCOINDARGS $B3ARGS &
-B3PID=$!
-
-# Wait until all three nodes are at the same block number
-function WaitBlocks {
- while :
- do
- sleep 1
- declare -i BLOCKS1=$( GetBlocks $B1ARGS )
- declare -i BLOCKS2=$( GetBlocks $B2ARGS )
- declare -i BLOCKS3=$( GetBlocks $B3ARGS )
- if (( BLOCKS1 == BLOCKS2 && BLOCKS2 == BLOCKS3 ))
- then
- break
- fi
- done
-}
-
-echo "Generating test blockchain..."
-
-# 1 block, 50 XBT each == 50 XBT
-$CLI $B1ARGS setgenerate true 1
-WaitBlocks
-# 101 blocks, 1 mature == 50 XBT
-$CLI $B2ARGS setgenerate true 101
-WaitBlocks
-
-CheckBalance "$B1ARGS" 50
-CheckBalance "$B2ARGS" 50
-
-# Send 21 XBT from 1 to 3. Second
-# transaction will be child of first, and
-# will require a fee
-Send $B1ARGS $B3ARGS 11
-Send $B1ARGS $B3ARGS 10
-
-# Have B1 mine a new block, and mature it
-# to recover transaction fees
-$CLI $B1ARGS setgenerate true 1
-WaitBlocks
-
-# Have B2 mine 100 blocks so B1's block is mature:
-$CLI $B2ARGS setgenerate true 100
-WaitBlocks
-
-# B1 should end up with 100 XBT in block rewards plus fees,
-# minus the 21 XBT sent to B3:
-CheckBalance "$B1ARGS" "100-21"
-CheckBalance "$B3ARGS" "21"
-
-# B1 should have two unspent outputs; create a couple
-# of raw transactions to send them to B3, submit them through
-# B2, and make sure both B1 and B3 pick them up properly:
-RAW1=$(CreateTxn1 $B1ARGS 1 $(Address $B3ARGS "from1" ) )
-RAW2=$(CreateTxn1 $B1ARGS 2 $(Address $B3ARGS "from1" ) )
-RAWTXID1=$(SendRawTxn "$B2ARGS" $RAW1)
-RAWTXID2=$(SendRawTxn "$B2ARGS" $RAW2)
-
-# Have B2 mine a block to confirm transactions:
-$CLI $B2ARGS setgenerate true 1
-WaitBlocks
-
-# Check balances after confirmation
-CheckBalance "$B1ARGS" 0
-CheckBalance "$B3ARGS" 100
-CheckBalance "$B3ARGS" "100-21" "from1"
-
-$CLI $B3ARGS stop > /dev/null 2>&1
-wait $B3PID
-$CLI $B2ARGS stop > /dev/null 2>&1
-wait $B2PID
-$CLI $B1ARGS stop > /dev/null 2>&1
-wait $B1PID
-
-echo "Tests successful, cleaning up"
-rm -rf $D
-exit 0