X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=p2pool%2Fbitcoin%2Fheight_tracker.py;h=e5119fb8e41393e71d5602b5e2edcd8ab12c3e7c;hb=0a3493d6873cfef4fb189d39e64dfbc6e162e2a7;hp=53d7e841e5899cdbf285c2dd4ffe1d67d2ac5702;hpb=151b088435d17d4ffe24c5f37febfd37594faa28;p=p2pool.git diff --git a/p2pool/bitcoin/height_tracker.py b/p2pool/bitcoin/height_tracker.py index 53d7e84..e5119fb 100644 --- a/p2pool/bitcoin/height_tracker.py +++ b/p2pool/bitcoin/height_tracker.py @@ -1,11 +1,11 @@ -from twisted.internet import defer, task +from twisted.internet import defer from twisted.python import log -from p2pool.bitcoin import data as bitcoin_data, getwork -from p2pool.util import deferral, forest, variable +import p2pool +from p2pool.bitcoin import data as bitcoin_data +from p2pool.util import deferral, forest, jsonrpc, variable class HeaderWrapper(object): - target = 2**256 - 1 __slots__ = 'hash previous_hash'.split(' ') @classmethod @@ -18,8 +18,8 @@ class HeaderWrapper(object): class HeightTracker(object): '''Point this at a factory and let it take care of getting block heights''' - def __init__(self, rpc_proxy, factory, backlog_needed): - self._rpc_proxy = rpc_proxy + def __init__(self, best_block_func, factory, backlog_needed): + self._best_block_func = best_block_func self._factory = factory self._backlog_needed = backlog_needed @@ -29,18 +29,17 @@ class HeightTracker(object): self._watch2 = self._factory.new_block.watch(self._request) self._requested = set() - self._clear_task = task.LoopingCall(self._requested.clear) + self._clear_task = deferral.RobustLoopingCall(self._requested.clear) self._clear_task.start(60) self._last_notified_size = 0 self.updated = variable.Event() - self._think_task = task.LoopingCall(self._think) + self._think_task = deferral.RobustLoopingCall(self._think) self._think_task.start(15) - self._think2_task = task.LoopingCall(self._think2) + self._think2_task = deferral.RobustLoopingCall(self._think2) self._think2_task.start(15) - self.best_hash = None def _think(self): try: @@ -53,20 +52,14 @@ class HeightTracker(object): except: log.err(None, 'Error in HeightTracker._think:') - @defer.inlineCallbacks def _think2(self): - try: - ba = getwork.BlockAttempt.from_getwork((yield self._rpc_proxy.rpc_getwork())) - self._request(ba.previous_block) - self.best_hash = ba.previous_block - except: - log.err(None, 'Error in HeightTracker._think2:') + self._request(self._best_block_func()) def _heard_headers(self, headers): changed = False for header in headers: hw = HeaderWrapper.from_header(header) - if hw.hash in self._tracker.shares: + if hw.hash in self._tracker.items: continue changed = True self._tracker.add(hw) @@ -74,13 +67,13 @@ class HeightTracker(object): self.updated.happened() self._think() - if len(self._tracker.shares) >= self._last_notified_size + 100: - print 'Have %i/%i block headers' % (len(self._tracker.shares), self._backlog_needed) - self._last_notified_size = len(self._tracker.shares) + if len(self._tracker.items) >= self._last_notified_size + 100: + print 'Have %i/%i block headers' % (len(self._tracker.items), self._backlog_needed) + self._last_notified_size = len(self._tracker.items) @defer.inlineCallbacks def _request(self, last): - if last in self._tracker.shares: + if last in self._tracker.items: return if last in self._requested: return @@ -89,31 +82,32 @@ class HeightTracker(object): def get_height_rel_highest(self, block_hash): # callers: highest height can change during yields! - best_height, best_last = self._tracker.get_height_and_last(self.best_hash) + best_height, best_last = self._tracker.get_height_and_last(self._best_block_func()) height, last = self._tracker.get_height_and_last(block_hash) if last != best_last: return -1000000000 # XXX hack return height - best_height @defer.inlineCallbacks -def get_height_rel_highest_func(bitcoind, factory, current_work, net): +def get_height_rel_highest_func(bitcoind, factory, best_block_func, net): if '\ngetblock ' in (yield deferral.retry()(bitcoind.rpc_help)()): @deferral.DeferredCacher @defer.inlineCallbacks def height_cacher(block_hash): try: x = yield bitcoind.rpc_getblock('%x' % (block_hash,)) - except jsonrpc.Error, e: - if e.code == -5 and not p2pool.DEBUG: + except jsonrpc.Error_for_code(-5): # Block not found + if not p2pool.DEBUG: raise deferral.RetrySilentlyException() - raise + else: + raise defer.returnValue(x['blockcount'] if 'blockcount' in x else x['height']) - best_height_cached = variable.Variable((yield deferral.retry()(height_cacher)(current_work.value['previous_block']))) + best_height_cached = variable.Variable((yield deferral.retry()(height_cacher)(best_block_func()))) def get_height_rel_highest(block_hash): this_height = height_cacher.call_now(block_hash, 0) - best_height = height_cacher.call_now(current_work.value['previous_block'], 0) + best_height = height_cacher.call_now(best_block_func(), 0) best_height_cached.set(max(best_height_cached.value, this_height, best_height)) return this_height - best_height_cached.value else: - get_height_rel_highest = HeightTracker(bitcoind, factory, 5*net.SHARE_PERIOD*net.CHAIN_LENGTH/net.PARENT.BLOCK_PERIOD).get_height_rel_highest + get_height_rel_highest = HeightTracker(best_block_func, factory, 5*net.SHARE_PERIOD*net.CHAIN_LENGTH/net.PARENT.BLOCK_PERIOD).get_height_rel_highest defer.returnValue(get_height_rel_highest)