Dash Core  0.12.2.1
P2P Digital Currency
addressindex.py
Go to the documentation of this file.
1 #!/usr/bin/env python2
2 # Copyright (c) 2014-2015 The Bitcoin Core developers
3 # Distributed under the MIT software license, see the accompanying
4 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #
7 # Test addressindex generation and fetching
8 #
9 
10 import time
11 from test_framework.test_framework import BitcoinTestFramework
12 from test_framework.util import *
13 from test_framework.script import *
14 from test_framework.mininode import *
15 import binascii
16 
18 
19  def setup_chain(self):
20  print("Initializing test directory "+self.options.tmpdir)
21  initialize_chain_clean(self.options.tmpdir, 4)
22 
23  def setup_network(self):
24  self.nodes = []
25  # Nodes 0/1 are "wallet" nodes
26  self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-relaypriority=0"]))
27  self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-addressindex"]))
28  # Nodes 2/3 are used for testing
29  self.nodes.append(start_node(2, self.options.tmpdir, ["-debug", "-addressindex", "-relaypriority=0"]))
30  self.nodes.append(start_node(3, self.options.tmpdir, ["-debug", "-addressindex"]))
31  connect_nodes(self.nodes[0], 1)
32  connect_nodes(self.nodes[0], 2)
33  connect_nodes(self.nodes[0], 3)
34 
35  self.is_network_split = False
36  self.sync_all()
37 
38  def run_test(self):
39  print "Mining blocks..."
40  self.nodes[0].generate(105)
41  self.sync_all()
42 
43  chain_height = self.nodes[1].getblockcount()
44  assert_equal(chain_height, 105)
45  assert_equal(self.nodes[1].getbalance(), 0)
46  assert_equal(self.nodes[2].getbalance(), 0)
47 
48  # Check that balances are correct
49  balance0 = self.nodes[1].getaddressbalance("93bVhahvUKmQu8gu9g3QnPPa2cxFK98pMB")
50  assert_equal(balance0["balance"], 0)
51 
52  # Check p2pkh and p2sh address indexes
53  print "Testing p2pkh and p2sh address index..."
54 
55  txid0 = self.nodes[0].sendtoaddress("yMNJePdcKvXtWWQnFYHNeJ5u8TF2v1dfK4", 10)
56  self.nodes[0].generate(1)
57 
58  txidb0 = self.nodes[0].sendtoaddress("93bVhahvUKmQu8gu9g3QnPPa2cxFK98pMB", 10)
59  self.nodes[0].generate(1)
60 
61  txid1 = self.nodes[0].sendtoaddress("yMNJePdcKvXtWWQnFYHNeJ5u8TF2v1dfK4", 15)
62  self.nodes[0].generate(1)
63 
64  txidb1 = self.nodes[0].sendtoaddress("93bVhahvUKmQu8gu9g3QnPPa2cxFK98pMB", 15)
65  self.nodes[0].generate(1)
66 
67  txid2 = self.nodes[0].sendtoaddress("yMNJePdcKvXtWWQnFYHNeJ5u8TF2v1dfK4", 20)
68  self.nodes[0].generate(1)
69 
70  txidb2 = self.nodes[0].sendtoaddress("93bVhahvUKmQu8gu9g3QnPPa2cxFK98pMB", 20)
71  self.nodes[0].generate(1)
72 
73  self.sync_all()
74 
75  txids = self.nodes[1].getaddresstxids("yMNJePdcKvXtWWQnFYHNeJ5u8TF2v1dfK4")
76  assert_equal(len(txids), 3)
77  assert_equal(txids[0], txid0)
78  assert_equal(txids[1], txid1)
79  assert_equal(txids[2], txid2)
80 
81  txidsb = self.nodes[1].getaddresstxids("93bVhahvUKmQu8gu9g3QnPPa2cxFK98pMB")
82  assert_equal(len(txidsb), 3)
83  assert_equal(txidsb[0], txidb0)
84  assert_equal(txidsb[1], txidb1)
85  assert_equal(txidsb[2], txidb2)
86 
87  # Check that limiting by height works
88  print "Testing querying txids by range of block heights.."
89  height_txids = self.nodes[1].getaddresstxids({
90  "addresses": ["93bVhahvUKmQu8gu9g3QnPPa2cxFK98pMB"],
91  "start": 105,
92  "end": 110
93  })
94  assert_equal(len(height_txids), 2)
95  assert_equal(height_txids[0], txidb0)
96  assert_equal(height_txids[1], txidb1)
97 
98  # Check that multiple addresses works
99  multitxids = self.nodes[1].getaddresstxids({"addresses": ["93bVhahvUKmQu8gu9g3QnPPa2cxFK98pMB", "yMNJePdcKvXtWWQnFYHNeJ5u8TF2v1dfK4"]})
100  assert_equal(len(multitxids), 6)
101  assert_equal(multitxids[0], txid0)
102  assert_equal(multitxids[1], txidb0)
103  assert_equal(multitxids[2], txid1)
104  assert_equal(multitxids[3], txidb1)
105  assert_equal(multitxids[4], txid2)
106  assert_equal(multitxids[5], txidb2)
107 
108  # Check that balances are correct
109  balance0 = self.nodes[1].getaddressbalance("93bVhahvUKmQu8gu9g3QnPPa2cxFK98pMB")
110  assert_equal(balance0["balance"], 45 * 100000000)
111 
112  # Check that outputs with the same address will only return one txid
113  print "Testing for txid uniqueness..."
114  addressHash = "FE30B718DCF0BF8A2A686BF1820C073F8B2C3B37".decode("hex")
115  scriptPubKey = CScript([OP_HASH160, addressHash, OP_EQUAL])
116  unspent = self.nodes[0].listunspent()
117  tx = CTransaction()
118  tx.vin = [CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))]
119  tx.vout = [CTxOut(10, scriptPubKey), CTxOut(11, scriptPubKey)]
120  tx.rehash()
121 
122  signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8"))
123  sent_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True)
124 
125  self.nodes[0].generate(1)
126  self.sync_all()
127 
128  txidsmany = self.nodes[1].getaddresstxids("93bVhahvUKmQu8gu9g3QnPPa2cxFK98pMB")
129  assert_equal(len(txidsmany), 4)
130  assert_equal(txidsmany[3], sent_txid)
131 
132  # Check that balances are correct
133  print "Testing balances..."
134  balance0 = self.nodes[1].getaddressbalance("93bVhahvUKmQu8gu9g3QnPPa2cxFK98pMB")
135  assert_equal(balance0["balance"], 45 * 100000000 + 21)
136 
137  # Check that balances are correct after spending
138  print "Testing balances after spending..."
139  privkey2 = "cU4zhap7nPJAWeMFu4j6jLrfPmqakDAzy8zn8Fhb3oEevdm4e5Lc"
140  address2 = "yeMpGzMj3rhtnz48XsfpB8itPHhHtgxLc3"
141  addressHash2 = "C5E4FB9171C22409809A3E8047A29C83886E325D".decode("hex")
142  scriptPubKey2 = CScript([OP_DUP, OP_HASH160, addressHash2, OP_EQUALVERIFY, OP_CHECKSIG])
143  self.nodes[0].importprivkey(privkey2)
144 
145  unspent = self.nodes[0].listunspent()
146  tx = CTransaction()
147  tx.vin = [CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))]
148  amount = unspent[0]["amount"] * 100000000
149  tx.vout = [CTxOut(amount, scriptPubKey2)]
150  tx.rehash()
151  signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8"))
152  spending_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True)
153  self.nodes[0].generate(1)
154  self.sync_all()
155  balance1 = self.nodes[1].getaddressbalance(address2)
156  assert_equal(balance1["balance"], amount)
157 
158  tx = CTransaction()
159  tx.vin = [CTxIn(COutPoint(int(spending_txid, 16), 0))]
160  send_amount = 1 * 100000000 + 12840
161  change_amount = amount - send_amount - 10000
162  tx.vout = [CTxOut(change_amount, scriptPubKey2), CTxOut(send_amount, scriptPubKey)]
163  tx.rehash()
164 
165  signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8"))
166  sent_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True)
167  self.nodes[0].generate(1)
168  self.sync_all()
169 
170  balance2 = self.nodes[1].getaddressbalance(address2)
171  assert_equal(balance2["balance"], change_amount)
172 
173  # Check that deltas are returned correctly
174  deltas = self.nodes[1].getaddressdeltas({"addresses": [address2], "start": 0, "end": 200})
175  balance3 = 0
176  for delta in deltas:
177  balance3 += delta["satoshis"]
178  assert_equal(balance3, change_amount)
179  assert_equal(deltas[0]["address"], address2)
180  assert_equal(deltas[0]["blockindex"], 1)
181 
182  # Check that entire range will be queried
183  deltasAll = self.nodes[1].getaddressdeltas({"addresses": [address2]})
184  assert_equal(len(deltasAll), len(deltas))
185 
186  # Check that deltas can be returned from range of block heights
187  deltas = self.nodes[1].getaddressdeltas({"addresses": [address2], "start": 113, "end": 113})
188  assert_equal(len(deltas), 1)
189 
190  # Check that unspent outputs can be queried
191  print "Testing utxos..."
192  utxos = self.nodes[1].getaddressutxos({"addresses": [address2]})
193  assert_equal(len(utxos), 1)
194  assert_equal(utxos[0]["satoshis"], change_amount)
195 
196  # Check that indexes will be updated with a reorg
197  print "Testing reorg..."
198 
199  best_hash = self.nodes[0].getbestblockhash()
200  self.nodes[0].invalidateblock(best_hash)
201  self.nodes[1].invalidateblock(best_hash)
202  self.nodes[2].invalidateblock(best_hash)
203  self.nodes[3].invalidateblock(best_hash)
204  # Allow some time for the reorg to start
205  time.sleep(2)
206  self.sync_all()
207 
208  balance4 = self.nodes[1].getaddressbalance(address2)
209  assert_equal(balance4, balance1)
210 
211  utxos2 = self.nodes[1].getaddressutxos({"addresses": [address2]})
212  assert_equal(len(utxos2), 1)
213  assert_equal(utxos2[0]["satoshis"], amount)
214 
215  # Check sorting of utxos
216  self.nodes[2].generate(150)
217 
218  txidsort1 = self.nodes[2].sendtoaddress(address2, 50)
219  self.nodes[2].generate(1)
220  txidsort2 = self.nodes[2].sendtoaddress(address2, 50)
221  self.nodes[2].generate(1)
222  self.sync_all()
223 
224  utxos3 = self.nodes[1].getaddressutxos({"addresses": [address2]})
225  assert_equal(len(utxos3), 3)
226  assert_equal(utxos3[0]["height"], 114)
227  assert_equal(utxos3[1]["height"], 264)
228  assert_equal(utxos3[2]["height"], 265)
229 
230  # Check mempool indexing
231  print "Testing mempool indexing..."
232 
233  privKey3 = "cRyrMvvqi1dmpiCmjmmATqjAwo6Wu7QTjKu1ABMYW5aFG4VXW99K"
234  address3 = "yWB15aAdpeKuSaQHFVJpBDPbNSLZJSnDLA"
235  addressHash3 = "6C186B3A308A77C779A9BB71C3B5A7EC28232A13".decode("hex")
236  scriptPubKey3 = CScript([OP_DUP, OP_HASH160, addressHash3, OP_EQUALVERIFY, OP_CHECKSIG])
237  # address4 = "2N8oFVB2vThAKury4vnLquW2zVjsYjjAkYQ"
238  scriptPubKey4 = CScript([OP_HASH160, addressHash3, OP_EQUAL])
239  unspent = self.nodes[2].listunspent()
240 
241  tx = CTransaction()
242  tx.vin = [CTxIn(COutPoint(int(unspent[0]["txid"], 16), unspent[0]["vout"]))]
243  amount = unspent[0]["amount"] * 100000000
244  tx.vout = [CTxOut(amount, scriptPubKey3)]
245  tx.rehash()
246  signed_tx = self.nodes[2].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8"))
247  memtxid1 = self.nodes[2].sendrawtransaction(signed_tx["hex"], True)
248  time.sleep(2)
249 
250  tx2 = CTransaction()
251  tx2.vin = [CTxIn(COutPoint(int(unspent[1]["txid"], 16), unspent[1]["vout"]))]
252  amount = unspent[1]["amount"] * 100000000
253  tx2.vout = [
254  CTxOut(amount / 4, scriptPubKey3),
255  CTxOut(amount / 4, scriptPubKey3),
256  CTxOut(amount / 4, scriptPubKey4),
257  CTxOut(amount / 4, scriptPubKey4)
258  ]
259  tx2.rehash()
260  signed_tx2 = self.nodes[2].signrawtransaction(binascii.hexlify(tx2.serialize()).decode("utf-8"))
261  memtxid2 = self.nodes[2].sendrawtransaction(signed_tx2["hex"], True)
262  time.sleep(2)
263 
264  mempool = self.nodes[2].getaddressmempool({"addresses": [address3]})
265  assert_equal(len(mempool), 3)
266  assert_equal(mempool[0]["txid"], memtxid1)
267  assert_equal(mempool[0]["address"], address3)
268  assert_equal(mempool[0]["index"], 0)
269  assert_equal(mempool[1]["txid"], memtxid2)
270  assert_equal(mempool[1]["index"], 0)
271  assert_equal(mempool[2]["txid"], memtxid2)
272  assert_equal(mempool[2]["index"], 1)
273 
274  self.nodes[2].generate(1);
275  self.sync_all();
276  mempool2 = self.nodes[2].getaddressmempool({"addresses": [address3]})
277  assert_equal(len(mempool2), 0)
278 
279  tx = CTransaction()
280  tx.vin = [
281  CTxIn(COutPoint(int(memtxid2, 16), 0)),
282  CTxIn(COutPoint(int(memtxid2, 16), 1))
283  ]
284  tx.vout = [CTxOut(amount / 2 - 10000, scriptPubKey2)]
285  tx.rehash()
286  self.nodes[2].importprivkey(privKey3)
287  signed_tx3 = self.nodes[2].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8"))
288  memtxid3 = self.nodes[2].sendrawtransaction(signed_tx3["hex"], True)
289  time.sleep(2)
290 
291  mempool3 = self.nodes[2].getaddressmempool({"addresses": [address3]})
292  assert_equal(len(mempool3), 2)
293  assert_equal(mempool3[0]["prevtxid"], memtxid2)
294  assert_equal(mempool3[0]["prevout"], 0)
295  assert_equal(mempool3[1]["prevtxid"], memtxid2)
296  assert_equal(mempool3[1]["prevout"], 1)
297 
298  # sending and receiving to the same address
299  privkey1 = "cMvZn1pVWntTEcsK36ZteGQXRAcZ8CoTbMXF1QasxBLdnTwyVQCc"
300  address1 = "yM9Eed1bxjy7tYxD3yZDHxjcVT48WdRoB1"
301  address1hash = "0909C84A817651502E020AAD0FBCAE5F656E7D8A".decode("hex")
302  address1script = CScript([OP_DUP, OP_HASH160, address1hash, OP_EQUALVERIFY, OP_CHECKSIG])
303 
304  self.nodes[0].sendtoaddress(address1, 10)
305  self.nodes[0].generate(1)
306  self.sync_all()
307 
308  utxos = self.nodes[1].getaddressutxos({"addresses": [address1]})
309  assert_equal(len(utxos), 1)
310 
311  tx = CTransaction()
312  tx.vin = [
313  CTxIn(COutPoint(int(utxos[0]["txid"], 16), utxos[0]["outputIndex"]))
314  ]
315  amount = utxos[0]["satoshis"] - 10000
316  tx.vout = [CTxOut(amount, address1script)]
317  tx.rehash()
318  self.nodes[0].importprivkey(privkey1)
319  signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8"))
320  mem_txid = self.nodes[0].sendrawtransaction(signed_tx["hex"], True)
321 
322  self.sync_all()
323  mempool_deltas = self.nodes[2].getaddressmempool({"addresses": [address1]})
324  assert_equal(len(mempool_deltas), 2)
325 
326  print "Passed\n"
327 
328 
329 if __name__ == '__main__':
UniValue importprivkey(const UniValue &params, bool fHelp)
Definition: rpcdump.cpp:76
UniValue getaddressbalance(const UniValue &params, bool fHelp)
Definition: misc.cpp:809
UniValue getaddresstxids(const UniValue &params, bool fHelp)
Definition: misc.cpp:865
UniValue getaddressdeltas(const UniValue &params, bool fHelp)
Definition: misc.cpp:721
UniValue getbalance(const UniValue &params, bool fHelp)
Definition: rpcwallet.cpp:792
UniValue listunspent(const UniValue &params, bool fHelp)
Definition: rpcwallet.cpp:2533
UniValue sendtoaddress(const UniValue &params, bool fHelp)
Definition: rpcwallet.cpp:409
UniValue getaddressutxos(const UniValue &params, bool fHelp)
Definition: misc.cpp:654
def connect_nodes(from_connection, node_num)
Definition: util.py:343
UniValue getblockcount(const UniValue &params, bool fHelp)
Definition: blockchain.cpp:131
def initialize_chain_clean(test_dir, num_nodes)
Definition: util.py:252
UniValue signrawtransaction(const UniValue &params, bool fHelp)
def start_node(i, dirname, extra_args=None, rpchost=None, timewait=None, binary=None)
Definition: util.py:281
UniValue generate(const UniValue &params, bool fHelp)
Definition: mining.cpp:122
UniValue sendrawtransaction(const UniValue &params, bool fHelp)
UniValue getaddressmempool(const UniValue &params, bool fHelp)
Definition: misc.cpp:583
UniValue getbestblockhash(const UniValue &params, bool fHelp)
Definition: blockchain.cpp:148
def assert_equal(thing1, thing2)
Definition: util.py:461