From: forrest Date: Sun, 10 Jul 2011 15:19:20 +0000 (+0000) Subject: working on tracker X-Git-Tag: 0.8.2~396 X-Git-Url: https://git.novaco.in/?a=commitdiff_plain;h=24af112f6c34e334c378ee307daf86067c94ed38;p=p2pool.git working on tracker git-svn-id: svn://forre.st/p2pool@1372 470744a7-cac9-478e-843e-5ec1b25c69e8 --- diff --git a/p2pool/bitcoin/p2p.py b/p2pool/bitcoin/p2p.py index aba9532..b756c2d 100644 --- a/p2pool/bitcoin/p2p.py +++ b/p2pool/bitcoin/p2p.py @@ -35,6 +35,13 @@ class BaseProtocol(protocol.Protocol): payload = yield length + if self.compress: + try: + payload = zlib.decompress(payload) + except: + print 'FAILURE DECOMPRESSING' + continue + if checksum is not None: if hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4] != checksum: print 'RECV', command, checksum.encode('hex') if checksum is not None else None, repr(payload.encode('hex')), len(payload) @@ -69,20 +76,21 @@ class BaseProtocol(protocol.Protocol): traceback.print_exc() continue - def sendPacket(self, command, payload2={}): + def sendPacket(self, command, payload2): + if len(command) >= 12: + raise ValueError('command too long') type_ = getattr(self, "message_" + command, None) if type_ is None: raise ValueError('invalid command') payload = type_.pack(payload2) - if len(command) >= 12: - raise ValueError('command too long') if self.use_checksum: checksum = hashlib.sha256(hashlib.sha256(payload).digest()).digest()[:4] else: checksum = '' + if self.compress: + payload = zlib.compress(payload) data = self._prefix + struct.pack('<12sI', command, len(payload)) + checksum + payload self.transport.write(data) - #print 'SEND', command, payload2 def __getattr__(self, attr): prefix = 'send_' @@ -98,6 +106,7 @@ class Protocol(BaseProtocol): version = 0 + compress = False @property def use_checksum(self): return self.version >= 209 diff --git a/p2pool/data.py b/p2pool/data.py index 7bf30e3..6b2c4ee 100644 --- a/p2pool/data.py +++ b/p2pool/data.py @@ -203,7 +203,7 @@ def generate_transaction(tracker, previous_share_hash, new_script, subsidy, nonc share = dict(target=target2) dest_weights = {} - for share in itertools.chain([fake_share], itertools.islice(tracker.get_chain(previous_share_hash), net.CHAIN_LENGTH)): + for i, share in enumerate(itertools.chain([fake_share], itertools.islice(tracker.get_chain(previous_share_hash), net.CHAIN_LENGTH))): weight = bitcoin_data.target_to_average_attempts(share.share['target']) weight = max(weight, attempts_to_block - total_weight) @@ -212,6 +212,7 @@ def generate_transaction(tracker, previous_share_hash, new_script, subsidy, nonc if total_weight == attempts_to_block: break + assert total_weight == attempts_to_block or i == net.CHAIN_LENGTH + 1 amounts = dict((script, subsidy*(199*weight)//(200*total_weight)) for (script, weight) in dest_weights.iteritems()) amounts[net.SCRIPT] = amounts.get(net.SCRIPT, 0) + subsidy*1//200 # prevent fake previous p2pool blocks @@ -243,13 +244,15 @@ def generate_transaction(tracker, previous_share_hash, new_script, subsidy, nonc class Tracker(object): - def __init__(self): + def __init__(self, net): + self.net = net + self.shares = {} # hash -> share self.reverse_shares = {} # previous_share_hash -> share_hash self.heads = {} # head hash -> tail_hash self.tails = {} # tail hash -> set of head hashes - self.heights = {} # share hash -> height, to_share_hash + self.heights = {} # share_hash -> height_to, other_share_hash def add_share(self, share): if share.hash in self.shares: @@ -335,8 +338,9 @@ if __name__ == '__main__': print share_hash, t.get_height_and_last(share_hash) class OkayTracker(Tracker): - def __init__(self): - Tracker.__init__(self) + def __init__(self, net): + Tracker.__init__(self, net) + """ self.okay_cache = {} # hash -> height def is_okay(self, start, _height_after=0): @@ -364,15 +368,32 @@ class OkayTracker(Tracker): # picking up last share from for loop, ew self.okay_cache.add(share) return validate(share, to_end_rev[::-1]) - - def accept_share(self, share): - self.add_share(share) - + """ + def think(self): + desired = set() for head in self.heads: height, last = self.get_height(head) - if last is None or height >= 2*self.net.CHAIN_LENGTH: - a + if last is not None and height < 2*self.net.CHAIN_LENGTH: + desired.add(last) + continue + first_to_verify = math.nth(self.get_chain(head), self.net.CHAIN_LENGTH - 1) + to_verify = [] + for share_hash in self.get_chain(head): + if share_hash not in self.verified: + to_verify.append(share_hash) + for share_hash in reversed(to_verify): + try: + share.check(self, self.net) + except: + print + print "Share check failed:" + traceback.print_exc() + print + break + else: a + return desired + class Chain(object): def __init__(self): pass diff --git a/p2pool/p2p.py b/p2pool/p2p.py index cf53011..2aa5093 100644 --- a/p2pool/p2p.py +++ b/p2pool/p2p.py @@ -25,6 +25,7 @@ class Protocol(bitcoin_p2p.BaseProtocol): self._prefix = self.node.net.PREFIX use_checksum = True + compress = True other_version = None node_var_watch = None diff --git a/p2pool/util/math.py b/p2pool/util/math.py index 1c09e55..67a883d 100644 --- a/p2pool/util/math.py +++ b/p2pool/util/math.py @@ -29,3 +29,9 @@ def clip(x, (low, high)): return high else: return x + +def nth(i, n=0): + i = iter(i) + for _ in xrange(n): + i.next() + return i.next()