1 from __future__ import division
5 from twisted.internet import defer, reactor
6 from twisted.trial import unittest
7 from twisted.web import resource, server
9 from p2pool import networks, node, work
10 from p2pool.bitcoin import worker_interface
11 from p2pool.util import deferral, jsonrpc, variable
13 class factory(object):
14 new_headers = variable.Event()
15 new_block = variable.Event()
16 new_tx = variable.Event()
17 conn = variable.Variable(None)
19 def getProtocol(self):
20 return defer.Deferred()
22 class bitcoind(object):
28 def rpc_getblock(self, block_hash_hex):
29 return dict(height=42)
32 def rpc_getmemorypool(self):
35 "previousblockhash" : "000000000000016c169477c25421250ec5d32cf9c6d38538b5de970a2355fd89",
39 "flags" : "062f503253482f"
41 "coinbasevalue" : 5044450000,
42 "target" : "0000000000000513c50000000000000000000000000000000000000000000000",
43 "mintime" : 1351655621,
49 "noncerange" : "00000000ffffffff",
51 "sizelimit" : 1000000,
52 "curtime" : 1351659940,
57 class MiniNode(object):
59 @defer.inlineCallbacks
60 def start(cls, net, factory, bitcoind, peer_ports):
63 self.n = node.Node(factory, bitcoind, [], [], net)
66 self.n.p2p_node = node.P2PNode(self.n, 0, 1000000, {}, [('127.0.0.1', peer_port) for peer_port in peer_ports])
67 self.n.p2p_node.start()
69 wb = work.WorkerBridge(node=self.n, my_pubkey_hash=random.randrange(2**160), donation_percentage=random.uniform(0, 10), merged_urls=[], worker_fee=3)
70 web_root = resource.Resource()
71 worker_interface.WorkerInterface(wb).attach_to(web_root)
72 self.web_port = reactor.listenTCP(0, server.Site(web_root))
74 defer.returnValue(self)
76 @defer.inlineCallbacks
78 yield self.web_port.stopListening()
79 yield self.n.p2p_node.stop()
81 del self.web_port, self.n
83 class Test(unittest.TestCase):
84 @defer.inlineCallbacks
86 net = networks.nets['litecoin_testnet']
87 n = node.Node(factory, bitcoind, [], [], net)
90 wb = work.WorkerBridge(node=n, my_pubkey_hash=42, donation_percentage=2, merged_urls=[], worker_fee=3)
91 web_root = resource.Resource()
92 worker_interface.WorkerInterface(wb).attach_to(web_root)
93 port = reactor.listenTCP(0, server.Site(web_root))
95 proxy = jsonrpc.Proxy('http://127.0.0.1:' + str(port.getHost().port))
97 yield deferral.sleep(3)
100 blah = yield proxy.rpc_getwork()
101 yield proxy.rpc_getwork(blah['data'])
103 yield deferral.sleep(3)
105 assert len(n.tracker.items) == 100
106 assert n.tracker.verified.get_height(n.best_share_var.value) == 100
110 yield port.stopListening()
111 del net, n, wb, web_root, port, proxy
117 yield deferral.sleep(20) # waiting for work_poller to exit
119 @defer.inlineCallbacks
120 def test_nodes(self):
121 net = networks.nets['litecoin_testnet']
126 nodes.append((yield MiniNode.start(net, factory, bitcoind, [mn.n.p2p_node.serverfactory.listen_port.getHost().port for mn in nodes])))
128 yield deferral.sleep(3)
130 for i in xrange(100):
131 proxy = jsonrpc.Proxy('http://127.0.0.1:' + str(random.choice(nodes).web_port.getHost().port))
132 blah = yield proxy.rpc_getwork()
133 yield proxy.rpc_getwork(blah['data'])
134 yield deferral.sleep(random.expovariate(1/.1))
136 yield deferral.sleep(3)
138 for i, n in enumerate(nodes):
139 assert len(n.n.tracker.items) == 100, (i, len(n.n.tracker.items))
140 assert n.n.tracker.verified.get_height(n.n.best_share_var.value) == 100, (i, n.n.tracker.verified.get_height(n.n.best_share_var.value))
151 yield deferral.sleep(20) # waiting for work_poller to exit