1
0

move network interface in separate class; use jsonrpc with http

This commit is contained in:
thomasv
2012-01-11 16:50:24 +01:00
parent c6fa553f2f
commit f909fb39aa
2 changed files with 111 additions and 85 deletions

View File

@@ -216,6 +216,88 @@ def raw_tx( inputs, outputs, for_sig = None ):
from version import ELECTRUM_VERSION, SEED_VERSION
class Interface:
def __init__(self):
self.servers = ['ecdsa.org','electrum.novit.ro'] # list of default servers
self.host = random.choice( self.servers ) # random choice when the wallet is created
self.rtime = 0
self.blocks = 0
self.message = ''
self.set_port(50000)
def set_port(self, port_number):
self.port = port_number
if self.use_http():
import jsonrpclib
self.http_json_server = jsonrpclib.Server('http://%s:%d'%(self.host,self.port))
def use_http(self):
return self.port in [80,81,8080,8081]
def request(self, request ):
import time
t1 = time.time()
request += "#"
s = socket.socket( socket.AF_INET, socket.SOCK_STREAM)
s.connect(( self.host, self.port))
s.send( request )
out = ''
while 1:
msg = s.recv(1024)
if msg: out += msg
else: break
s.close()
self.rtime = time.time() - t1
return out
def send_tx(self, data):
if self.use_http():
out = self.http_json_server.blockchain.transaction.broadcast(data)
else:
out = self.request( repr ( ('tx', data )))
return out
def retrieve_history(self, address):
if self.use_http():
out = self.http_json_server.blockchain.address.get_history(params)
else:
out = ast.literal_eval( self.request( repr ( ('h', address ))) )
return out
def poll(self):
if self.use_http():
out = ast.literal_eval( self.http_json_server.session.poll( self.session_id ) )
else:
out = ast.literal_eval( self.request( repr ( ('poll', self.session_id ))))
blocks, changed_addr = out
if blocks == -1: raise BaseException("session not found")
self.blocks = int(blocks)
return changed_addr
def new_session(self, addresses, version):
if self.use_http():
out = ast.literal_eval( self.http_json_server.session.new(addresses, version) )
else:
out = ast.literal_eval( self.request( repr ( ('new_session', repr( ( version, addresses)) ))))
self.session_id, self.message = out
def update_session(self):
if self.use_http():
out = self.http_json_server.session.update(self.session_id, self.all_addresses())
else:
out = self.request( repr ( ('update_session', repr((self.session_id, self.all_addresses())))))
return out
def get_servers(self):
if self.use_http():
out = self.http_json_server.peers()
else:
out = ast.literal_eval( self.request( repr ( ('peers', '' ))))
self.servers = map( lambda x:x[1], out )
class Wallet:
def __init__(self):
@@ -224,10 +306,7 @@ class Wallet:
self.seed_version = SEED_VERSION
self.gap_limit = 5 # configuration
self.port = 50000
self.fee = 100000
self.servers = ['ecdsa.org','electrum.novit.ro'] # list of default servers
self.host = random.choice( self.servers ) # random choice when the wallet is created
self.master_public_key = ''
# saved fields
@@ -239,15 +318,14 @@ class Wallet:
self.history = {}
self.labels = {} # labels for addresses and transactions
self.addressbook = [] # outgoing addresses, for payments
self.blocks = 0
# not saved
self.message = ''
self.tx_history = {}
self.rtime = 0
self.imported_keys = {}
self.interface = Interface()
def set_path(self, wallet_path):
@@ -359,7 +437,7 @@ class Wallet:
# updates
print address
self.history[address] = h = self.retrieve_history(address)
self.history[address] = h = self.interface.retrieve_history(address)
self.status[address] = h[-1]['blk_hash'] if h else None
return address
@@ -410,8 +488,8 @@ class Wallet:
'use_encryption':self.use_encryption,
'master_public_key': self.master_public_key.encode('hex'),
'fee':self.fee,
'host':self.host,
'port':self.port,
'host':self.interface.host,
'port':self.interface.port,
'blocks':self.blocks,
'seed':self.seed,
'addresses':self.addresses,
@@ -440,8 +518,8 @@ class Wallet:
self.master_public_key = d.get('master_public_key').decode('hex')
self.use_encryption = d.get('use_encryption')
self.fee = int( d.get('fee') )
self.host = d.get('host')
self.port = d.get('port')
self.interface.host = d.get('host')
self.interface.set_port( d.get('port') )
self.blocks = d.get('blocks')
self.seed = d.get('seed')
self.addresses = d.get('addresses')
@@ -493,66 +571,13 @@ class Wallet:
unconf += u
return conf, unconf
def use_http(self):
return self.port in [80,8080,443]
def request(self, request ):
import time
t1 = time.time()
if self.use_http():
import httplib, urllib
params = urllib.urlencode({'q':request})
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
conn = httplib.HTTPSConnection(self.host) if self.port == 443 else httplib.HTTPConnection(self.host)
conn.request("POST", "/electrum.php", params, headers)
response = conn.getresponse()
if response.status == 200:
out = response.read()
else: out = ''
conn.close()
else:
request += "#"
s = socket.socket( socket.AF_INET, socket.SOCK_STREAM)
s.connect(( self.host, self.port))
s.send( request )
out = ''
while 1:
msg = s.recv(1024)
if msg: out += msg
else: break
s.close()
self.rtime = time.time() - t1
return out
def send_tx(self, data):
return self.request( repr ( ('tx', data )))
def retrieve_history(self, address):
return ast.literal_eval( self.request( repr ( ('h', address ))) )
def poll(self):
return ast.literal_eval( self.request( repr ( ('poll', self.session_id ))))
def new_session(self):
self.session_id, self.message = ast.literal_eval( self.request( repr ( ('new_session', repr( (self.electrum_version, self.all_addresses())) ))))
def update_session(self):
return self.request( repr ( ('update_session', repr((self.session_id, self.all_addresses())))))
def get_servers(self):
self.servers = map( lambda x:x[1], ast.literal_eval( self.request( repr ( ('peers', '' )))) )
def update(self):
is_new = False
blocks, changed_addresses = self.poll()
if blocks == -1: raise BaseException("session not found")
self.blocks = int(blocks)
changed_addresses = self.interface.poll()
for addr, blk_hash in changed_addresses.items():
if self.status.get(addr) != blk_hash:
print "updating history for", addr
self.history[addr] = self.retrieve_history(addr)
self.history[addr] = self.interface.retrieve_history(addr)
self.status[addr] = blk_hash
is_new = True
@@ -702,7 +727,7 @@ class Wallet:
def sendtx(self, tx):
tx_hash = Hash(tx.decode('hex') )[::-1].encode('hex')
out = self.send_tx(tx)
out = self.interface.send_tx(tx)
if out != tx_hash:
return False, "error: " + out
return True, out
@@ -806,7 +831,7 @@ if __name__ == '__main__':
# open session
if cmd not in ['password', 'mktx', 'history', 'label', 'contacts', 'help', 'validateaddress']:
wallet.new_session()
wallet.interface.new_session(wallet.all_addresses(), wallet.electrum_version)
wallet.update()
wallet.save()