e417fc782b1e248a3fa117f9299a0a4c9e5aadea
[stratum-mining.git] / lib / bitcoin_rpc.py
1 '''
2     Implements simple interface to novacoind's RPC.
3 '''
4
5 import simplejson as json
6 import base64
7 from twisted.internet import defer
8 from twisted.web import client
9
10 import stratum.logger
11 log = stratum.logger.get_logger('bitcoin_rpc')
12
13 class BitcoinRPC(object):
14
15     def __init__(self, host, port, username, password):
16         self.bitcoin_url = 'http://%s:%d' % (host, port)
17         self.credentials = base64.b64encode("%s:%s" % (username, password))
18         self.headers = {
19             'Content-Type': 'text/json',
20             'Authorization': 'Basic %s' % self.credentials,
21         }
22
23     def _call_raw(self, data):
24         return client.getPage(
25             url=self.bitcoin_url,
26             method='POST',
27             headers=self.headers,
28             postdata=data,
29         )
30
31     def _call(self, method, params):
32         return self._call_raw(json.dumps({
33                 'jsonrpc': '2.0',
34                 'method': method,
35                 'params': params,
36                 'id': '1',
37             }))
38
39     @defer.inlineCallbacks
40     def submitblock(self, block_hex):
41         resp = (yield self._call('submitblock', [block_hex,]))
42         if json.loads(resp)['result'] == None:
43             defer.returnValue(True)
44         else:
45             defer.returnValue(False)
46
47     @defer.inlineCallbacks
48     def getinfo(self):
49          resp = (yield self._call('getinfo', []))
50          defer.returnValue(json.loads(resp)['result'])
51
52     @defer.inlineCallbacks
53     def getblocktemplate(self):
54         resp = (yield self._call('getblocktemplate', []))
55         defer.returnValue(json.loads(resp)['result'])
56
57     @defer.inlineCallbacks
58     def prevhash(self):
59         resp = (yield self._call('getwork', []))
60         try:
61             defer.returnValue(json.loads(resp)['result']['data'][8:72])
62         except Exception as e:
63             log.exception("Cannot decode prevhash %s" % str(e))
64             raise
65
66     @defer.inlineCallbacks
67     def validateaddress(self, address):
68         resp = (yield self._call('validateaddress', [address,]))
69         defer.returnValue(json.loads(resp)['result'])