remove dangling whitespace
[stratum-mining.git] / lib / block_updater.py
1 from twisted.internet import reactor, defer
2 from stratum import settings
3
4 import util
5 from mining.interfaces import Interfaces
6
7 import stratum.logger
8 log = stratum.logger.get_logger('block_updater')
9
10 class BlockUpdater(object):
11     '''
12         Polls upstream's getinfo() and detecting new block on the network.
13         This will call registry.update_block when new prevhash appear.
14
15         This is just failback alternative when something
16         with ./bitcoind -blocknotify will go wrong.
17     '''
18
19     def __init__(self, registry, bitcoin_rpc):
20         self.bitcoin_rpc = bitcoin_rpc
21         self.registry = registry
22         self.clock = None
23         self.schedule()
24
25     def schedule(self):
26         when = self._get_next_time()
27         #log.debug("Next prevhash update in %.03f sec" % when)
28         #log.debug("Merkle update in next %.03f sec" % \
29         #          ((self.registry.last_update + settings.MERKLE_REFRESH_INTERVAL)-Interfaces.timestamper.time()))
30         self.clock = reactor.callLater(when, self.run)
31
32     def _get_next_time(self):
33         when = settings.PREVHASH_REFRESH_INTERVAL - (Interfaces.timestamper.time() - self.registry.last_update) % \
34                settings.PREVHASH_REFRESH_INTERVAL
35         return when
36
37     @defer.inlineCallbacks
38     def run(self):
39         update = False
40
41         try:
42             if self.registry.last_block:
43                 current_prevhash = "%064x" % self.registry.last_block.hashPrevBlock
44             else:
45                 current_prevhash = None
46
47             prevhash = util.reverse_hash((yield self.bitcoin_rpc.prevhash()))
48             if prevhash and prevhash != current_prevhash:
49                 log.info("New block! Prevhash: %s" % prevhash)
50                 update = True
51
52             elif Interfaces.timestamper.time() - self.registry.last_update >= settings.MERKLE_REFRESH_INTERVAL:
53                 log.info("Merkle update! Prevhash: %s" % prevhash)
54                 update = True
55
56             if update:
57                 self.registry.update_block()
58
59         except Exception:
60             log.exception("UpdateWatchdog.run failed")
61         finally:
62             self.schedule()
63
64