Initial commit
[stratum-mining.git] / lib / block_updater.py
diff --git a/lib/block_updater.py b/lib/block_updater.py
new file mode 100644 (file)
index 0000000..3ed44b8
--- /dev/null
@@ -0,0 +1,64 @@
+from twisted.internet import reactor, defer
+from stratum import settings
+
+import util
+from mining.interfaces import Interfaces
+
+import stratum.logger
+log = stratum.logger.get_logger('block_updater')
+
+class BlockUpdater(object):
+    '''
+        Polls upstream's getinfo() and detecting new block on the network.
+        This will call registry.update_block when new prevhash appear.
+        
+        This is just failback alternative when something
+        with ./bitcoind -blocknotify will go wrong. 
+    '''
+    
+    def __init__(self, registry, bitcoin_rpc):
+        self.bitcoin_rpc = bitcoin_rpc
+        self.registry = registry
+        self.clock = None
+        self.schedule()
+                        
+    def schedule(self):
+        when = self._get_next_time()
+        log.debug("Next prevhash update in %.03f sec" % when)
+        log.debug("Merkle update in next %.03f sec" % \
+                  ((self.registry.last_update + settings.MERKLE_REFRESH_INTERVAL)-Interfaces.timestamper.time()))
+        self.clock = reactor.callLater(when, self.run)
+        
+    def _get_next_time(self):
+        when = settings.PREVHASH_REFRESH_INTERVAL - (Interfaces.timestamper.time() - self.registry.last_update) % \
+               settings.PREVHASH_REFRESH_INTERVAL
+        return when  
+                     
+    @defer.inlineCallbacks
+    def run(self):
+        update = False
+       
+        try:             
+            if self.registry.last_block:
+                current_prevhash = "%064x" % self.registry.last_block.hashPrevBlock
+            else:
+                current_prevhash = None
+                
+            prevhash = util.reverse_hash((yield self.bitcoin_rpc.prevhash()))
+            if prevhash and prevhash != current_prevhash:
+                log.info("New block! Prevhash: %s" % prevhash)
+                update = True
+            
+            elif Interfaces.timestamper.time() - self.registry.last_update >= settings.MERKLE_REFRESH_INTERVAL:
+                log.info("Merkle update! Prevhash: %s" % prevhash)
+                update = True
+                
+            if update:
+                self.registry.update_block()
+
+        except Exception:
+            log.exception("UpdateWatchdog.run failed")
+        finally:
+            self.schedule()
+
+    
\ No newline at end of file