def run_command(cmd, password=None, args=[]):
+ import xmlrpclib, socket
cmd_runner = Commands(wallet, network)
- func = getattr(cmd_runner, cmd)
+ func = getattr(cmd_runner, cmd.name)
cmd_runner.password = password
+
+ if cmd.requires_network and not options.offline:
+ cmd_runner.network = xmlrpclib.ServerProxy('http://localhost:8000')
+ if wallet:
+ wallet.start_threads(cmd_runner.network)
+ wallet.update()
+ else:
+ cmd_runner.network = None
+
try:
result = func(*args[1:])
+ except socket.error:
+ print "Network server not found."
+ sys.exit(1)
except Exception:
traceback.print_exc(file=sys.stdout)
sys.exit(1)
+
+ if cmd.requires_network and not options.offline:
+ if wallet:
+ wallet.stop_threads()
+
+
if type(result) == str:
util.print_msg(result)
elif result is not None:
print_msg("Type 'electrum create' to create a new wallet, or provide a path to a wallet with the -w option")
sys.exit(0)
+
+
+
+
+
if cmd.name in ['create', 'restore']:
if storage.file_exists:
sys.exit("Error: Remove the existing wallet first!")
print_msg("Warning: Final argument was reconstructed from several arguments:", repr(message))
args = args[0:cmd.min_args] + [message]
- # open session
- if cmd.requires_network and not options.offline:
- network = Network(config)
- if not network.start(wait=True):
- print_msg("Not connected, aborting.")
- sys.exit(1)
- print_error("Connected to " + network.interface.connection_msg)
- if wallet:
- wallet.start_threads(network)
- wallet.update()
- else:
- network = None
+ if cmd.name == 'start_network':
+ pid = os.fork()
+ if (pid == 0): # The first child.
+ os.chdir("/")
+ os.setsid()
+ os.umask(0)
+ pid2 = os.fork()
+ if (pid2 == 0): # Second child
+ from SimpleXMLRPCServer import SimpleXMLRPCServer
+ # start the daemon
+ network = Network(config)
+ if not network.start(wait=True):
+ print_msg("Not connected, aborting.")
+ sys.exit(1)
+ print_msg("Connected to " + network.interface.connection_msg)
+ server = SimpleXMLRPCServer(('localhost',8000), allow_none=True, logRequests=False)
+ server.register_function(network.synchronous_get, 'synchronous_get')
+ server.register_function(network.get_servers, 'get_servers')
+ server.register_function(network.main_server, 'main_server')
+ server.register_function(network.send, 'send')
+ server.register_function(network.subscribe, 'subscribe')
+ server.register_function(network.is_connected, 'is_connected')
+ server.register_function(network.is_up_to_date, 'is_up_to_date')
+ server.register_function(lambda: setattr(server,'running', False), 'stop')
+ server.running = True
+ while server.running:
+ server.handle_request()
+ print_msg("Server stopped")
+ sys.exit(0)
+ else:
+ sys.exit(0)
+ else:
+ sys.exit(0)
+
# run the command
if cmd.name == 'deseed':
wallet.update_password(password, new_password)
else:
- run_command(cmd.name, password, args)
+ run_command(cmd, password, args)
- if network:
- if wallet:
- wallet.stop_threads()
- network.stop()
- time.sleep(0.1)
- sys.exit(0)
+
+ time.sleep(0.1)
+ sys.exit(0)
register_command('freeze', 1, 1, False, True, True, 'Freeze the funds at one of your wallet\'s addresses', 'freeze <address>')
register_command('getbalance', 0, 1, True, True, False, 'Return the balance of your wallet, or of one account in your wallet', 'getbalance [<account>]')
register_command('getservers', 0, 0, True, False, False, 'Return the list of available servers')
-register_command('getversion', 0, 0, False, False, False, 'Return the version of your client', 'getversion')
-register_command('getaddressbalance', 1, 1, True, True, False, 'Return the balance of an address', 'getaddressbalance <address>')
-register_command('getaddresshistory', 1, 1, True, True, False, 'Return the transaction history of a wallet address', 'getaddresshistory <address>')
+register_command('getversion', 0, 0, False, False, False, 'Return the version of your client', 'getversion')
+register_command('getaddressbalance', 1, 1, True, False, False, 'Return the balance of an address', 'getaddressbalance <address>')
+register_command('getaddresshistory', 1, 1, True, False, False, 'Return the transaction history of a wallet address', 'getaddresshistory <address>')
register_command('getconfig', 1, 1, False, False, False, 'Return a configuration variable', 'getconfig <name>')
register_command('getpubkeys', 1, 1, False, True, False, 'Return the public keys for a wallet address', 'getpubkeys <bitcoin address>')
register_command('getrawtransaction', 1, 1, True, False, False, 'Retrieve a transaction', 'getrawtransaction <txhash>')
register_command('history', 0, 0, True, True, False, 'Returns the transaction history of your wallet')
register_command('importprivkey', 1, 1, False, True, True, 'Import a private key', 'importprivkey <privatekey>')
register_command('listaddresses', 2, 2, False, True, False, 'Returns your list of addresses.', '', listaddr_options)
-register_command('listunspent', 0, 0, True, True, False, 'Returns the list of unspent inputs in your wallet.')
+register_command('listunspent', 0, 0, True, False, False, 'Returns the list of unspent inputs in your wallet.')
+register_command('getaddressunspent', 1, 1, True, False, False, 'Returns the list of unspent inputs in your wallet.')
register_command('mktx', 5, 5, False, True, True, 'Create a signed transaction', 'mktx <recipient> <amount> [label]', payto_options)
register_command('mksendmanytx', 4, 4, False, True, True, 'Create a signed transaction', mksendmany_syntax, payto_options)
register_command('payto', 5, 5, True, True, True, 'Create and broadcast a transaction.', payto_syntax, payto_options)
register_command('validateaddress', 1, 1, False, False, False, 'Check that the address is valid', 'validateaddress <address>')
register_command('verifymessage', 3,-1, False, False, False, 'Verifies a signature', verifymessage_syntax)
+register_command('start_network', 0, 0, False, False, False, 'start the daemon')
+register_command('stop_network', 0, 0, True, False, False, 'stop the daemon')
self._callback = callback
self.password = None
+
def _run(self, method, args, password_getter):
cmd = known_commands[method]
if cmd.requires_password and self.wallet.use_encryption:
apply(self._callback, ())
return result
+
def getaddresshistory(self, addr):
- assert self.wallet.is_mine(addr)
- h = self.wallet.get_history(addr)
- if h is None: h = self.network.synchronous_get([ ('blockchain.address.get_history',[addr]) ])[0]
- return h
+ return self.network.synchronous_get([ ('blockchain.address.get_history',[addr]) ])[0]
+
+
+ def stop_network(self):
+ return self.network.stop()
+
def listunspent(self):
import copy
for i in l: i["value"] = str(Decimal(i["value"])/100000000)
return l
+
+ def getaddressunspent(self, addr):
+ return self.network.synchronous_get([ ('blockchain.address.getunspent',[addr]) ])[0]
+
+
def createrawtransaction(self, inputs, outputs):
# convert to own format
for i in inputs:
return out
def getaddressbalance(self, addr):
- c, u = self.wallet.get_addr_balance(addr)
- out = { "confirmed": str(Decimal(c)/100000000) }
- if u: out["unconfirmed"] = str(Decimal(u)/100000000)
- return out
+ # c, u = self.wallet.get_addr_balance(addr)
+ # out = { "confirmed": str(Decimal(c)/100000000) }
+ # if u: out["unconfirmed"] = str(Decimal(u)/100000000)
+ # return out
+ return self.network.synchronous_get([ ('blockchain.address.get_balance',[addr]) ])[0]
def getservers(self):
return self.network.get_servers()
if cmd.options: print_msg("options:\n" + cmd.options)
return None
+
def getrawtransaction(self, tx_hash):
+ import transaction
if self.wallet:
tx = self.wallet.transactions.get(tx_hash)
if tx:
return tx
- return self.network.retrieve_transaction(tx_hash)
+
+ r = self.network.synchronous_get([ ('blockchain.transaction.get',[tx_hash]) ])[0]
+ if r:
+ return transaction.Transaction(r)
+ else:
+ return "unknown transaction"
+
def start_threads(self, network):
from verifier import TxVerifier
self.network = network
- if self.network:
+ if self.network is not None:
self.verifier = TxVerifier(self.network, self.storage)
self.verifier.start()
self.set_verifier(self.verifier)
if not self.network.is_connected():
self.network.wait_until_connected()
- self.run_interface(self.network.interface)
+ self.run_interface()
- def run_interface(self, interface):
+ def run_interface(self):
- print_error("synchronizer: connected to", interface.server)
+ print_error("synchronizer: connected to", self.network.main_server())
requested_tx = []
missing_tx = []
# request missing transactions
for tx_hash, tx_height in missing_tx:
if (tx_hash, tx_height) not in requested_tx:
- interface.send([ ('blockchain.transaction.get',[tx_hash, tx_height]) ], lambda i,r: self.queue.put(r))
+ self.network.send([ ('blockchain.transaction.get',[tx_hash, tx_height]) ], lambda i,r: self.queue.put(r))
requested_tx.append( (tx_hash, tx_height) )
missing_tx = []
# detect if situation has changed
- if interface.is_up_to_date() and self.queue.empty():
+ if self.network.is_up_to_date() and self.queue.empty():
if not self.wallet.is_up_to_date():
self.wallet.set_up_to_date(True)
self.was_updated = True
self.was_updated = True
if self.was_updated:
- self.wallet.network.trigger_callback('updated')
+ self.network.trigger_callback('updated')
self.was_updated = False
# 2. get a response
except Queue.Empty:
continue
- if interface != self.network.interface:
- break
+ # see if it changed
+ #if interface != self.network.interface:
+ # break
if not r:
continue
addr = params[0]
if self.wallet.get_status(self.wallet.get_history(addr)) != result:
if requested_histories.get(addr) is None:
- interface.send([('blockchain.address.get_history', [addr])], lambda i,r:self.queue.put(r))
+ self.network.send([('blockchain.address.get_history', [addr])], lambda i,r:self.queue.put(r))
requested_histories[addr] = result
elif method == 'blockchain.address.get_history':
print_error("Error: Unknown message:" + method + ", " + repr(params) + ", " + repr(result) )
if self.was_updated and not requested_tx:
- self.wallet.network.trigger_callback('updated')
- self.wallet.network.trigger_callback("new_transaction") # Updated gets called too many times from other places as well; if we use that signal we get the notification three times
-
+ self.network.trigger_callback('updated')
+ # Updated gets called too many times from other places as well; if we use that signal we get the notification three times
+ self.network.trigger_callback("new_transaction")
self.was_updated = False