diff --git a/lib/blockchaininterface.py b/lib/blockchaininterface.py index 63b96028..076c0520 100644 --- a/lib/blockchaininterface.py +++ b/lib/blockchaininterface.py @@ -2,7 +2,7 @@ import subprocess import unittest import json, threading, abc, pprint, time, random, sys, os, re -import BaseHTTPServer, SimpleHTTPServer, urllib +import BaseHTTPServer, urllib from decimal import Decimal import bitcoin as btc @@ -270,11 +270,11 @@ def query_utxo_set(self, txout): return result -class NotifyRequestHeader(SimpleHTTPServer.SimpleHTTPRequestHandler): +class NotifyRequestHeader(BaseHTTPServer.BaseHTTPRequestHandler): def __init__(self, request, client_address, base_server): self.btcinterface = base_server.btcinterface self.base_server = base_server - SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, request, client_address, base_server) + BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, request, client_address, base_server) def do_HEAD(self): pages = ('/walletnotify?', '/alertnotify?') @@ -336,8 +336,12 @@ def __init__(self, btcinterface): self.btcinterface = btcinterface def run(self): + if 'notify_port' in common.config.options("BLOCKCHAIN"): + notify_port = int(common.config.get("BLOCKCHAIN","notify_port")) + else: + notify_port = 62602 #default for inc in range(10): - hostport = ('localhost', 62602 + inc) + hostport = ('localhost', notify_port + inc) try: httpd = BaseHTTPServer.HTTPServer(hostport, NotifyRequestHeader) except Exception: @@ -378,8 +382,9 @@ def add_watchonly_addresses(self, addr_list, wallet_name): common.debug('importing ' + str(len(addr_list)) + ' addresses into account ' + wallet_name) for addr in addr_list: self.rpc(['importaddress', addr, wallet_name, 'false']) - print 'now restart bitcoind with -rescan' - sys.exit(0) + if common.config.get("BLOCKCHAIN", "blockchain_source") != 'regtest': + print 'now restart bitcoind with -rescan' + sys.exit(0) def sync_addresses(self, wallet): if isinstance(wallet, common.BitcoinCoreWallet): @@ -397,11 +402,15 @@ def sync_addresses(self, wallet): self.add_watchonly_addresses(wallet_addr_list, wallet_name) return - #TODO get all the transactions above 1000, by looping until len(result) < 1000 ret = self.rpc(['listtransactions', wallet_name, '1000', '0', 'true']) - txs = json.loads(ret) - if len(txs) == 1000: - raise Exception('time to stop putting off this bug and actually fix it, see the TODO') + buf = json.loads(ret) + txs = buf + # If the buffer's full, check for more, until it ain't + while len(buf) == 1000: + ret = self.rpc(['listtransactions', wallet_name, '1000', + str(len(txs)), 'true']) + buf = json.loads(ret) + txs += buf used_addr_list = [tx['address'] for tx in txs if tx['category'] == 'receive'] too_few_addr_mix_change = [] for mix_depth in range(wallet.max_mix_depth): @@ -544,7 +553,17 @@ def grab_coins(self, receiving_addr, amt=50): raise Exception("Failed to broadcast transaction") #confirm self.tick_forward_chain(1) - return txid + return txid + + def get_received_by_addr(self, addresses, query_params): + #NB This will NOT return coinbase coins (but wont matter in our use case). + #allow importaddress to fail in case the address is already in the wallet + res = [] + for address in addresses: + self.rpc(['importaddress', address,'watchonly']) + res.append({'address':address,'balance':\ + int(Decimal(1e8) * Decimal(self.rpc(['getreceivedbyaddress', address])))}) + return {'data':res} def main(): #TODO some useful quick testing here, so people know if they've set it up right diff --git a/lib/regtesttest.py b/regtest.py similarity index 88% rename from lib/regtesttest.py rename to regtest.py index 1de906d8..30bb5664 100644 --- a/lib/regtesttest.py +++ b/regtest.py @@ -1,5 +1,7 @@ import sys import os, time +data_dir = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.join(data_dir, 'lib')) import subprocess import unittest import common @@ -35,7 +37,7 @@ def local_command(command, bg=False, redirect=''): print "OS not recognised, quitting." elif redirect: command.extend(['>', redirect]) - + if bg: return subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) @@ -68,7 +70,7 @@ def setUp(self): def run_simple_send(self, n): #start yield generator with wallet1 yigen_proc = local_command(['python','yield-generator.py', - str(self.wallets[1]['seed'])], bg=True) + str(self.wallets[1]['seed'])],redirect=self.wallets[1]['seed'],bg=True) #A significant delay is needed to wait for the yield generator to sync its wallet time.sleep(30) @@ -78,7 +80,7 @@ def run_simple_send(self, n): dest_address = btc.privkey_to_address(os.urandom(32), common.get_addr_vbyte()) try: for i in range(n): - sp_proc = local_command(['python','sendpayment.py','-N','1', self.wallets[2]['seed'],\ + sp_proc = local_command(['python','sendpayment.py','--yes','-N','1', self.wallets[2]['seed'],\ str(amt), dest_address]) except subprocess.CalledProcessError, e: if yigen_proc: @@ -95,8 +97,9 @@ def run_simple_send(self, n): # with open(cf, 'rb') as f: # if 'CRASHING' in f.read(): return False - received = common.bc_interface.get_balance_at_addr([dest_address], None)['data'][0]['balance'] - if received != amt: + received = common.bc_interface.get_received_by_addr([dest_address], None)['data'][0]['balance'] + if received != amt*n: + common.debug('received was: '+str(received)+ ' but amount was: '+str(amt)) return False return True @@ -143,7 +146,7 @@ def run_nparty_join(self): amt = 100000000 #in satoshis dest_address = btc.privkey_to_address(os.urandom(32), common.get_addr_vbyte()) try: - sp_proc = local_command(['python','sendpayment.py','-N', str(self.n),\ + sp_proc = local_command(['python','sendpayment.py','--yes','-N', str(self.n),\ self.wallets[self.n]['seed'], str(amt), dest_address]) except subprocess.CalledProcessError, e: for ygp in yigen_procs: @@ -163,7 +166,7 @@ def run_nparty_join(self): #with open(cf, 'rb') as f: # if 'CRASHING' in f.read(): return False - received = common.bc_interface.get_balance_at_addr([dest_address], None)['data'][0]['balance'] + received = common.bc_interface.get_received_by_addr([dest_address], None)['data'][0]['balance'] if received != amt: return False return True diff --git a/sendpayment.py b/sendpayment.py index 1151f2e9..fb4e86e5 100644 --- a/sendpayment.py +++ b/sendpayment.py @@ -18,7 +18,7 @@ def check_high_fee(total_fee_pc): print '\n'.join(['='* 60]*3) print 'WARNING ' * 6 print '\n'.join(['='* 60]*1) - print 'OFFERED FEE IS INSANELY LARGE.'*2 + print 'OFFERED COINJOIN FEE IS UNUSUALLY HIGH. DOUBLE/TRIPLE CHECK.' print '\n'.join(['='* 60]*1) print 'WARNING ' * 6 print '\n'.join(['='* 60]*3) diff --git a/tumbler.py b/tumbler.py index 9c8b6f37..d3ac96c5 100644 --- a/tumbler.py +++ b/tumbler.py @@ -226,7 +226,7 @@ def main(): parser.add_option('-f', '--txfee', type='int', dest='txfee', default=10000, help='miner fee contribution, in satoshis, default=10000') parser.add_option('-x', '--maxcjfee', type='float', dest='maxcjfee', - default=0.03, help='maximum coinjoin fee the tumbler is willing to pay to a single market maker. default=0.01 (1%)') + default=0.01, help='maximum coinjoin fee the tumbler is willing to pay to a single market maker. default=0.01 (1%)') parser.add_option('-a', '--addrask', type='int', dest='addrask', default=2, help='How many more addresses to ask for in the terminal. Should ' 'be similar to --txcountparams. default=2')