try:
share.check(self)
except:
- log.err(None, 'Share check failed:')
+ log.err(None, 'Share check failed: %064x -> %064x' % (share.hash, share.previous_hash if share.previous_hash is not None else 0))
return False
else:
self.verified.add(share)
def think(self, block_rel_height_func, previous_block, bits, known_txs):
desired = set()
+ bad_peer_addresses = set()
# O(len(self.heads))
# make 'unverified heads' set?
# for each overall head, attempt verification
# if it fails, attempt on parent, and repeat
# if no successful verification because of lack of parents, request parent
- bads = set()
+ bads = []
for head in set(self.heads) - set(self.verified.heads):
head_height, last = self.get_height_and_last(head)
for share in self.get_chain(head, head_height if last is None else min(5, max(0, head_height - self.net.CHAIN_LENGTH))):
if self.attempt_verify(share):
break
- if share.hash in self.heads:
- bads.add(share.hash)
+ bads.append(share.hash)
else:
if last is not None:
desired.add((
))
for bad in bads:
assert bad not in self.verified.items
- assert bad in self.heads
+ #assert bad in self.heads
+ bad_share = self.items[bad]
+ if bad_share.peer_addr is not None:
+ bad_peer_addresses.add(bad_share.peer_addr)
if p2pool.DEBUG:
print "BAD", bad
- self.remove(bad)
+ try:
+ self.remove(bad)
+ except NotImplementedError:
+ pass
# try to get at least CHAIN_LENGTH height for each verified head, requesting parents if needed
for head in list(self.verified.heads):
for peer_addr, hash, ts, targ in desired:
print ' ', None if peer_addr is None else '%s:%i' % peer_addr, format_hash(hash), math.format_dt(time.time() - ts), bitcoin_data.target_to_difficulty(targ), ts >= timestamp_cutoff, targ <= target_cutoff
- return best, [(peer_addr, hash) for peer_addr, hash, ts, targ in desired if ts >= timestamp_cutoff], decorated_heads
+ return best, [(peer_addr, hash) for peer_addr, hash, ts, targ in desired if ts >= timestamp_cutoff], decorated_heads, bad_peer_addresses
def score(self, share_hash, block_rel_height_func):
# returns approximate lower bound on chain's hashrate in the last self.net.CHAIN_LENGTH*15//16*self.net.SHARE_PERIOD time
stop_signal.watch(t.stop)
def set_best_share(self):
- best, desired, decorated_heads = self.tracker.think(self.get_height_rel_highest, self.bitcoind_work.value['previous_block'], self.bitcoind_work.value['bits'], self.known_txs_var.value)
+ best, desired, decorated_heads, bad_peer_addresses = self.tracker.think(self.get_height_rel_highest, self.bitcoind_work.value['previous_block'], self.bitcoind_work.value['bits'], self.known_txs_var.value)
self.best_share_var.set(best)
self.desired_var.set(desired)
+ if self.p2p_node is not None:
+ for bad_peer_address in bad_peer_addresses:
+ # XXX O(n)
+ for peer in self.p2p_node.peers.itervalues():
+ if peer.addr == bad_peer_address:
+ peer.badPeerHappened()
+ break
def get_current_txouts(self):
return p2pool_data.get_expected_payouts(self.tracker, self.best_share_var.value, self.bitcoind_work.value['bits'].target, self.bitcoind_work.value['subsidy'], self.net)
def clean_tracker(self):
- best, desired, decorated_heads = self.tracker.think(self.get_height_rel_highest, self.bitcoind_work.value['previous_block'], self.bitcoind_work.value['bits'], self.known_txs_var.value)
+ best, desired, decorated_heads, bad_peer_addresses = self.tracker.think(self.get_height_rel_highest, self.bitcoind_work.value['previous_block'], self.bitcoind_work.value['bits'], self.known_txs_var.value)
# eat away at heads
if decorated_heads: