calculate work timestamp using included transactions
authoralexhz <balthazar@yandex.ru>
Mon, 18 Mar 2013 18:34:45 +0000 (18:34 +0000)
committeralexhz <balthazar@yandex.ru>
Mon, 18 Mar 2013 18:34:45 +0000 (18:34 +0000)
p2pool/bitcoin/helper.py
p2pool/data.py
p2pool/node.py
p2pool/work.py

index d4fb288..16cb6d5 100644 (file)
@@ -39,6 +39,16 @@ def getwork(bitcoind, use_getblocktemplate=False):
             print >>sys.stderr, 'Error: Bitcoin version too old! Upgrade to v0.5 or newer!'
             raise deferral.RetrySilentlyException()
     packed_transactions = [(x['data'] if isinstance(x, dict) else x).decode('hex') for x in work['transactions']]
+
+    transactions=map(bitcoin_data.tx_type.unpack, packed_transactions)
+    transaction_hashes=map(bitcoin_data.hash256, packed_transactions)
+    
+    txn_timestamp = 0
+    
+    for tx in transactions:
+        if tx.timestamp > txn_timestamp:
+            txn_timestamp = tx.timestamp
+
     if 'height' not in work:
         work['height'] = (yield bitcoind.rpc_getblock(work['previousblockhash']))['height'] + 1
     elif p2pool.DEBUG:
@@ -46,11 +56,12 @@ def getwork(bitcoind, use_getblocktemplate=False):
     defer.returnValue(dict(
         version=work['version'],
         previous_block=int(work['previousblockhash'], 16),
-        transactions=map(bitcoin_data.tx_type.unpack, packed_transactions),
-        transaction_hashes=map(bitcoin_data.hash256, packed_transactions),
+        transactions=transactions,
+        transaction_hashes=transaction_hashes,
         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'],
+        txn_timestamp=txn_timestamp,
         bits=bitcoin_data.FloatingIntegerType().unpack(work['bits'].decode('hex')[::-1]) if isinstance(work['bits'], (str, unicode)) else bitcoin_data.FloatingInteger(work['bits']),
         coinbaseflags=work['coinbaseflags'].decode('hex') if 'coinbaseflags' in work else ''.join(x.decode('hex') for x in work['coinbaseaux'].itervalues()) if 'coinbaseaux' in work else '',
         height=work['height'],
index 712c805..cd1efa7 100644 (file)
@@ -139,10 +139,7 @@ class Share(object):
             # 2417cc2063b11fd5255c7e5605780de78163ffc698ed22856bff1a5d880c3c44e400000000
 
             # Giving users some time to upgrade
-            if share_data['desired_version'] > 11:
-                coinbase_size = 50 + (1 + len(share_data['coinbase'])) + outpointsnum * 44 + 76 + 46
-            else:
-                coinbase_size = 59 + outpointsnum * 44 + 50
+            coinbase_size = 50 + (1 + len(share_data['coinbase'])) + outpointsnum * 44 + 76 + 46
 
             # if coinbase size is greater than 1000 bytes, it should pay fee (0.01 per 1000 bytes)
             if coinbase_size > 1000:
@@ -711,7 +708,7 @@ def get_warnings(tracker, best_share, net, bitcoind_warning, bitcoind_work_value
     desired_version_counts = get_desired_version_counts(tracker, best_share,
         min(net.CHAIN_LENGTH, 60*60//net.SHARE_PERIOD, tracker.get_height(best_share)))
     majority_desired_version = max(desired_version_counts, key=lambda k: desired_version_counts[k])
-    if majority_desired_version > 12 and desired_version_counts[majority_desired_version] > sum(desired_version_counts.itervalues())/2:
+    if majority_desired_version > 13 and desired_version_counts[majority_desired_version] > sum(desired_version_counts.itervalues())/2:
         res.append('A MAJORITY OF SHARES CONTAIN A VOTE FOR AN UNSUPPORTED SHARE IMPLEMENTATION! (v%i with %i%% support)\n'
             'An upgrade is likely necessary. Check https://github.com/CryptoManiac/p2pool for more information.' % (
                 majority_desired_version, 100*desired_version_counts[majority_desired_version]/sum(desired_version_counts.itervalues())))
index 85b501b..c3d09aa 100644 (file)
@@ -190,12 +190,10 @@ class Node(object):
 
         self.pow_bits = variable.Variable(None)
         self.pow_subsidy = 0
-        self.last_block_time = 0
 
         def handle_header(new_header):
             self.pow_bits = self.bitcoind_work.value['bits']
             self.pow_subsidy = self.bitcoind_work.value['subsidy']
-            self.last_block_time = self.bitcoind_work.value['time']
 
             # check that header matches current target
             #
@@ -251,6 +249,12 @@ class Node(object):
         # add p2p transactions from bitcoind to known_txs
         @self.factory.new_tx.watch
         def _(tx):
+            if tx.timestamp > time.time() + 3600:
+                return
+            
+            if tx.timestamp > self.bitcoind_work.value['txn_timestamp']:
+                self.bitcoind_work.value['txn_timestamp'] = tx.timestamp
+            
             new_known_txs = dict(self.known_txs_var.value)
             new_known_txs[bitcoin_data.hash256(bitcoin_data.tx_type.pack(tx))] = tx
             self.known_txs_var.set(new_known_txs)
index 73835d5..7907bee 100644 (file)
@@ -97,7 +97,7 @@ class WorkerBridge(worker_interface.WorkerBridge):
                     bits=self.node.pow_bits, # not always true
                     coinbaseflags='',
                     height=t['height'] + 1,
-                    time=t['time'] + 5, # better way?
+                    time=t['time'] + 300, # better way?
                     transactions=[],
                     transaction_fees=[],
                     merkle_link=bitcoin_data.calculate_merkle_link([None], 0),
@@ -185,6 +185,7 @@ class WorkerBridge(worker_interface.WorkerBridge):
         
         tx_hashes = [bitcoin_data.hash256(bitcoin_data.tx_type.pack(tx)) for tx in self.current_work.value['transactions']]
         tx_map = dict(zip(tx_hashes, self.current_work.value['transactions']))
+        txn_timestamp = self.current_work.value['txn_timestamp']
         
         if self.node.best_share_var.value is None:
             share_type = p2pool_data.Share
@@ -207,6 +208,7 @@ class WorkerBridge(worker_interface.WorkerBridge):
         
         if True:
             subsidy = self.node.net.PARENT.SUBSIDY_FUNC(self.current_work.value['bits'].target)
+            desired_timestamp = int(time.time() + 0.5)
 
             share_info, gentx, other_transaction_hashes, get_share = share_type.generate_transaction(
                 tracker=self.node.tracker,
@@ -225,10 +227,10 @@ class WorkerBridge(worker_interface.WorkerBridge):
                         'doa' if doas > doas_recorded_in_chain else
                         None
                     )(*self.get_stale_counts()),
-                    desired_version=12,
+                    desired_version=13,
                 ),
                 block_target=self.current_work.value['bits'].target,
-                desired_timestamp=int(time.time() + 0.5),
+                desired_timestamp=desired_timestamp if txn_timestamp < desired_timestamp else txn_timestamp + 1,
                 desired_target=desired_share_target,
                 ref_merkle_link=dict(branch=[], index=0),
                 desired_other_transaction_hashes_and_fees=zip(tx_hashes, self.current_work.value['transaction_fees']),