From 7f793feb4ee96e61a00655a4fbc15420d16ab3c3 Mon Sep 17 00:00:00 2001 From: Forrest Voight Date: Mon, 17 Dec 2012 15:39:11 -0500 Subject: [PATCH] fix subsidy being calculated incorrectly when per-share transaction limit is exceeded --- p2pool/bitcoin/helper.py | 1 + p2pool/data.py | 15 ++++++++++++--- p2pool/work.py | 4 +++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/p2pool/bitcoin/helper.py b/p2pool/bitcoin/helper.py index 07d18a7..a46f5fd 100644 --- a/p2pool/bitcoin/helper.py +++ b/p2pool/bitcoin/helper.py @@ -48,6 +48,7 @@ def getwork(bitcoind, use_getblocktemplate=False): previous_block=int(work['previousblockhash'], 16), transactions=map(bitcoin_data.tx_type.unpack, packed_transactions), transaction_hashes=map(bitcoin_data.hash256, packed_transactions), + transaction_fees=[x.get('fee', None) if isinstance(x, dict) else None for x in work['transactions']], subsidy=work['coinbasevalue'], time=work['time'] if 'time' in work else work['curtime'], bits=bitcoin_data.FloatingIntegerType().unpack(work['bits'].decode('hex')[::-1]) if isinstance(work['bits'], (str, unicode)) else bitcoin_data.FloatingInteger(work['bits']), diff --git a/p2pool/data.py b/p2pool/data.py index b6404f1..05f35fa 100644 --- a/p2pool/data.py +++ b/p2pool/data.py @@ -106,7 +106,7 @@ class Share(object): gentx_before_refhash = pack.VarStrType().pack(DONATION_SCRIPT) + pack.IntType(64).pack(0) + pack.VarStrType().pack('\x24' + pack.IntType(256).pack(0) + pack.IntType(32).pack(0))[:2] @classmethod - def generate_transaction(cls, tracker, share_data, block_target, desired_timestamp, desired_target, ref_merkle_link, desired_other_transaction_hashes, net, known_txs=None, last_txout_nonce=0): + def generate_transaction(cls, tracker, share_data, block_target, desired_timestamp, desired_target, ref_merkle_link, desired_other_transaction_hashes_and_fees, net, known_txs=None, last_txout_nonce=0, base_subsidy=None): previous_share = tracker.items[share_data['previous_share_hash']] if share_data['previous_share_hash'] is not None else None height, last = tracker.get_height_and_last(share_data['previous_share_hash']) @@ -148,7 +148,7 @@ class Share(object): for j, tx_hash in enumerate(share.new_transaction_hashes): if tx_hash not in tx_hash_to_this: tx_hash_to_this[tx_hash] = [1+i, j] # share_count, tx_count - for tx_hash in desired_other_transaction_hashes: + for tx_hash, fee in desired_other_transaction_hashes_and_fees: if tx_hash in tx_hash_to_this: this = tx_hash_to_this[tx_hash] else: @@ -162,6 +162,15 @@ class Share(object): transaction_hash_refs.extend(this) other_transaction_hashes.append(tx_hash) + included_transactions = set(other_transaction_hashes) + 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)) + else: + assert base_subsidy is not None + share_data = dict(share_data, subsidy=base_subsidy + definite_fees) + share_info = dict( share_data=share_data, far_share_hash=None if last is None and height < 99 else tracker.get_nth_parent_hash(share_data['previous_share_hash'], 99), @@ -297,7 +306,7 @@ class Share(object): other_tx_hashes = [tracker.items[tracker.get_nth_parent_hash(self.hash, share_count)].share_info['new_transaction_hashes'][tx_count] for share_count, tx_count in self.iter_transaction_hash_refs()] - 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'], other_tx_hashes, self.net, last_txout_nonce=self.contents['last_txout_nonce']) + 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 if share_info != self.share_info: raise ValueError('share_info invalid') diff --git a/p2pool/work.py b/p2pool/work.py index 3f2eec6..bc836ed 100644 --- a/p2pool/work.py +++ b/p2pool/work.py @@ -93,6 +93,7 @@ class WorkerBridge(worker_interface.WorkerBridge): height=t['height'] + 1, time=bb['timestamp'] + 600, # better way? transactions=[], + transaction_fees=[], merkle_link=bitcoin_data.calculate_merkle_link([None], 0), subsidy=self.node.net.PARENT.SUBSIDY_FUNC(self.node.bitcoind_work.value['height']), last_update=self.node.bitcoind_work.value['last_update'], @@ -230,9 +231,10 @@ class WorkerBridge(worker_interface.WorkerBridge): desired_timestamp=int(time.time() + 0.5), desired_target=desired_share_target, ref_merkle_link=dict(branch=[], index=0), - desired_other_transaction_hashes=tx_hashes, + desired_other_transaction_hashes_and_fees=zip(tx_hashes, self.current_work.value['transaction_fees']), net=self.node.net, known_txs=tx_map, + base_subsidy=self.node.net.PARENT.SUBSIDY_FUNC(self.current_work.value['height']), ) transactions = [gentx] + [tx_map[tx_hash] for tx_hash in other_transaction_hashes] -- 1.7.1