From 036b0bc5d32a841a56c304a6da79668944d714a4 Mon Sep 17 00:00:00 2001 From: genjix Date: Fri, 6 Apr 2012 18:51:16 +0100 Subject: [PATCH] Import backend using backend name. --- modules/abe/__init__.py | 2 +- modules/libbitcoin/__init__.py | 182 +++++++++++++++++++++++++++++++++ modules/libbitcoin/composed.py | 194 ++++++++++++++++++++++++++++++++++++ modules/python_bitcoin/__init__.py | 182 --------------------------------- modules/python_bitcoin/composed.py | 194 ------------------------------------ server.py | 10 +- 6 files changed, 382 insertions(+), 382 deletions(-) create mode 100644 modules/libbitcoin/__init__.py create mode 100644 modules/libbitcoin/composed.py delete mode 100644 modules/python_bitcoin/__init__.py delete mode 100644 modules/python_bitcoin/composed.py diff --git a/modules/abe/__init__.py b/modules/abe/__init__.py index b327114..d63847d 100644 --- a/modules/abe/__init__.py +++ b/modules/abe/__init__.py @@ -371,7 +371,7 @@ class AbeStore(Datastore_class): from processor import Processor -class AbeProcessor(Processor): +class BlockchainProcessor(Processor): def __init__(self, config): Processor.__init__(self) diff --git a/modules/libbitcoin/__init__.py b/modules/libbitcoin/__init__.py new file mode 100644 index 0000000..97440ce --- /dev/null +++ b/modules/libbitcoin/__init__.py @@ -0,0 +1,182 @@ +import bitcoin +from processor import Processor +import threading +import time + +import composed + +class Backend: + + def __init__(self): + # Create 3 thread-pools each with 1 thread + self.network_service = bitcoin.async_service(1) + self.disk_service = bitcoin.async_service(1) + self.mempool_service = bitcoin.async_service(1) + + self.hosts = bitcoin.hosts(self.network_service) + self.handshake = bitcoin.handshake(self.network_service) + self.network = bitcoin.network(self.network_service) + self.protocol = bitcoin.protocol(self.network_service, self.hosts, + self.handshake, self.network) + + db_prefix = "/home/genjix/libbitcoin/database" + self.blockchain = bitcoin.bdb_blockchain(self.disk_service, db_prefix) + self.poller = bitcoin.poller(self.blockchain) + self.transaction_pool = \ + bitcoin.transaction_pool(self.mempool_service, self.blockchain) + + self.protocol.subscribe_channel(self.monitor_tx) + self.session = \ + bitcoin.session(self.hosts, self.handshake, self.network, + self.protocol, self.blockchain, self.poller, + self.transaction_pool) + self.session.start(self.handle_start) + + def handle_start(self, ec): + if ec: + print "Error starting backend:", ec + + def stop(self): + self.session.stop(self.handle_stop) + + def handle_stop(self, ec): + if ec: + print "Error stopping backend:", ec + print "Stopped backend" + + def monitor_tx(self, node): + # We will be notified here when connected to new bitcoin nodes + # Here we subscribe to new transactions from them which we + # add to the transaction_pool. That way we can track which + # transactions we are interested in. + node.subscribe_transaction( + bitcoin.bind(self.recv_tx, bitcoin._1, bitcoin._2, node)) + # Re-subscribe to next new node + self.protocol.subscribe_channel(self.monitor_tx) + + def recv_tx(self, ec, tx, node): + if ec: + print "Error with new transaction:", ec + return + tx_hash = bitcoin.hash_transaction(tx) + # If we want to ignore this transaction, we can set + # the 2 handlers to be null handlers that do nothing. + self.transaction_pool.store(tx, + bitcoin.bind(self.tx_confirmed, bitcoin._1, tx_hash), + bitcoin.bind(self.handle_mempool_store, bitcoin._1, tx_hash)) + # Re-subscribe to new transactions from node + node.subscribe_transaction( + bitcoin.bind(self.recv_tx, bitcoin._1, bitcoin._2, node)) + + def handle_mempool_store(self, ec, tx_hash): + if ec: + print "Error storing memory pool transaction", tx_hash, ec + else: + print "Accepted transaction", tx_hash + + def tx_confirmed(self, ec, tx_hash): + if ec: + print "Problem confirming transaction", tx_hash, ec + else: + print "Confirmed", tx_hash + +class GhostValue: + + def __init__(self): + self.event = threading.Event() + self.value = None + + def get(self): + self.event.wait() + return self.value + + def set(self, value): + self.value = value + self.event.set() + +class NumblocksSubscribe: + + def __init__(self, backend, processor): + self.backend = backend + self.processor = processor + self.lock = threading.Lock() + self.backend.blockchain.subscribe_reorganize(self.reorganize) + self.backend.blockchain.fetch_last_depth(self.set_last_depth) + self.latest = GhostValue() + + def set_last_depth(self, ec, last_depth): + if ec: + print "Error retrieving last depth", ec + else: + self.latest.set(last_depth) + + def reorganize(self, ec, fork_point, arrivals, replaced): + latest = fork_point + len(arrivals) + self.latest.set(latest) + self.processor.push_response({"method":"numblocks.subscribe", "result": latest}) + self.backend.blockchain.subscribe_reorganize(self.reorganize) + + +class AddressGetHistory: + + def __init__(self, backend, processor): + self.backend = backend + self.processor = processor + + def get(self, request): + address = str(request["params"]) + composed.payment_history(self.backend.blockchain, address, + bitcoin.bind(self.respond, request, bitcoin._1)) + + def respond(self, request, result): + self.processor.push_response({"id": request["id"], "method":request["method"], "params":request["params"], "result": result}) + + +class BlockchainProcessor(Processor): + + def __init__(self, config): + Processor.__init__(self) + self.backend = Backend() + self.numblocks_subscribe = NumblocksSubscribe(self.backend, self) + self.address_get_history = AddressGetHistory(self.backend, self) + + def stop(self): + self.backend.stop() + + def process(self, request): + + print "New request (lib)", request + if request["method"] == "numblocks.subscribe": + self.numblocks_subscribe.subscribe(session, request) + elif request["method"] == "address.get_history": + self.address_get_history.get(request) + elif request["method"] == "server.banner": + self.push_response({"id": request["id"], "method": request["method"], "params":request["params"], + "result": "libbitcoin using python-bitcoin bindings"}) + elif request["method"] == "transaction.broadcast": + self.broadcast_transaction(request) + # Execute and when ready, you call + # self.push_response(response) + + def broadcast_transaction(self, request): + raw_tx = bitcoin.data_chunk(str(request["params"])) + exporter = bitcoin.satoshi_exporter() + try: + tx = exporter.load_transaction(raw_tx) + except RuntimeError: + response = {"id": request["id"], "method": request["method"], "params":request["params"], "result": None, + "error": {"message": + "Exception while parsing the transaction data.", + "code": -4}} + else: + self.backend.protocol.broadcast_transaction(tx) + tx_hash = str(bitcoin.hash_transaction(tx)) + response = {"id": request["id"], "method": request["method"], "params":request["params"], "result": tx_hash} + self.push_response(response) + + def run(self): + # this class is a thread. it does nothing in this example. + print "Warning: pre-alpha prototype. Full of bugs." + while not self.shared.stopped(): + time.sleep(1) + diff --git a/modules/libbitcoin/composed.py b/modules/libbitcoin/composed.py new file mode 100644 index 0000000..9df57a0 --- /dev/null +++ b/modules/libbitcoin/composed.py @@ -0,0 +1,194 @@ +import bitcoin +import threading +import time + +class ExpiryQueue(threading.Thread): + + def __init__(self): + self.lock = threading.Lock() + self.items = [] + threading.Thread.__init__(self) + self.daemon = True + + def run(self): + # Garbage collection + while True: + with self.lock: + self.items = [i for i in self.items if not i.stopped()] + time.sleep(0.1) + + def add(self, item): + with self.lock: + self.items.append(item) + +expiry_queue = ExpiryQueue() + +class StatementLine: + + def __init__(self, output_point): + self.lock = threading.Lock() + self.output_point = output_point + self.output_loaded = None + self.input_point = None + self.input_loaded = None + self.raw_output_script = None + + def is_loaded(self): + with self.lock: + if self.output_loaded is None: + return False + elif (self.input_point is not False and + self.input_loaded is None): + return False + return True + +class PaymentHistory: + + def __init__(self, chain): + self.chain = chain + self.lock = threading.Lock() + self.statement = [] + self._stopped = False + + def run(self, address, handle_finish): + self.address = address + self.handle_finish = handle_finish + + pubkey_hash = bitcoin.address_to_short_hash(address) + self.chain.fetch_outputs(pubkey_hash, self.start_loading) + + def start_loading(self, ec, output_points): + with self.lock: + for outpoint in output_points: + statement_line = StatementLine(outpoint) + self.statement.append(statement_line) + self.chain.fetch_spend(outpoint, + bitcoin.bind(self.load_spend, + bitcoin._1, bitcoin._2, statement_line)) + self.load_tx_info(outpoint, statement_line, False) + + def load_spend(self, ec, inpoint, statement_line): + with statement_line.lock: + if ec: + statement_line.input_point = False + else: + statement_line.input_point = inpoint + self.finish_if_done() + if not ec: + self.load_tx_info(inpoint, statement_line, True) + + def finish_if_done(self): + with self.lock: + if any(not line.is_loaded() for line in self.statement): + return + result = [] + for line in self.statement: + if line.input_point: + line.input_loaded["value"] = -line.output_loaded["value"] + result.append(line.input_loaded) + else: + line.output_loaded["raw_output_script"] = \ + line.raw_output_script + result.append(line.output_loaded) + self.handle_finish(result) + self.stop() + + def stop(self): + with self.lock: + self._stopped = True + + def stopped(self): + with self.lock: + return self._stopped + + def load_tx_info(self, point, statement_line, is_input): + info = {} + info["tx_hash"] = str(point.hash) + info["index"] = point.index + info["is_input"] = 1 if is_input else 0 + self.chain.fetch_transaction_index(point.hash, + bitcoin.bind(self.tx_index, bitcoin._1, bitcoin._2, bitcoin._3, + statement_line, info)) + + def tx_index(self, ec, block_depth, offset, statement_line, info): + info["height"] = block_depth + self.chain.fetch_block_header_by_depth(block_depth, + bitcoin.bind(self.block_header, bitcoin._1, bitcoin._2, + statement_line, info)) + + def block_header(self, ec, blk_head, statement_line, info): + info["timestamp"] = blk_head.timestamp + info["block_hash"] = str(bitcoin.hash_block_header(blk_head)) + tx_hash = bitcoin.hash_digest(info["tx_hash"]) + self.chain.fetch_transaction(tx_hash, + bitcoin.bind(self.load_tx, bitcoin._1, bitcoin._2, + statement_line, info)) + + def load_tx(self, ec, tx, statement_line, info): + outputs = [] + for tx_out in tx.outputs: + script = tx_out.output_script + if script.type() == bitcoin.payment_type.pubkey_hash: + pkh = bitcoin.short_hash(str(script.operations()[2].data)) + outputs.append(bitcoin.public_key_hash_to_address(pkh)) + else: + outputs.append("Unknown") + info["outputs"] = outputs + info["inputs"] = [None for i in range(len(tx.inputs))] + if info["is_input"] == 1: + info["inputs"][info["index"]] = self.address + else: + our_output = tx.outputs[info["index"]] + info["value"] = our_output.value + with statement_line.lock: + statement_line.raw_output_script = \ + str(bitcoin.save_script(our_output.output_script)) + if not [empty_in for empty_in in info["inputs"] if empty_in is None]: + # We have the sole input + assert(info["is_input"] == 1) + with statement_line.lock: + statement_line.input_loaded = info + self.finish_if_done() + for tx_idx, tx_in in enumerate(tx.inputs): + if info["is_input"] == 1 and info["index"] == tx_idx: + continue + self.chain.fetch_transaction(tx_in.previous_output.hash, + bitcoin.bind(self.load_input, bitcoin._1, bitcoin._2, + tx_in.previous_output.index, statement_line, info, tx_idx)) + + def load_input(self, ec, tx, index, statement_line, info, inputs_index): + script = tx.outputs[index].output_script + if script.type() == bitcoin.payment_type.pubkey_hash: + pkh = bitcoin.short_hash(str(script.operations()[2].data)) + info["inputs"][inputs_index] = \ + bitcoin.public_key_hash_to_address(pkh) + else: + info["inputs"][inputs_index] = "Unknown" + if not [empty_in for empty_in in info["inputs"] if empty_in is None]: + with statement_line.lock: + if info["is_input"] == 1: + statement_line.input_loaded = info + else: + statement_line.output_loaded = info + self.finish_if_done() + +def payment_history(chain, address, handle_finish): + ph = PaymentHistory(chain) + expiry_queue.add(ph) + ph.run(address, handle_finish) + +if __name__ == "__main__": + def finish(result): + print result + def last(ec, depth): + print "D:", depth + + service = bitcoin.async_service(1) + prefix = "/home/genjix/libbitcoin/database" + chain = bitcoin.bdb_blockchain(service, prefix) + chain.fetch_last_depth(last) + address = "1Pbn3DLXfjqF1fFV9YPdvpvyzejZwkHhZE" + print "Looking up", address + payment_history(chain, address, finish) + raw_input() + diff --git a/modules/python_bitcoin/__init__.py b/modules/python_bitcoin/__init__.py deleted file mode 100644 index 97440ce..0000000 --- a/modules/python_bitcoin/__init__.py +++ /dev/null @@ -1,182 +0,0 @@ -import bitcoin -from processor import Processor -import threading -import time - -import composed - -class Backend: - - def __init__(self): - # Create 3 thread-pools each with 1 thread - self.network_service = bitcoin.async_service(1) - self.disk_service = bitcoin.async_service(1) - self.mempool_service = bitcoin.async_service(1) - - self.hosts = bitcoin.hosts(self.network_service) - self.handshake = bitcoin.handshake(self.network_service) - self.network = bitcoin.network(self.network_service) - self.protocol = bitcoin.protocol(self.network_service, self.hosts, - self.handshake, self.network) - - db_prefix = "/home/genjix/libbitcoin/database" - self.blockchain = bitcoin.bdb_blockchain(self.disk_service, db_prefix) - self.poller = bitcoin.poller(self.blockchain) - self.transaction_pool = \ - bitcoin.transaction_pool(self.mempool_service, self.blockchain) - - self.protocol.subscribe_channel(self.monitor_tx) - self.session = \ - bitcoin.session(self.hosts, self.handshake, self.network, - self.protocol, self.blockchain, self.poller, - self.transaction_pool) - self.session.start(self.handle_start) - - def handle_start(self, ec): - if ec: - print "Error starting backend:", ec - - def stop(self): - self.session.stop(self.handle_stop) - - def handle_stop(self, ec): - if ec: - print "Error stopping backend:", ec - print "Stopped backend" - - def monitor_tx(self, node): - # We will be notified here when connected to new bitcoin nodes - # Here we subscribe to new transactions from them which we - # add to the transaction_pool. That way we can track which - # transactions we are interested in. - node.subscribe_transaction( - bitcoin.bind(self.recv_tx, bitcoin._1, bitcoin._2, node)) - # Re-subscribe to next new node - self.protocol.subscribe_channel(self.monitor_tx) - - def recv_tx(self, ec, tx, node): - if ec: - print "Error with new transaction:", ec - return - tx_hash = bitcoin.hash_transaction(tx) - # If we want to ignore this transaction, we can set - # the 2 handlers to be null handlers that do nothing. - self.transaction_pool.store(tx, - bitcoin.bind(self.tx_confirmed, bitcoin._1, tx_hash), - bitcoin.bind(self.handle_mempool_store, bitcoin._1, tx_hash)) - # Re-subscribe to new transactions from node - node.subscribe_transaction( - bitcoin.bind(self.recv_tx, bitcoin._1, bitcoin._2, node)) - - def handle_mempool_store(self, ec, tx_hash): - if ec: - print "Error storing memory pool transaction", tx_hash, ec - else: - print "Accepted transaction", tx_hash - - def tx_confirmed(self, ec, tx_hash): - if ec: - print "Problem confirming transaction", tx_hash, ec - else: - print "Confirmed", tx_hash - -class GhostValue: - - def __init__(self): - self.event = threading.Event() - self.value = None - - def get(self): - self.event.wait() - return self.value - - def set(self, value): - self.value = value - self.event.set() - -class NumblocksSubscribe: - - def __init__(self, backend, processor): - self.backend = backend - self.processor = processor - self.lock = threading.Lock() - self.backend.blockchain.subscribe_reorganize(self.reorganize) - self.backend.blockchain.fetch_last_depth(self.set_last_depth) - self.latest = GhostValue() - - def set_last_depth(self, ec, last_depth): - if ec: - print "Error retrieving last depth", ec - else: - self.latest.set(last_depth) - - def reorganize(self, ec, fork_point, arrivals, replaced): - latest = fork_point + len(arrivals) - self.latest.set(latest) - self.processor.push_response({"method":"numblocks.subscribe", "result": latest}) - self.backend.blockchain.subscribe_reorganize(self.reorganize) - - -class AddressGetHistory: - - def __init__(self, backend, processor): - self.backend = backend - self.processor = processor - - def get(self, request): - address = str(request["params"]) - composed.payment_history(self.backend.blockchain, address, - bitcoin.bind(self.respond, request, bitcoin._1)) - - def respond(self, request, result): - self.processor.push_response({"id": request["id"], "method":request["method"], "params":request["params"], "result": result}) - - -class BlockchainProcessor(Processor): - - def __init__(self, config): - Processor.__init__(self) - self.backend = Backend() - self.numblocks_subscribe = NumblocksSubscribe(self.backend, self) - self.address_get_history = AddressGetHistory(self.backend, self) - - def stop(self): - self.backend.stop() - - def process(self, request): - - print "New request (lib)", request - if request["method"] == "numblocks.subscribe": - self.numblocks_subscribe.subscribe(session, request) - elif request["method"] == "address.get_history": - self.address_get_history.get(request) - elif request["method"] == "server.banner": - self.push_response({"id": request["id"], "method": request["method"], "params":request["params"], - "result": "libbitcoin using python-bitcoin bindings"}) - elif request["method"] == "transaction.broadcast": - self.broadcast_transaction(request) - # Execute and when ready, you call - # self.push_response(response) - - def broadcast_transaction(self, request): - raw_tx = bitcoin.data_chunk(str(request["params"])) - exporter = bitcoin.satoshi_exporter() - try: - tx = exporter.load_transaction(raw_tx) - except RuntimeError: - response = {"id": request["id"], "method": request["method"], "params":request["params"], "result": None, - "error": {"message": - "Exception while parsing the transaction data.", - "code": -4}} - else: - self.backend.protocol.broadcast_transaction(tx) - tx_hash = str(bitcoin.hash_transaction(tx)) - response = {"id": request["id"], "method": request["method"], "params":request["params"], "result": tx_hash} - self.push_response(response) - - def run(self): - # this class is a thread. it does nothing in this example. - print "Warning: pre-alpha prototype. Full of bugs." - while not self.shared.stopped(): - time.sleep(1) - diff --git a/modules/python_bitcoin/composed.py b/modules/python_bitcoin/composed.py deleted file mode 100644 index 9df57a0..0000000 --- a/modules/python_bitcoin/composed.py +++ /dev/null @@ -1,194 +0,0 @@ -import bitcoin -import threading -import time - -class ExpiryQueue(threading.Thread): - - def __init__(self): - self.lock = threading.Lock() - self.items = [] - threading.Thread.__init__(self) - self.daemon = True - - def run(self): - # Garbage collection - while True: - with self.lock: - self.items = [i for i in self.items if not i.stopped()] - time.sleep(0.1) - - def add(self, item): - with self.lock: - self.items.append(item) - -expiry_queue = ExpiryQueue() - -class StatementLine: - - def __init__(self, output_point): - self.lock = threading.Lock() - self.output_point = output_point - self.output_loaded = None - self.input_point = None - self.input_loaded = None - self.raw_output_script = None - - def is_loaded(self): - with self.lock: - if self.output_loaded is None: - return False - elif (self.input_point is not False and - self.input_loaded is None): - return False - return True - -class PaymentHistory: - - def __init__(self, chain): - self.chain = chain - self.lock = threading.Lock() - self.statement = [] - self._stopped = False - - def run(self, address, handle_finish): - self.address = address - self.handle_finish = handle_finish - - pubkey_hash = bitcoin.address_to_short_hash(address) - self.chain.fetch_outputs(pubkey_hash, self.start_loading) - - def start_loading(self, ec, output_points): - with self.lock: - for outpoint in output_points: - statement_line = StatementLine(outpoint) - self.statement.append(statement_line) - self.chain.fetch_spend(outpoint, - bitcoin.bind(self.load_spend, - bitcoin._1, bitcoin._2, statement_line)) - self.load_tx_info(outpoint, statement_line, False) - - def load_spend(self, ec, inpoint, statement_line): - with statement_line.lock: - if ec: - statement_line.input_point = False - else: - statement_line.input_point = inpoint - self.finish_if_done() - if not ec: - self.load_tx_info(inpoint, statement_line, True) - - def finish_if_done(self): - with self.lock: - if any(not line.is_loaded() for line in self.statement): - return - result = [] - for line in self.statement: - if line.input_point: - line.input_loaded["value"] = -line.output_loaded["value"] - result.append(line.input_loaded) - else: - line.output_loaded["raw_output_script"] = \ - line.raw_output_script - result.append(line.output_loaded) - self.handle_finish(result) - self.stop() - - def stop(self): - with self.lock: - self._stopped = True - - def stopped(self): - with self.lock: - return self._stopped - - def load_tx_info(self, point, statement_line, is_input): - info = {} - info["tx_hash"] = str(point.hash) - info["index"] = point.index - info["is_input"] = 1 if is_input else 0 - self.chain.fetch_transaction_index(point.hash, - bitcoin.bind(self.tx_index, bitcoin._1, bitcoin._2, bitcoin._3, - statement_line, info)) - - def tx_index(self, ec, block_depth, offset, statement_line, info): - info["height"] = block_depth - self.chain.fetch_block_header_by_depth(block_depth, - bitcoin.bind(self.block_header, bitcoin._1, bitcoin._2, - statement_line, info)) - - def block_header(self, ec, blk_head, statement_line, info): - info["timestamp"] = blk_head.timestamp - info["block_hash"] = str(bitcoin.hash_block_header(blk_head)) - tx_hash = bitcoin.hash_digest(info["tx_hash"]) - self.chain.fetch_transaction(tx_hash, - bitcoin.bind(self.load_tx, bitcoin._1, bitcoin._2, - statement_line, info)) - - def load_tx(self, ec, tx, statement_line, info): - outputs = [] - for tx_out in tx.outputs: - script = tx_out.output_script - if script.type() == bitcoin.payment_type.pubkey_hash: - pkh = bitcoin.short_hash(str(script.operations()[2].data)) - outputs.append(bitcoin.public_key_hash_to_address(pkh)) - else: - outputs.append("Unknown") - info["outputs"] = outputs - info["inputs"] = [None for i in range(len(tx.inputs))] - if info["is_input"] == 1: - info["inputs"][info["index"]] = self.address - else: - our_output = tx.outputs[info["index"]] - info["value"] = our_output.value - with statement_line.lock: - statement_line.raw_output_script = \ - str(bitcoin.save_script(our_output.output_script)) - if not [empty_in for empty_in in info["inputs"] if empty_in is None]: - # We have the sole input - assert(info["is_input"] == 1) - with statement_line.lock: - statement_line.input_loaded = info - self.finish_if_done() - for tx_idx, tx_in in enumerate(tx.inputs): - if info["is_input"] == 1 and info["index"] == tx_idx: - continue - self.chain.fetch_transaction(tx_in.previous_output.hash, - bitcoin.bind(self.load_input, bitcoin._1, bitcoin._2, - tx_in.previous_output.index, statement_line, info, tx_idx)) - - def load_input(self, ec, tx, index, statement_line, info, inputs_index): - script = tx.outputs[index].output_script - if script.type() == bitcoin.payment_type.pubkey_hash: - pkh = bitcoin.short_hash(str(script.operations()[2].data)) - info["inputs"][inputs_index] = \ - bitcoin.public_key_hash_to_address(pkh) - else: - info["inputs"][inputs_index] = "Unknown" - if not [empty_in for empty_in in info["inputs"] if empty_in is None]: - with statement_line.lock: - if info["is_input"] == 1: - statement_line.input_loaded = info - else: - statement_line.output_loaded = info - self.finish_if_done() - -def payment_history(chain, address, handle_finish): - ph = PaymentHistory(chain) - expiry_queue.add(ph) - ph.run(address, handle_finish) - -if __name__ == "__main__": - def finish(result): - print result - def last(ec, depth): - print "D:", depth - - service = bitcoin.async_service(1) - prefix = "/home/genjix/libbitcoin/database" - chain = bitcoin.bdb_blockchain(service, prefix) - chain.fetch_last_depth(last) - address = "1Pbn3DLXfjqF1fFV9YPdvpvyzejZwkHhZE" - print "Looking up", address - payment_history(chain, address, finish) - raw_input() - diff --git a/server.py b/server.py index 71878cd..f0b2b41 100755 --- a/server.py +++ b/server.py @@ -86,10 +86,10 @@ if __name__ == '__main__': # NativeServer cannot be used with libbitcoin native_port = None config.set('server', 'native_port', '') - from modules.python_bitcoin import BlockchainProcessor - elif backend_name == "abe": - from modules.abe import AbeProcessor as BlockchainProcessor - else: + try: + backend = __import__("modules." + backend_name, + fromlist=["BlockchainProcessor"]) + except ImportError: sys.stderr.write('Unknown backend specified\n') sys.exit(-1) @@ -98,7 +98,7 @@ if __name__ == '__main__': shared = dispatcher.shared # Create and register processors - chain_proc = BlockchainProcessor(config) + chain_proc = backend.BlockchainProcessor(config) dispatcher.register('blockchain', chain_proc) server_proc = ServerProcessor(config) -- 1.7.1