From 20b363009089cfdfb7e9200e652384f2ed0b91ac Mon Sep 17 00:00:00 2001 From: forrest Date: Wed, 13 Jul 2011 13:35:59 +0000 Subject: [PATCH] good chain choosing scheme git-svn-id: svn://forre.st/p2pool@1384 470744a7-cac9-478e-843e-5ec1b25c69e8 --- p2pool/bitcoin/data.py | 9 +++++++++ p2pool/bitcoin/p2p.py | 3 +++ p2pool/data.py | 37 +++++++++++++++++++++++++++---------- p2pool/main.py | 5 ++++- 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/p2pool/bitcoin/data.py b/p2pool/bitcoin/data.py index 0fa7432..3351b56 100644 --- a/p2pool/bitcoin/data.py +++ b/p2pool/bitcoin/data.py @@ -403,6 +403,7 @@ class Tracker(object): self.heights = {} # share_hash -> height_to, other_share_hash def add(self, share): + assert not isinstance(share, (int, long, type(None))) if share.hash in self.shares: return # XXX raise exception? @@ -427,6 +428,7 @@ class Tracker(object): self.heads[head] = tail def get_height_and_last(self, share_hash): + assert isinstance(share_hash, (int, long, type(None))) orig = share_hash height = 0 updates = [] @@ -445,6 +447,7 @@ class Tracker(object): return height, share_hash def get_height_and_last2(self, share_hash): + assert isinstance(share_hash, (int, long, type(None))) height = 0 while True: if share_hash not in self.shares: @@ -454,6 +457,7 @@ class Tracker(object): return height, share_hash def get_chain_known(self, start_hash): + assert isinstance(start_hash, (int, long, type(None))) ''' Chain starting with item of hash I{start_hash} of items that this Tracker contains ''' @@ -467,6 +471,8 @@ class Tracker(object): item_hash_to_get = share.previous_hash def get_chain_to_root(self, start_hash, root=None): + assert isinstance(start_hash, (int, long, type(None))) + assert isinstance(root, (int, long, type(None))) ''' Chain of hashes starting with share_hash of shares to the root (doesn't include root) Raises an error if one is missing @@ -484,6 +490,9 @@ class Tracker(object): if not self.heads: return None return max(self.heads, key=self.get_height_and_last) + + def get_highest_height(self): + return max(self.get_height_and_last(head)[0] for head in self.heads) if self.heads else 0 # network definitions diff --git a/p2pool/bitcoin/p2p.py b/p2pool/bitcoin/p2p.py index 3156fa2..dab765a 100644 --- a/p2pool/bitcoin/p2p.py +++ b/p2pool/bitcoin/p2p.py @@ -390,6 +390,9 @@ class HeightTracker(object): if last is not None: self.request([], last) return height + + def get_highest_height(self): + return self.tracker.get_highest_height() if __name__ == '__main__': factory = ClientFactory(bitcoin_data.Mainnet) diff --git a/p2pool/data.py b/p2pool/data.py index 7ab598a..d463521 100644 --- a/p2pool/data.py +++ b/p2pool/data.py @@ -231,9 +231,9 @@ def generate_transaction(tracker, previous_share_hash, new_script, subsidy, nonc if time == 0: time = 1 attempts_per_second = attempts//time - pre_target = 2**256//(net.SHARE_PERIOD*attempts_per_sec4nd) - 1 + pre_target = 2**256//(net.SHARE_PERIOD*attempts_per_second) - 1 pre_target2 = math.clip(pre_target, (previous_share2.target2*9//10, previous_share2.target2*11//10)) - pre_target3 = math.clip(pre_target2, (0, 2**256//2**25 - 1)) + pre_target3 = math.clip(pre_target2, (0, 2**256//2**24 - 1)) target2 = bitcoin_data.FloatingIntegerType().truncate_to(pre_target3) print attempts_per_second//1000, "KHASH" #print "TARGET", 2**256//target2, 2**256/pre_target @@ -380,21 +380,38 @@ class OkayTracker(bitcoin_data.Tracker): if self.attempt_verify(share): break + last = object + # try to get at least CHAIN_LENGTH height for each verified head, requesting parents if needed for head in self.verified.heads: - head_height, last = self.verified.get_height_and_last(head) - last_height, last_last = self.get_height_and_last(last) - for share in itertools.islice(self.get_chain_known(last), max(0, min(self.net.CHAIN_LENGTH - head_height, last_height - 1 - self.net.CHAIN_LENGTH))): + head_height, last_hash = self.verified.get_height_and_last(head) + last_height, last_last_hash = self.get_height_and_last(last_hash) + # XXX review boundary conditions + want = self.net.CHAIN_LENGTH - head_height + can = max(last_height - 1 - self.net.CHAIN_LENGTH, 0) if last_last_hash is not None else last_height + if want > can: + get = can + else: + get = want + #print "Z", head_height, last_hash is None, last_height, last_last_hash is None, want, can, get + for share in itertools.islice(self.get_chain_known(last_hash), get): if not self.attempt_verify(share): break - if head_height < self.net.CHAIN_LENGTH and last_last is not None: - desired.add((self.verified.shares[random.choice(list(self.verified.reverse_shares[last]))].peer, last_last)) + if head_height < self.net.CHAIN_LENGTH and last_last_hash is not None: + desired.add((self.verified.shares[random.choice(list(self.verified.reverse_shares[last_hash]))].peer, last_last_hash)) # decide best verified head def score(share_hash): - share = self.verified.shares[share_hash] - head_height, last = self.verified.get_height_and_last(share) - score2 = sum(ht.get_min_height(share.header['previous_block']) for share in itertools.islice(self.verified.get_chain_known(share_hash), self.net.CHAIN_LENGTH)) + head_height, last = self.verified.get_height_and_last(share_hash) + score2 = 0 + attempts = 0 + max_height = 0 + for share in itertools.islice(self.verified.get_chain_known(share_hash), self.net.CHAIN_LENGTH): + max_height = max(max_height, ht.get_min_height(share.header['previous_block'])) + attempts += bitcoin_data.target_to_average_attempts(share.target2) + this_score = attempts//(ht.get_highest_height() - max_height + 1) + if this_score > score2: + score2 = this_score res = (min(head_height, self.net.CHAIN_LENGTH), score2) print res return res diff --git a/p2pool/main.py b/p2pool/main.py index 639cb9f..1ff37e4 100644 --- a/p2pool/main.py +++ b/p2pool/main.py @@ -296,7 +296,10 @@ def main(args): else: return x, args.net.P2P_PORT - nodes = [('72.14.191.28', args.net.P2P_PORT)] + nodes = [ + ('72.14.191.28', args.net.P2P_PORT), + ('62.204.197.159', args.net.P2P_PORT), + ] try: nodes.append(((yield reactor.resolve('p2pool.forre.st')), args.net.P2P_PORT)) except: -- 1.7.1