electrum-bitcoinprivate/lib/network.py

153 lines
4.3 KiB
Python
Raw Normal View History

import threading, time, Queue, os, sys, shutil, random
from util import user_dir, appdata_dir, print_error, print_msg
from bitcoin import *
2013-09-08 08:23:01 -07:00
import interface
from blockchain import Blockchain
class Network(threading.Thread):
def __init__(self, config):
threading.Thread.__init__(self)
self.daemon = True
self.config = config
self.lock = threading.Lock()
self.blockchain = Blockchain(config, self)
2013-09-08 08:23:01 -07:00
self.interfaces = {}
self.queue = Queue.Queue()
self.default_server = self.config.get('server')
self.servers_list = interface.filter_protocol(interface.DEFAULT_SERVERS,'s')
2013-09-09 04:33:25 -07:00
self.callbacks = {}
2013-09-08 08:23:01 -07:00
2013-09-09 04:33:25 -07:00
def register_callback(self, event, callback):
with self.lock:
if not self.callbacks.get(event):
self.callbacks[event] = []
self.callbacks[event].append(callback)
def trigger_callback(self, event):
with self.lock:
callbacks = self.callbacks.get(event,[])[:]
if callbacks:
[callback() for callback in callbacks]
2013-09-08 08:23:01 -07:00
def random_server(self):
if len(self.servers_list) <= len(self.interfaces.keys()):
return
while True:
server = random.choice( self.servers_list )
if server not in self.interfaces.keys(): break
2013-09-08 08:23:01 -07:00
return server
2013-09-08 08:23:01 -07:00
def start_interface(self, server):
if server in self.interfaces.keys():
return
i = interface.Interface({'server':server})
i.network = self # fixme
self.interfaces[server] = i
i.start(self.queue)
def start_random_interface(self):
server = self.random_server()
if server:
self.start_interface(server)
def start_interfaces(self):
2013-09-08 08:23:01 -07:00
if self.default_server:
self.start_interface(self.default_server)
self.interface = self.interfaces[self.default_server]
2013-09-08 08:23:01 -07:00
for i in range(8):
self.start_random_interface()
if not self.interface:
self.interface = self.interfaces.values()[0]
2013-09-08 08:23:01 -07:00
def start(self, wait=False):
2013-09-09 04:33:25 -07:00
self.start_interfaces()
threading.Thread.start(self)
2013-09-09 04:33:25 -07:00
if wait:
self.interface.connect_event.wait()
return self.interface.is_connected
2013-09-08 08:23:01 -07:00
2013-09-10 10:59:58 -07:00
def set_server(self, server, proxy):
subscriptions = self.interface.subscriptions
self.default_server = server
self.start_interface(server)
self.interface = self.interfaces[server]
self.resend_subscriptions(subscriptions)
self.trigger_callback('disconnecting') # for actively disconnecting
2013-09-08 08:23:01 -07:00
def run(self):
self.blockchain.start()
with self.lock:
self.running = True
while self.is_running():
i = self.queue.get()
if i.is_connected:
i.register_channel('verifier', self.blockchain.queue)
i.register_channel('get_header')
i.send([ ('blockchain.headers.subscribe',[])], 'verifier')
2013-09-08 08:23:01 -07:00
if i == self.interface:
i.send([('server.banner',[])])
i.send([('server.peers.subscribe',[])])
else:
self.servers_list.remove(i.server)
2013-09-08 08:23:01 -07:00
self.interfaces.pop(i.server)
self.start_random_interface()
2013-09-08 08:23:01 -07:00
if i == self.interface:
if self.config.get('auto_cycle'):
self.interface = random.choice(self.interfaces.values())
self.config.set_key('server', self.interface.server, False)
2013-09-08 08:23:01 -07:00
else:
self.trigger_callback('disconnected')
2013-09-08 08:23:01 -07:00
def on_peers(self, result):
# populate servers list here
2013-09-08 08:23:01 -07:00
pass
def on_banner(self, result):
pass
def stop(self):
with self.lock: self.running = False
def is_running(self):
with self.lock: return self.running
2013-09-10 10:59:58 -07:00
def resend_subscriptions(self, subscriptions):
for channel, messages in subscriptions.items():
2013-09-08 08:23:01 -07:00
if messages:
2013-09-10 10:59:58 -07:00
self.interface.send(messages, channel)
2013-09-08 08:23:01 -07:00
if __name__ == "__main__":
import simple_config
config = simple_config.SimpleConfig({'verbose':True})
network = Network(config)
network.start()
while 1:
time.sleep(1)