9 self.network_service = bitcoin.async_service(1)
10 self.disk_service = bitcoin.async_service(1)
11 self.mempool_service = bitcoin.async_service(1)
13 self.hosts = bitcoin.hosts(self.network_service)
14 self.handshake = bitcoin.handshake(self.network_service)
15 self.network = bitcoin.network(self.network_service)
16 self.protocol = bitcoin.protocol(self.network_service, self.hosts,
17 self.handshake, self.network)
19 db_prefix = "/home/genjix/libbitcoin/database"
20 self.blockchain = bitcoin.bdb_blockchain(self.disk_service, db_prefix)
21 self.poller = bitcoin.poller(self.blockchain)
22 self.transaction_pool = \
23 bitcoin.transaction_pool(self.mempool_service, self.blockchain)
25 self.protocol.subscribe_channel(self.monitor_tx)
27 bitcoin.session(self.hosts, self.handshake, self.network,
28 self.protocol, self.blockchain, self.poller,
29 self.transaction_pool)
30 self.session.start(self.handle_start)
32 def handle_start(self, ec):
34 print "Error starting backend:", ec
37 self.session.stop(self.handle_stop)
39 def handle_stop(self, ec):
41 print "Error stopping backend:", ec
42 print "Stopped backend"
44 def monitor_tx(self, node):
45 # We will be notified here when connected to new bitcoin nodes
46 # Here we subscribe to new transactions from them which we
47 # add to the transaction_pool. That way we can track which
48 # transactions we are interested in.
49 node.subscribe_transaction(
50 bitcoin.bind(self.recv_tx, bitcoin._1, bitcoin._2, node))
51 # Re-subscribe to next new node
52 self.protocol.subscribe_channel(self.monitor_tx)
54 def recv_tx(self, ec, tx, node):
56 print "Error with new transaction:", ec
58 tx_hash = bitcoin.hash_transaction(tx)
59 self.transaction_pool.store(tx,
60 bitcoin.bind(self.tx_confirmed, bitcoin._1, tx_hash),
61 bitcoin.bind(self.handle_mempool_store, bitcoin._1, tx_hash))
62 # Re-subscribe to new transactions from node
63 node.subscribe_transaction(
64 bitcoin.bind(self.recv_tx, bitcoin._1, bitcoin._2, node))
66 def handle_mempool_store(self, ec, tx_hash):
68 print "Error storing memory pool transaction", tx_hash, ec
70 print "Accepted transaction", tx_hash
72 def tx_confirmed(self, ec, tx_hash):
74 print "Problem confirming transaction", tx_hash, ec
76 print "Confirmed", tx_hash
78 class NumblocksSubscribe:
80 def __init__(self, backend):
81 self.backend = backend
82 self.lock = threading.Lock()
83 self.backend.blockchain.subscribe_reorganize(self.reorganize)
84 self.backend.blockchain.fetch_last_depth(self.set_last_depth)
87 def subscribe(self, session, request):
88 last = self.get_last_depth()
89 session.push_response({"id": request["id"], "result": last})
91 def get_last_depth(self):
92 # Stall until last depth has been set...
93 # Should use condition variable here instead
101 def set_last_depth(self, ec, last_depth):
103 print "Error retrieving last depth", ec
106 self.latest = last_depth
108 def reorganize(self, ec, fork_point, arrivals, replaced):
111 class LibbitcoinProcessor(stratum.Processor):
114 self.backend = Backend()
115 self.numblocks_subscribe = NumblocksSubscribe(self.backend)
116 stratum.Processor.__init__(self)
121 def process(self, session):
122 request = session.pop_request()
123 if request["method"] == "numblocks.subscribe":
124 self.numblocks_subscribe.subscribe(session, request)
125 print "New request (lib)", request
126 # Execute and when ready, you call
127 # session.push_response(response)
129 if __name__ == "__main__":
130 processor = LibbitcoinProcessor()
131 app = stratum.Stratum()