X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=p2pool%2Fdata.py;h=72afbe4e609ebc0230d41f50127154e4c2048d47;hb=ed2c5da2875b0af5f56b11f9de41a2d300fce751;hp=a988e54b2647fd0efd5f8199c63f2e171657046e;hpb=ef706a72f4c338bfab5e58d31174a851e7ff1d76;p=p2pool.git diff --git a/p2pool/data.py b/p2pool/data.py index a988e54..72afbe4 100644 --- a/p2pool/data.py +++ b/p2pool/data.py @@ -49,7 +49,7 @@ def load_share(share, net, peer_addr): else: raise ValueError('unknown share type: %r' % (share['type'],)) -DONATION_SCRIPT = '4104ffd03de44a6e11b9917f3a29f9443283d9871c9d743ef30d5eddcd37094b64d1b3d8090496b53256786bf5c82932ec23c3b74d9f05a6f95a8b5529352656664bac'.decode('hex') +DONATION_SCRIPT = '41043b253cc0b5c8ce26f24b84bb955bec955cbb4643f19ab7ea073884f22874abdafc42040b97efec3c9eeb29ce69022a96cc1772f8bc805f78af0d3dc5c441db5fac'.decode('hex') class Share(object): VERSION = 13 @@ -139,6 +139,8 @@ class Share(object): this = tx_hash_to_this[tx_hash] else: if known_txs is not None: + if known_txs[tx_hash]['timestamp'] > desired_timestamp - 30: + continue this_size = bitcoin_data.tx_type.packed_size(known_txs[tx_hash]) if new_transaction_size + this_size > 50000: # only allow 50 kB of new txns/share break @@ -152,10 +154,10 @@ class Share(object): removed_fees = [fee for tx_hash, fee in desired_other_transaction_hashes_and_fees if tx_hash not in included_transactions] definite_fees = sum(0 if fee is None else fee for tx_hash, fee in desired_other_transaction_hashes_and_fees if tx_hash in included_transactions) if None not in removed_fees: - share_data = dict(share_data, subsidy=share_data['subsidy'] - sum(removed_fees)) + share_data = dict(share_data, subsidy=share_data['subsidy']) else: assert base_subsidy is not None - share_data = dict(share_data, subsidy=base_subsidy + definite_fees) + share_data = dict(share_data, subsidy=base_subsidy) weights, total_weight, donation_weight = tracker.get_cumulative_weights(previous_share.share_data['previous_share_hash'] if previous_share is not None else None, max(0, min(height, net.REAL_CHAIN_LENGTH) - 1), @@ -190,6 +192,9 @@ class Share(object): gentx = dict( version=1, + # coinbase timestamp must be older than share/block timestamp + # maybe there are more elegant solution, but this hack works quite well for now + timestamp=share_info['timestamp'], tx_ins=[dict( previous_output=None, sequence=None, @@ -268,8 +273,7 @@ class Share(object): ) merkle_root = bitcoin_data.check_merkle_link(self.gentx_hash, self.merkle_link) self.header = dict(self.min_header, merkle_root=merkle_root) - self.pow_hash = net.PARENT.POW_FUNC(bitcoin_data.block_header_type.pack(self.header)) - self.hash = self.header_hash = bitcoin_data.hash256(bitcoin_data.block_header_type.pack(self.header)) + self.pow_hash = self.hash = self.header_hash = bitcoin_data.scrypt(bitcoin_data.block_header_type.pack(self.header)) if self.target > net.MAX_TARGET: from p2pool import p2p @@ -316,6 +320,7 @@ class Share(object): share_info, gentx, other_tx_hashes2, get_share = self.generate_transaction(tracker, self.share_info['share_data'], self.header['bits'].target, self.share_info['timestamp'], self.share_info['bits'].target, self.contents['ref_merkle_link'], [(h, None) for h in other_tx_hashes], self.net, last_txout_nonce=self.contents['last_txout_nonce']) assert other_tx_hashes2 == other_tx_hashes +# workaround if share_info != self.share_info: raise ValueError('share_info invalid') if bitcoin_data.hash256(bitcoin_data.tx_type.pack(gentx)) != self.gentx_hash: @@ -369,7 +374,7 @@ class Share(object): other_txs = self._get_other_txs(tracker, known_txs) if other_txs is None: return None # not all txs present - return dict(header=self.header, txs=[self.check(tracker)] + other_txs) + return dict(header=self.header, txs=[self.check(tracker)] + other_txs, signature='') class WeightsSkipList(forest.TrackerSkipList): @@ -430,7 +435,7 @@ class OkayTracker(forest.Tracker): 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) @@ -438,21 +443,21 @@ class OkayTracker(forest.Tracker): 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(( @@ -463,10 +468,16 @@ class OkayTracker(forest.Tracker): )) 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): @@ -527,7 +538,7 @@ class OkayTracker(forest.Tracker): 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 @@ -594,7 +605,7 @@ def get_desired_version_counts(tracker, best_share_hash, dist): res[share.desired_version] = res.get(share.desired_version, 0) + bitcoin_data.target_to_average_attempts(share.target) return res -def get_warnings(tracker, best_share, net, bitcoind_warning, bitcoind_work_value): +def get_warnings(tracker, best_share, net, bitcoind_getinfo, bitcoind_work_value): res = [] desired_version_counts = get_desired_version_counts(tracker, best_share, @@ -605,9 +616,13 @@ def get_warnings(tracker, best_share, net, bitcoind_warning, bitcoind_work_value 'An upgrade is likely necessary. Check http://p2pool.forre.st/ for more information.' % ( majority_desired_version, 100*desired_version_counts[majority_desired_version]/sum(desired_version_counts.itervalues()))) - if bitcoind_warning is not None: - if 'This is a pre-release test build' not in bitcoind_warning: - res.append('(from bitcoind) %s' % (bitcoind_warning,)) + if bitcoind_getinfo['errors'] != '': + if 'This is a pre-release test build' not in bitcoind_getinfo['errors']: + res.append('(from bitcoind) %s' % (bitcoind_getinfo['errors'],)) + + version_warning = getattr(net, 'VERSION_WARNING', lambda v: None)(bitcoind_getinfo['version']) + if version_warning is not None: + res.append(version_warning) if time.time() > bitcoind_work_value['last_update'] + 60: res.append('''LOST CONTACT WITH BITCOIND for %s! Check that it isn't frozen or dead!''' % (math.format_dt(time.time() - bitcoind_work_value['last_update']),))