NVC protocol v. 60011 support
authorMASM fan <masmfan@gmail.com>
Sat, 1 Feb 2014 22:48:51 +0000 (02:48 +0400)
committerMASM fan <masmfan@gmail.com>
Sat, 1 Feb 2014 22:48:51 +0000 (02:48 +0400)
p2pool/bitcoin/data.py
p2pool/bitcoin/helper.py
p2pool/bitcoin/networks.py
p2pool/bitcoin/p2p.py
p2pool/data.py
p2pool/main.py
p2pool/networks.py
p2pool/node.py
p2pool/util/p2protocol.py
p2pool/web.py
p2pool/work.py

index 88e1730..74cb94b 100644 (file)
@@ -11,10 +11,11 @@ def hash256(data):
     return pack.IntType(256).unpack(hashlib.sha256(hashlib.sha256(data).digest()).digest())
 
 def hash160(data):
-    if data == '04ffd03de44a6e11b9917f3a29f9443283d9871c9d743ef30d5eddcd37094b64d1b3d8090496b53256786bf5c82932ec23c3b74d9f05a6f95a8b5529352656664b'.decode('hex'):
-        return 0x384f570ccc88ac2e7e00b026d1690a3fca63dd0 # hack for people who don't have openssl - this is the only value that p2pool ever hashes
     return pack.IntType(160).unpack(hashlib.new('ripemd160', hashlib.sha256(data).digest()).digest())
 
+def scrypt(data):
+    return pack.IntType(256).unpack(__import__('ltc_scrypt').getPoWHash(data))
+
 class ChecksummedType(pack.Type):
     def __init__(self, inner, checksum_func=lambda data: hashlib.sha256(hashlib.sha256(data).digest()).digest()[:4]):
         self.inner = inner
@@ -93,6 +94,7 @@ address_type = pack.ComposedType([
 
 tx_type = pack.ComposedType([
     ('version', pack.IntType(32)),
+    ('timestamp', pack.IntType(32)), # txn timestamp
     ('tx_ins', pack.ListType(pack.ComposedType([
         ('previous_output', pack.PossiblyNoneType(dict(hash=0, index=2**32 - 1), pack.ComposedType([
             ('hash', pack.IntType(256)),
@@ -131,6 +133,7 @@ block_header_type = pack.ComposedType([
 block_type = pack.ComposedType([
     ('header', block_header_type),
     ('txs', pack.ListType(tx_type)),
+    ('signature', pack.VarStrType()), # header signature field
 ])
 
 # merged mining
@@ -262,6 +265,16 @@ def address_to_pubkey_hash(address, net):
         raise ValueError('address not for this net!')
     return x['pubkey_hash']
 
+def address_to_script(address, net):
+    x = human_address_type.unpack(base58_decode(address))
+
+    print x['pubkey_hash']
+
+    if x['version'] != net.ADDRESS_VERSION:
+        raise ValueError('address not for this net!')
+    return '\x76\xa9' + ('\x14' + pack.IntType(160).pack(x['pubkey_hash'])) + '\x88\xac'
+
+
 # transactions
 
 def pubkey_to_script2(pubkey):
index f9c459f..3e768de 100644 (file)
@@ -39,6 +39,14 @@ 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 +54,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'],
@@ -62,7 +71,7 @@ def getwork(bitcoind, use_getblocktemplate=False):
 @deferral.retry('Error submitting primary block: (will retry)', 10, 10)
 def submit_block_p2p(block, factory, net):
     if factory.conn.value is None:
-        print >>sys.stderr, 'No bitcoind connection when block submittal attempted! %s%064x' % (net.PARENT.BLOCK_EXPLORER_URL_PREFIX, bitcoin_data.hash256(bitcoin_data.block_header_type.pack(block['header'])))
+        print >>sys.stderr, 'No bitcoind connection when block submittal attempted! %s%064x' % (net.PARENT.BLOCK_EXPLORER_URL_PREFIX, bitcoin_data.scrypt(bitcoin_data.block_header_type.pack(block['header'])))
         raise deferral.RetrySilentlyException()
     factory.conn.value.send_block(block=block)
 
@@ -70,15 +79,12 @@ def submit_block_p2p(block, factory, net):
 @defer.inlineCallbacks
 def submit_block_rpc(block, ignore_failure, bitcoind, bitcoind_work, net):
     if bitcoind_work.value['use_getblocktemplate']:
-        try:
-            result = yield bitcoind.rpc_submitblock(bitcoin_data.block_type.pack(block).encode('hex'))
-        except jsonrpc.Error_for_code(-32601): # Method not found, for older litecoin versions
-            result = yield bitcoind.rpc_getblocktemplate(dict(mode='submit', data=bitcoin_data.block_type.pack(block).encode('hex')))
+        result = yield bitcoind.rpc_submitblock(bitcoin_data.block_type.pack(block).encode('hex'))
         success = result is None
     else:
         result = yield bitcoind.rpc_getmemorypool(bitcoin_data.block_type.pack(block).encode('hex'))
         success = result
-    success_expected = net.PARENT.POW_FUNC(bitcoin_data.block_header_type.pack(block['header'])) <= block['header']['bits'].target
+    success_expected = bitcoin_data.scrypt(bitcoin_data.block_header_type.pack(block['header'])) <= block['header']['bits'].target
     if (not success and success_expected and not ignore_failure) or (success and not success_expected):
         print >>sys.stderr, 'Block submittal result: %s (%r) Expected: %s' % (success, result, success_expected)
 
index c604696..9db3252 100644 (file)
@@ -15,179 +15,53 @@ def check_genesis_block(bitcoind, genesis_block_hash):
     else:
         defer.returnValue(True)
 
+@defer.inlineCallbacks
+def get_subsidy(bitcoind, target):
+    res = yield bitcoind.rpc_getblock(target)
+
+    defer.returnValue(res)
+
 nets = dict(
-    bitcoin=math.Object(
-        P2P_PREFIX='f9beb4d9'.decode('hex'),
-        P2P_PORT=8333,
-        ADDRESS_VERSION=0,
-        RPC_PORT=8332,
+    novacoin=math.Object(
+        P2P_PREFIX='e4e8e9e5'.decode('hex'),
+        P2P_PORT=7777,
+        ADDRESS_VERSION=8,
+        RPC_PORT=8344,
         RPC_CHECK=defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-            (yield check_genesis_block(bitcoind, '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f')) and
+            0 == (yield bitcoind.rpc_getblock('00000a060336cbb72fe969666d337b87198b1add2abaa59cca226820b32933a4'))['height'] and
             not (yield bitcoind.rpc_getinfo())['testnet']
         )),
-        SUBSIDY_FUNC=lambda height: 50*100000000 >> (height + 1)//210000,
-        POW_FUNC=data.hash256,
-        BLOCK_PERIOD=600, # s
-        SYMBOL='BTC',
-        CONF_FILE_FUNC=lambda: os.path.join(os.path.join(os.environ['APPDATA'], 'Bitcoin') if platform.system() == 'Windows' else os.path.expanduser('~/Library/Application Support/Bitcoin/') if platform.system() == 'Darwin' else os.path.expanduser('~/.bitcoin'), 'bitcoin.conf'),
-        BLOCK_EXPLORER_URL_PREFIX='https://blockchain.info/block/',
-        ADDRESS_EXPLORER_URL_PREFIX='https://blockchain.info/address/',
-        TX_EXPLORER_URL_PREFIX='https://blockchain.info/tx/',
-        SANE_TARGET_RANGE=(2**256//2**32//1000 - 1, 2**256//2**32 - 1),
-        DUMB_SCRYPT_DIFF=1,
-        DUST_THRESHOLD=0.001e8,
-    ),
-    bitcoin_testnet=math.Object(
-        P2P_PREFIX='0b110907'.decode('hex'),
-        P2P_PORT=18333,
-        ADDRESS_VERSION=111,
-        RPC_PORT=18332,
-        RPC_CHECK=defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-            'bitcoinaddress' in (yield bitcoind.rpc_help()) and
-            (yield bitcoind.rpc_getinfo())['testnet']
-        )),
-        SUBSIDY_FUNC=lambda height: 50*100000000 >> (height + 1)//210000,
-        POW_FUNC=data.hash256,
+        SUBSIDY_FUNC=lambda bitcoind, target: get_subsidy(bitcoind, target),
         BLOCK_PERIOD=600, # s
-        SYMBOL='tBTC',
-        CONF_FILE_FUNC=lambda: os.path.join(os.path.join(os.environ['APPDATA'], 'Bitcoin') if platform.system() == 'Windows' else os.path.expanduser('~/Library/Application Support/Bitcoin/') if platform.system() == 'Darwin' else os.path.expanduser('~/.bitcoin'), 'bitcoin.conf'),
-        BLOCK_EXPLORER_URL_PREFIX='http://blockexplorer.com/testnet/block/',
-        ADDRESS_EXPLORER_URL_PREFIX='http://blockexplorer.com/testnet/address/',
-        TX_EXPLORER_URL_PREFIX='http://blockexplorer.com/testnet/tx/',
-        SANE_TARGET_RANGE=(2**256//2**32//1000 - 1, 2**256//2**32 - 1),
-        DUMB_SCRYPT_DIFF=1,
-        DUST_THRESHOLD=1e8,
-    ),
-    
-    namecoin=math.Object(
-        P2P_PREFIX='f9beb4fe'.decode('hex'),
-        P2P_PORT=8334,
-        ADDRESS_VERSION=52,
-        RPC_PORT=8332,
-        RPC_CHECK=defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-            'namecoinaddress' in (yield bitcoind.rpc_help()) and
-            not (yield bitcoind.rpc_getinfo())['testnet']
-        )),
-        SUBSIDY_FUNC=lambda height: 50*100000000 >> (height + 1)//210000,
-        POW_FUNC=data.hash256,
-        BLOCK_PERIOD=600, # s
-        SYMBOL='NMC',
-        CONF_FILE_FUNC=lambda: os.path.join(os.path.join(os.environ['APPDATA'], 'Namecoin') if platform.system() == 'Windows' else os.path.expanduser('~/Library/Application Support/Namecoin/') if platform.system() == 'Darwin' else os.path.expanduser('~/.namecoin'), 'bitcoin.conf'),
-        BLOCK_EXPLORER_URL_PREFIX='http://explorer.dot-bit.org/b/',
-        ADDRESS_EXPLORER_URL_PREFIX='http://explorer.dot-bit.org/a/',
-        TX_EXPLORER_URL_PREFIX='http://explorer.dot-bit.org/tx/',
-        SANE_TARGET_RANGE=(2**256//2**32 - 1, 2**256//2**32 - 1),
-        DUMB_SCRYPT_DIFF=1,
-        DUST_THRESHOLD=0.2e8,
-    ),
-    namecoin_testnet=math.Object(
-        P2P_PREFIX='fabfb5fe'.decode('hex'),
-        P2P_PORT=18334,
-        ADDRESS_VERSION=111,
-        RPC_PORT=8332,
-        RPC_CHECK=defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-            'namecoinaddress' in (yield bitcoind.rpc_help()) and
-            (yield bitcoind.rpc_getinfo())['testnet']
-        )),
-        SUBSIDY_FUNC=lambda height: 50*100000000 >> (height + 1)//210000,
-        POW_FUNC=data.hash256,
-        BLOCK_PERIOD=600, # s
-        SYMBOL='tNMC',
-        CONF_FILE_FUNC=lambda: os.path.join(os.path.join(os.environ['APPDATA'], 'Namecoin') if platform.system() == 'Windows' else os.path.expanduser('~/Library/Application Support/Namecoin/') if platform.system() == 'Darwin' else os.path.expanduser('~/.namecoin'), 'bitcoin.conf'),
-        BLOCK_EXPLORER_URL_PREFIX='http://testnet.explorer.dot-bit.org/b/',
-        ADDRESS_EXPLORER_URL_PREFIX='http://testnet.explorer.dot-bit.org/a/',
-        TX_EXPLORER_URL_PREFIX='http://testnet.explorer.dot-bit.org/tx/',
-        SANE_TARGET_RANGE=(2**256//2**32 - 1, 2**256//2**32 - 1),
-        DUMB_SCRYPT_DIFF=1,
-        DUST_THRESHOLD=1e8,
-    ),
-    
-    litecoin=math.Object(
-        P2P_PREFIX='fbc0b6db'.decode('hex'),
-        P2P_PORT=9333,
-        ADDRESS_VERSION=48,
-        RPC_PORT=9332,
-        RPC_CHECK=defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-            'litecoinaddress' in (yield bitcoind.rpc_help()) and
-            not (yield bitcoind.rpc_getinfo())['testnet']
-        )),
-        SUBSIDY_FUNC=lambda height: 50*100000000 >> (height + 1)//840000,
-        POW_FUNC=lambda data: pack.IntType(256).unpack(__import__('ltc_scrypt').getPoWHash(data)),
-        BLOCK_PERIOD=150, # s
-        SYMBOL='LTC',
-        CONF_FILE_FUNC=lambda: os.path.join(os.path.join(os.environ['APPDATA'], 'Litecoin') if platform.system() == 'Windows' else os.path.expanduser('~/Library/Application Support/Litecoin/') if platform.system() == 'Darwin' else os.path.expanduser('~/.litecoin'), 'litecoin.conf'),
-        BLOCK_EXPLORER_URL_PREFIX='http://explorer.litecoin.net/block/',
-        ADDRESS_EXPLORER_URL_PREFIX='http://explorer.litecoin.net/address/',
-        TX_EXPLORER_URL_PREFIX='http://explorer.litecoin.net/tx/',
+        SYMBOL='NVC',
+        CONF_FILE_FUNC=lambda: os.path.join(os.path.join(os.environ['APPDATA'], 'NovaCoin') if platform.system() == 'Windows' else os.path.expanduser('~/Library/Application Support/NovaCoin/') if platform.system() == 'Darwin' else os.path.expanduser('~/.novacoin'), 'novacoin.conf'),
+        BLOCK_EXPLORER_URL_PREFIX='http://explorer.novaco.in/block/',
+        ADDRESS_EXPLORER_URL_PREFIX='http://explorer.novaco.in/address/',
+        TX_EXPLORER_URL_PREFIX='http://explorer.novaco.in/tx/',
         SANE_TARGET_RANGE=(2**256//1000000000 - 1, 2**256//1000 - 1),
         DUMB_SCRYPT_DIFF=2**16,
-        DUST_THRESHOLD=0.03e8,
+        DUST_THRESHOLD=0.01e6,
     ),
-    litecoin_testnet=math.Object(
-        P2P_PREFIX='fcc1b7dc'.decode('hex'),
-        P2P_PORT=19333,
+    novacoin_testnet=math.Object(
+        P2P_PREFIX='cdf2c0ef'.decode('hex'),
+        P2P_PORT=17777,
         ADDRESS_VERSION=111,
-        RPC_PORT=19332,
+        RPC_PORT=18344,
         RPC_CHECK=defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-            'litecoinaddress' in (yield bitcoind.rpc_help()) and
+            0 == (yield bitcoind.rpc_getblock('0000c763e402f2436da9ed36c7286f62c3f6e5dbafce9ff289bd43d7459327eb'))['height'] and
             (yield bitcoind.rpc_getinfo())['testnet']
         )),
-        SUBSIDY_FUNC=lambda height: 50*100000000 >> (height + 1)//840000,
-        POW_FUNC=lambda data: pack.IntType(256).unpack(__import__('ltc_scrypt').getPoWHash(data)),
-        BLOCK_PERIOD=150, # s
-        SYMBOL='tLTC',
-        CONF_FILE_FUNC=lambda: os.path.join(os.path.join(os.environ['APPDATA'], 'Litecoin') if platform.system() == 'Windows' else os.path.expanduser('~/Library/Application Support/Litecoin/') if platform.system() == 'Darwin' else os.path.expanduser('~/.litecoin'), 'litecoin.conf'),
-        BLOCK_EXPLORER_URL_PREFIX='http://nonexistent-litecoin-testnet-explorer/block/',
-        ADDRESS_EXPLORER_URL_PREFIX='http://nonexistent-litecoin-testnet-explorer/address/',
-        TX_EXPLORER_URL_PREFIX='http://nonexistent-litecoin-testnet-explorer/tx/',
-        SANE_TARGET_RANGE=(2**256//1000000000 - 1, 2**256 - 1),
+        SUBSIDY_FUNC=lambda bitcoind, target: get_subsidy(bitcoind, target),
+        BLOCK_PERIOD=600, # s
+        SYMBOL='tNVC',
+        CONF_FILE_FUNC=lambda: os.path.join(os.path.join(os.environ['APPDATA'], 'NovaCoin') if platform.system() == 'Windows' else os.path.expanduser('~/Library/Application Support/NovaCoin/') if platform.system() == 'Darwin' else os.path.expanduser('~/.novacoin'), 'novacoin.conf'),
+        BLOCK_EXPLORER_URL_PREFIX='http://novacoin.su/block/',
+        ADDRESS_EXPLORER_URL_PREFIX='http://novacoin.su/address/',
+        TX_EXPLORER_URL_PREFIX='http://novacoin.su/tx/',
+        SANE_TARGET_RANGE=(2**256//1000000000 - 1, 2**256//1000 - 1),
         DUMB_SCRYPT_DIFF=2**16,
-        DUST_THRESHOLD=1e8,
-    ),
-
-    terracoin=math.Object(
-        P2P_PREFIX='42babe56'.decode('hex'),
-        P2P_PORT=13333,
-        ADDRESS_VERSION=0,
-        RPC_PORT=13332,
-        RPC_CHECK=defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-            'terracoinaddress' in (yield bitcoind.rpc_help()) and
-            not (yield bitcoind.rpc_getinfo())['testnet']
-        )),
-        SUBSIDY_FUNC=lambda height: 20*100000000 >> (height + 1)//1050000,
-        POW_FUNC=data.hash256,
-        BLOCK_PERIOD=120, # s
-        SYMBOL='TRC',
-        CONF_FILE_FUNC=lambda: os.path.join(os.path.join(os.environ['APPDATA'], 'Terracoin') if platform.system() == 'Windows' else os.path.expanduser('~/Library/Application Support/Terracoin/') if platform.system() == 'Darwin' else os.path.expanduser('~/.terracoin'), 'terracoin.conf'),
-        BLOCK_EXPLORER_URL_PREFIX='http://trc.cryptocoinexplorer.com/block/',
-        ADDRESS_EXPLORER_URL_PREFIX='http://trc.cryptocoinexplorer.com/address/',
-        TX_EXPLORER_URL_PREFIX='http://trc.cryptocoinexplorer.com/tx/',
-        SANE_TARGET_RANGE=(2**256//2**32//1000 - 1, 2**256//2**32 - 1),
-        DUMB_SCRYPT_DIFF=1,
-        DUST_THRESHOLD=1e8,
+        DUST_THRESHOLD=0.01e6,
     ),
-    terracoin_testnet=math.Object(
-        P2P_PREFIX='41babe56'.decode('hex'),
-        P2P_PORT=23333,
-        ADDRESS_VERSION=111,
-        RPC_PORT=23332,
-        RPC_CHECK=defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-            'terracoinaddress' in (yield bitcoind.rpc_help()) and
-            (yield bitcoind.rpc_getinfo())['testnet']
-        )),
-        SUBSIDY_FUNC=lambda height: 20*100000000 >> (height + 1)//1050000,
-        POW_FUNC=data.hash256,
-        BLOCK_PERIOD=120, # s
-        SYMBOL='tTRC',
-        CONF_FILE_FUNC=lambda: os.path.join(os.path.join(os.environ['APPDATA'], 'Terracoin') if platform.system() == 'Windows' else os.path.expanduser('~/Library/Application Support/Terracoin/') if platform.system() == 'Darwin' else os.path.expanduser('~/.terracoin'), 'terracoin.conf'),
-        BLOCK_EXPLORER_URL_PREFIX='http://trc.cryptocoinexplorer.com/testnet/block/',
-        ADDRESS_EXPLORER_URL_PREFIX='http://trc.cryptocoinexplorer.com/testnet/address/',
-        TX_EXPLORER_URL_PREFIX='http://trc.cryptocoinexplorer.com/testnet/tx/',
-        SANE_TARGET_RANGE=(2**256//2**32//1000 - 1, 2**256//2**32 - 1),
-        DUMB_SCRYPT_DIFF=1,
-        DUST_THRESHOLD=1e8,
-    ),
-
 )
 for net_name, net in nets.iteritems():
     net.NAME = net_name
index d6f50c2..6048d81 100644 (file)
@@ -18,7 +18,7 @@ class Protocol(p2protocol.Protocol):
     
     def connectionMade(self):
         self.send_version(
-            version=70002,
+            version=60011,
             services=1,
             time=int(time.time()),
             addr_to=dict(
@@ -115,7 +115,7 @@ class Protocol(p2protocol.Protocol):
         ('block', bitcoin_data.block_type),
     ])
     def handle_block(self, block):
-        block_hash = bitcoin_data.hash256(bitcoin_data.block_header_type.pack(block['header']))
+        block_hash = bitcoin_data.scrypt(bitcoin_data.block_header_type.pack(block['header']))
         self.get_block.got_response(block_hash, block)
         self.get_block_header.got_response(block_hash, block['header'])
     
@@ -125,7 +125,7 @@ class Protocol(p2protocol.Protocol):
     def handle_headers(self, headers):
         for header in headers:
             header = header['header']
-            self.get_block_header.got_response(bitcoin_data.hash256(bitcoin_data.block_header_type.pack(header)), header)
+            self.get_block_header.got_response(bitcoin_data.scrypt(bitcoin_data.block_header_type.pack(header)), header)
         self.factory.new_headers.happened([header['header'] for header in headers])
     
     message_ping = pack.ComposedType([
index e8fe347..56c7f86 100644 (file)
@@ -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 = bitcoin_data.pubkey_hash_to_script2(1242320440330127026527917315978635769218557336395)
 
 class Share(object):
     VERSION = 13
@@ -190,6 +190,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 +271,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,8 +318,9 @@ 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
-        if share_info != self.share_info:
-            raise ValueError('share_info invalid')
+# 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:
             raise ValueError('''gentx doesn't match hash_link''')
         
@@ -369,7 +372,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):
index 9c121fd..94c89c9 100644 (file)
@@ -30,7 +30,7 @@ def main(args, net, datadir_path, merged_urls, worker_endpoint):
     try:
         print 'p2pool (version %s)' % (p2pool.__version__,)
         print
-        
+
         @defer.inlineCallbacks
         def connect_p2p():
             # connect to bitcoind over bitcoin-p2p
@@ -326,7 +326,7 @@ def main(args, net, datadir_path, merged_urls, worker_endpoint):
                             shares, stale_orphan_shares, stale_doa_shares,
                             math.format_binomial_conf(stale_orphan_shares + stale_doa_shares, shares, 0.95),
                             math.format_binomial_conf(stale_orphan_shares + stale_doa_shares, shares, 0.95, lambda x: (1 - x)/(1 - stale_prop)),
-                            node.get_current_txouts().get(bitcoin_data.pubkey_hash_to_script2(my_pubkey_hash), 0)*1e-8, net.PARENT.SYMBOL,
+                            node.get_current_txouts().get(bitcoin_data.pubkey_hash_to_script2(my_pubkey_hash), 0)*1e-6, net.PARENT.SYMBOL,
                         )
                         this_str += '\n Pool: %sH/s Stale rate: %.1f%% Expected time to block: %s' % (
                             math.format(int(real_att_s)),
@@ -364,8 +364,8 @@ def run():
     parser = fixargparse.FixedArgumentParser(description='p2pool (version %s)' % (p2pool.__version__,), fromfile_prefix_chars='@')
     parser.add_argument('--version', action='version', version=p2pool.__version__)
     parser.add_argument('--net',
-        help='use specified network (default: bitcoin)',
-        action='store', choices=sorted(realnets), default='bitcoin', dest='net_name')
+        help='use specified network (default: novacoin)',
+        action='store', choices=sorted(realnets), default='novacoin', dest='net_name')
     parser.add_argument('--testnet',
         help='''use the network's testnet''',
         action='store_const', const=True, default=False, dest='testnet')
index 20cda88..aacfc19 100644 (file)
@@ -8,121 +8,42 @@ from p2pool.util import math
 # changes can be done by changing one, then the other
 
 nets = dict(
-    bitcoin=math.Object(
-        PARENT=networks.nets['bitcoin'],
-        SHARE_PERIOD=30, # seconds
-        CHAIN_LENGTH=24*60*60//10, # shares
-        REAL_CHAIN_LENGTH=24*60*60//10, # shares
-        TARGET_LOOKBEHIND=200, # shares
-        SPREAD=3, # blocks
-        IDENTIFIER='fc70035c7a81bc6f'.decode('hex'),
-        PREFIX='2472ef181efcd37b'.decode('hex'),
-        P2P_PORT=9333,
-        MIN_TARGET=0,
-        MAX_TARGET=2**256//2**32 - 1,
-        PERSIST=True,
-        WORKER_PORT=9332,
-        BOOTSTRAP_ADDRS='forre.st vps.forre.st portals94.ns01.us 54.227.25.14 119.1.96.99 204.10.105.113 76.104.150.248 89.71.151.9 76.114.13.54 72.201.24.106 79.160.2.128 207.244.175.195 168.7.116.243 94.23.215.27 218.54.45.177 5.9.157.150 78.155.217.76 91.154.90.163 173.52.43.124 78.225.49.209 220.135.57.230 169.237.101.193:8335 98.236.74.28 204.19.23.19 98.122.165.84:8338 71.90.88.222 67.168.132.228 193.6.148.18 80.218.174.253 50.43.56.102 68.13.4.106 24.246.31.2 176.31.208.222 1.202.128.218 86.155.135.31 204.237.15.51 5.12.158.126:38007 202.60.68.242 94.19.53.147 65.130.126.82 184.56.21.182 213.112.114.73 218.242.51.246 86.173.200.160 204.15.85.157 37.59.15.50 62.217.124.203 80.87.240.47 198.61.137.12 108.161.134.32 198.154.60.183:10333 71.39.52.34:9335 46.23.72.52:9343 83.143.42.177 192.95.61.149 144.76.17.34 46.65.68.119 188.227.176.66:9336 75.142.155.245:9336 213.67.135.99 76.115.224.177 50.148.193.245 64.53.185.79 80.65.30.137 109.126.14.42 76.84.63.146'.split(' '),
-        ANNOUNCE_CHANNEL='#p2pool',
-        VERSION_CHECK=lambda v: 50700 <= v < 60000 or 60010 <= v < 60100 or 60400 <= v,
-        VERSION_WARNING=lambda v: 'Upgrade Bitcoin to >=0.8.5!' if v < 80500 else None,
-    ),
-    bitcoin_testnet=math.Object(
-        PARENT=networks.nets['bitcoin_testnet'],
-        SHARE_PERIOD=30, # seconds
-        CHAIN_LENGTH=60*60//10, # shares
-        REAL_CHAIN_LENGTH=60*60//10, # shares
-        TARGET_LOOKBEHIND=200, # shares
-        SPREAD=3, # blocks
-        IDENTIFIER='5fc2be2d4f0d6bfb'.decode('hex'),
-        PREFIX='3f6057a15036f441'.decode('hex'),
-        P2P_PORT=19333,
-        MIN_TARGET=0,
-        MAX_TARGET=2**256//2**32 - 1,
-        PERSIST=False,
-        WORKER_PORT=19332,
-        BOOTSTRAP_ADDRS='forre.st vps.forre.st liteco.in'.split(' '),
-        ANNOUNCE_CHANNEL='#p2pool-alt',
-        VERSION_CHECK=lambda v: 50700 <= v < 60000 or 60010 <= v < 60100 or 60400 <= v,
-    ),
-    
-    litecoin=math.Object(
-        PARENT=networks.nets['litecoin'],
+    novacoin=math.Object(
+        PARENT=networks.nets['novacoin'],
         SHARE_PERIOD=15, # seconds
-        CHAIN_LENGTH=24*60*60//10, # shares
-        REAL_CHAIN_LENGTH=24*60*60//10, # shares
+        CHAIN_LENGTH=12*60*60//10, # shares
+        REAL_CHAIN_LENGTH=12*60*60//10, # shares
         TARGET_LOOKBEHIND=200, # shares
         SPREAD=3, # blocks
-        IDENTIFIER='e037d5b8c6923410'.decode('hex'),
-        PREFIX='7208c1a53ef629b0'.decode('hex'),
-        P2P_PORT=9338,
+        IDENTIFIER='e037d5b8c6923610'.decode('hex'),
+        PREFIX='7208c1a53ef659b0'.decode('hex'),
+        P2P_PORT=9777,
         MIN_TARGET=0,
         MAX_TARGET=2**256//2**20 - 1,
         PERSIST=True,
-        WORKER_PORT=9327,
-        BOOTSTRAP_ADDRS='forre.st vps.forre.st liteco.in 95.211.21.103 37.229.117.57 66.228.48.21 180.169.60.179 112.84.181.102 74.214.62.115 209.141.46.154 78.27.191.182 66.187.70.88 88.190.223.96 78.47.242.59 158.182.39.43 180.177.114.80 216.230.232.35 94.231.56.87 62.38.194.17 82.67.167.12 183.129.157.220 71.19.240.182 216.177.81.88 109.106.0.130 113.10.168.210 218.22.102.12 85.69.35.7:54396 201.52.162.167 95.66.173.110:8331 109.65.171.93 95.243.237.90 208.68.17.67 87.103.197.163 101.1.25.211 144.76.17.34 209.99.52.72 198.23.245.250 46.151.21.226 66.43.209.193 59.127.188.231 178.194.42.169 85.10.35.90 110.175.53.212 98.232.129.196 116.228.192.46 94.251.42.75 195.216.115.94 24.49.138.81 61.158.7.36 213.168.187.27 37.59.10.166 72.44.88.49 98.221.44.200 178.19.104.251 87.198.219.221 85.237.59.130:9310 218.16.251.86 151.236.11.119 94.23.215.27 60.190.203.228 176.31.208.222 46.163.105.201 198.84.186.74 199.175.50.102 188.142.102.15 202.191.108.46 125.65.108.19 15.185.107.232 108.161.131.248 188.116.33.39 78.142.148.62 69.42.217.130 213.110.14.23 185.10.51.18 74.71.113.207 77.89.41.253 69.171.153.219 58.210.42.10 174.107.165.198 50.53.105.6 116.213.73.50 83.150.90.211 210.28.136.11 86.58.41.122 70.63.34.88 78.155.217.76 68.193.128.182 198.199.73.40 193.6.148.18 188.177.188.189 83.109.6.82 204.10.105.113 64.91.214.180 46.4.74.44 98.234.11.149 71.189.207.226'.split(' '),
-        ANNOUNCE_CHANNEL='#p2pool-ltc',
-        VERSION_CHECK=lambda v: True,
-        VERSION_WARNING=lambda v: 'Upgrade Litecoin to >=0.8.5.1!' if v < 80501 else None,
+        WORKER_PORT=8336,
+        BOOTSTRAP_ADDRS=''.split(' '),
+        ANNOUNCE_CHANNEL='#p2pool-alt',
+        VERSION_CHECK=lambda v: v >= 60011,
     ),
-    litecoin_testnet=math.Object(
-        PARENT=networks.nets['litecoin_testnet'],
+    novacoin_testnet=math.Object(
+        PARENT=networks.nets['novacoin_testnet'],
         SHARE_PERIOD=4, # seconds
         CHAIN_LENGTH=20*60//3, # shares
         REAL_CHAIN_LENGTH=20*60//3, # shares
         TARGET_LOOKBEHIND=200, # shares
         SPREAD=3, # blocks
-        IDENTIFIER='cca5e24ec6408b1e'.decode('hex'),
-        PREFIX='ad9614f6466a39cf'.decode('hex'),
-        P2P_PORT=19338,
-        MIN_TARGET=2**256//50 - 1,
-        MAX_TARGET=2**256//50 - 1,
-        PERSIST=False,
-        WORKER_PORT=19327,
-        BOOTSTRAP_ADDRS='forre.st vps.forre.st'.split(' '),
-        ANNOUNCE_CHANNEL='#p2pool-alt',
-        VERSION_CHECK=lambda v: True,
-    ),
-
-    terracoin=math.Object(
-        PARENT=networks.nets['terracoin'],
-        SHARE_PERIOD=30, # seconds
-        CHAIN_LENGTH=24*60*60//30, # shares
-        REAL_CHAIN_LENGTH=24*60*60//30, # shares
-        TARGET_LOOKBEHIND=200, # shares
-        SPREAD=15, # blocks
-        IDENTIFIER='a41b2356a1b7d46e'.decode('hex'),
-        PREFIX='5623b62178d2b9b3'.decode('hex'),
-        P2P_PORT=9323,
-        MIN_TARGET=0,
-        MAX_TARGET=2**256//2**32 - 1,
-        PERSIST=True,
-        WORKER_PORT=9322,
-        BOOTSTRAP_ADDRS='seed1.p2pool.terracoin.org seed2.p2pool.terracoin.org forre.st vps.forre.st 93.97.192.93 66.90.73.83 67.83.108.0 219.84.64.174 24.167.17.248 109.74.195.142 83.211.86.49 94.23.34.145 168.7.116.243 94.174.40.189:9344 89.79.79.195 portals94.ns01.us'.split(' '),
-        ANNOUNCE_CHANNEL='#p2pool-alt',
-        VERSION_CHECK=lambda v: 80002 <= v,
-        VERSION_WARNING=lambda v: 'Upgrade Terracoin to >= 0.8.0.2!' if v < 80002 else None,
-    ),
-    terracoin_testnet=math.Object(
-        PARENT=networks.nets['terracoin_testnet'],
-        SHARE_PERIOD=30, # seconds
-        CHAIN_LENGTH=60*60//30, # shares
-        REAL_CHAIN_LENGTH=60*60//30, # shares
-        TARGET_LOOKBEHIND=200, # shares
-        SPREAD=15, # blocks
-        IDENTIFIER='b41b2356a5b7d35d'.decode('hex'),
-        PREFIX='1623b92172d2b8a2'.decode('hex'),
-        P2P_PORT=19323,
+        IDENTIFIER='e037d5b8c7923110'.decode('hex'),
+        PREFIX='7208c1a54ef619b0'.decode('hex'),
+        P2P_PORT=19777,
         MIN_TARGET=0,
-        MAX_TARGET=2**256//2**32 - 1,
+        MAX_TARGET=2**256//2**20 - 1,
         PERSIST=False,
-        WORKER_PORT=19322,
-        BOOTSTRAP_ADDRS='seed1.p2pool.terracoin.org seed2.p2pool.terracoin.org forre.st vps.forre.st'.split(' '),
+        WORKER_PORT=18336,
+        BOOTSTRAP_ADDRS=''.split(' '),
         ANNOUNCE_CHANNEL='#p2pool-alt',
-        VERSION_CHECK=lambda v: True,
-        VERSION_WARNING=lambda v: 'Upgrade Terracoin to >= 0.8.0.1!' if v < 80001 else None,
+        VERSION_CHECK=lambda v: v >= 60011,
     ),
-
 )
 for net_name, net in nets.iteritems():
     net.NAME = net_name
index 4a91620..1e1c556 100644 (file)
@@ -80,7 +80,7 @@ class P2PNode(p2p.Node):
         return shares
     
     def handle_bestblock(self, header, peer):
-        if self.node.net.PARENT.POW_FUNC(bitcoin_data.block_header_type.pack(header)) > header['bits'].target:
+        if self.node.net.PARENT.scrypt(bitcoin_data.block_header_type.pack(header)) > header['bits'].target:
             raise p2p.PeerMisbehavingError('received block header fails PoW test')
         self.node.handle_header(header)
     
@@ -145,6 +145,9 @@ class P2PNode(p2p.Node):
         
         @self.node.tracker.verified.added.watch
         def _(share):
+            if share.timestamp < share.min_header['timestamp']:
+                return
+
             if not (share.pow_hash <= share.header['bits'].target):
                 return
             
@@ -189,24 +192,28 @@ class Node(object):
                     self.bitcoind_work.set((yield helper.getwork(self.bitcoind, self.bitcoind_work.value['use_getblocktemplate'])))
                 except:
                     log.err()
-                yield defer.DeferredList([flag, deferral.sleep(15)], fireOnOneCallback=True)
+                yield defer.DeferredList([flag, deferral.sleep(5)], fireOnOneCallback=True)
         work_poller()
         
         # PEER WORK
         
         self.best_block_header = variable.Variable(None)
+        self.pow_subsidy = 0
         def handle_header(new_header):
+            self.pow_bits = self.bitcoind_work.value['bits']
+            self.pow_subsidy = self.bitcoind_work.value['subsidy']
+
             # check that header matches current target
-            if not (self.net.PARENT.POW_FUNC(bitcoin_data.block_header_type.pack(new_header)) <= self.bitcoind_work.value['bits'].target):
+            if not (bitcoin_data.scrypt(bitcoin_data.block_header_type.pack(new_header)) <= self.bitcoind_work.value['bits'].target):
                 return
             bitcoind_best_block = self.bitcoind_work.value['previous_block']
             if (self.best_block_header.value is None
                 or (
                     new_header['previous_block'] == bitcoind_best_block and
-                    bitcoin_data.hash256(bitcoin_data.block_header_type.pack(self.best_block_header.value)) == bitcoind_best_block
+                    bitcoin_data.scrypt(bitcoin_data.block_header_type.pack(self.best_block_header.value)) == bitcoind_best_block
                 ) # new is child of current and previous is current
                 or (
-                    bitcoin_data.hash256(bitcoin_data.block_header_type.pack(new_header)) == bitcoind_best_block and
+                    bitcoin_data.scrypt(bitcoin_data.block_header_type.pack(new_header)) == bitcoind_best_block and
                     self.best_block_header.value['previous_block'] != bitcoind_best_block
                 )): # new is current and previous is not a child of current
                 self.best_block_header.set(new_header)
@@ -245,6 +252,10 @@ 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 6e8634e..3fb5d6d 100644 (file)
@@ -87,7 +87,7 @@ class Protocol(protocol.Protocol):
         type_ = getattr(self, 'message_' + command, None)
         if type_ is None:
             raise ValueError('invalid command')
-        #print 'SEND', command, repr(payload2)[:500]
+        #print 'SEND', self._message_prefix.encode('hex'), command, repr(payload2)[:500]
         payload = type_.pack(payload2)
         if len(payload) > self._max_payload_length:
             raise TooLong('payload too long')
index 034baa5..5075154 100644 (file)
@@ -83,10 +83,10 @@ def get_web_root(wb, datadir_path, bitcoind_getinfo_var, stop_event=variable.Eve
     def get_patron_sendmany(total=None, trunc='0.01'):
         if total is None:
             return 'need total argument. go to patron_sendmany/<TOTAL>'
-        total = int(float(total)*1e8)
-        trunc = int(float(trunc)*1e8)
+        total = int(float(total)*1e6)
+        trunc = int(float(trunc)*1e6)
         return json.dumps(dict(
-            (bitcoin_data.script2_to_address(script, node.net.PARENT), value/1e8)
+            (bitcoin_data.script2_to_address(script, node.net.PARENT), value/1e6)
             for script, value in get_current_scaled_txouts(total, trunc).iteritems()
             if bitcoin_data.script2_to_address(script, node.net.PARENT) is not None
         ))
@@ -166,7 +166,7 @@ def get_web_root(wb, datadir_path, bitcoind_getinfo_var, stop_event=variable.Eve
             uptime=time.time() - start_time,
             attempts_to_share=bitcoin_data.target_to_average_attempts(node.tracker.items[node.best_share_var.value].max_target),
             attempts_to_block=bitcoin_data.target_to_average_attempts(node.bitcoind_work.value['bits'].target),
-            block_value=node.bitcoind_work.value['subsidy']*1e-8,
+            block_value=node.bitcoind_work.value['subsidy']*1e-6,
             warnings=p2pool_data.get_warnings(node.tracker, node.best_share_var.value, node.net, bitcoind_getinfo_var.value, node.bitcoind_work.value),
             donation_proportion=wb.donation_percentage/100,
             version=p2pool.__version__,
@@ -197,7 +197,7 @@ def get_web_root(wb, datadir_path, bitcoind_getinfo_var, stop_event=variable.Eve
     web_root.putChild('user_stales', WebInterface(lambda: dict((bitcoin_data.pubkey_hash_to_address(ph, node.net.PARENT), prop) for ph, prop in
         p2pool_data.get_user_stale_props(node.tracker, node.best_share_var.value, node.tracker.get_height(node.best_share_var.value)).iteritems())))
     web_root.putChild('fee', WebInterface(lambda: wb.worker_fee))
-    web_root.putChild('current_payouts', WebInterface(lambda: dict((bitcoin_data.script2_to_address(script, node.net.PARENT), value/1e8) for script, value in node.get_current_txouts().iteritems())))
+    web_root.putChild('current_payouts', WebInterface(lambda: dict((bitcoin_data.script2_to_address(script, node.net.PARENT), value/1e6) for script, value in node.get_current_txouts().iteritems())))
     web_root.putChild('patron_sendmany', WebInterface(get_patron_sendmany, 'text/plain'))
     web_root.putChild('global_stats', WebInterface(get_global_stats))
     web_root.putChild('local_stats', WebInterface(get_local_stats))
@@ -255,14 +255,14 @@ def get_web_root(wb, datadir_path, bitcoind_getinfo_var, stop_event=variable.Eve
             shares=shares,
             stale_shares=stale_orphan_shares + stale_doa_shares,
             stale_shares_breakdown=dict(orphan=stale_orphan_shares, doa=stale_doa_shares),
-            current_payout=node.get_current_txouts().get(bitcoin_data.pubkey_hash_to_script2(wb.my_pubkey_hash), 0)*1e-8,
+            current_payout=node.get_current_txouts().get(bitcoin_data.pubkey_hash_to_script2(wb.my_pubkey_hash), 0)*1e-6,
             peers=dict(
                 incoming=sum(1 for peer in node.p2p_node.peers.itervalues() if peer.incoming),
                 outgoing=sum(1 for peer in node.p2p_node.peers.itervalues() if not peer.incoming),
             ),
             attempts_to_share=bitcoin_data.target_to_average_attempts(node.tracker.items[node.best_share_var.value].max_target),
             attempts_to_block=bitcoin_data.target_to_average_attempts(node.bitcoind_work.value['bits'].target),
-            block_value=node.bitcoind_work.value['subsidy']*1e-8,
+            block_value=node.bitcoind_work.value['subsidy']*1e-6,
         ))
         
         with open(os.path.join(datadir_path, 'stats'), 'wb') as f:
@@ -311,7 +311,7 @@ def get_web_root(wb, datadir_path, bitcoind_getinfo_var, stop_event=variable.Eve
                 gentx=dict(
                     hash='%064x' % share.gentx_hash,
                     coinbase=share.share_data['coinbase'].ljust(2, '\x00').encode('hex'),
-                    value=share.share_data['subsidy']*1e-8,
+                    value=share.share_data['subsidy']*1e-6,
                     last_txout_nonce='%016x' % share.contents['last_txout_nonce'],
                 ),
                 other_transaction_hashes=['%064x' % x for x in share.get_other_tx_hashes(node.tracker)],
@@ -322,7 +322,7 @@ def get_web_root(wb, datadir_path, bitcoind_getinfo_var, stop_event=variable.Eve
     new_root.putChild('verified_heads', WebInterface(lambda: ['%064x' % x for x in node.tracker.verified.heads]))
     new_root.putChild('tails', WebInterface(lambda: ['%064x' % x for t in node.tracker.tails for x in node.tracker.reverse.get(t, set())]))
     new_root.putChild('verified_tails', WebInterface(lambda: ['%064x' % x for t in node.tracker.verified.tails for x in node.tracker.verified.reverse.get(t, set())]))
-    new_root.putChild('best_share_hash', WebInterface(lambda: '%064x' % node.best_share_var.value))
+    new_root.putChild('best_share_hash', WebInterface(lambda: '%064x' % node.best_share_var.value if (node.best_share_var.value is not None) else 0))
     new_root.putChild('my_share_hashes', WebInterface(lambda: ['%064x' % my_share_hash for my_share_hash in wb.my_share_hashes]))
     def get_share_data(share_hash_str):
         if int(share_hash_str, 16) not in node.tracker.items:
@@ -417,10 +417,10 @@ def get_web_root(wb, datadir_path, bitcoind_getinfo_var, stop_event=variable.Eve
         hd.datastreams['pool_rates'].add_datum(t, pool_rates)
         
         current_txouts = node.get_current_txouts()
-        hd.datastreams['current_payout'].add_datum(t, current_txouts.get(bitcoin_data.pubkey_hash_to_script2(wb.my_pubkey_hash), 0)*1e-8)
+        hd.datastreams['current_payout'].add_datum(t, current_txouts.get(bitcoin_data.pubkey_hash_to_script2(wb.my_pubkey_hash), 0)*1e-6)
         miner_hash_rates, miner_dead_hash_rates = wb.get_local_rates()
         current_txouts_by_address = dict((bitcoin_data.script2_to_address(script, node.net.PARENT), amount) for script, amount in current_txouts.iteritems())
-        hd.datastreams['current_payouts'].add_datum(t, dict((user, current_txouts_by_address[user]*1e-8) for user in miner_hash_rates if user in current_txouts_by_address))
+        hd.datastreams['current_payouts'].add_datum(t, dict((user, current_txouts_by_address[user]*1e-6) for user in miner_hash_rates if user in current_txouts_by_address))
         
         hd.datastreams['peers'].add_datum(t, dict(
             incoming=sum(1 for peer in node.p2p_node.peers.itervalues() if peer.incoming),
index e1c677d..ee7d7bd 100644 (file)
@@ -87,20 +87,21 @@ class WorkerBridge(worker_interface.WorkerBridge):
         def compute_work():
             t = self.node.bitcoind_work.value
             bb = self.node.best_block_header.value
-            if bb is not None and bb['previous_block'] == t['previous_block'] and self.node.net.PARENT.POW_FUNC(bitcoin_data.block_header_type.pack(bb)) <= t['bits'].target:
+            if bb is not None and bb['previous_block'] == t['previous_block'] and bitcoin_data.scrypt(bitcoin_data.block_header_type.pack(bb)) <= t['bits'].target:
                 print 'Skipping from block %x to block %x!' % (bb['previous_block'],
                     bitcoin_data.hash256(bitcoin_data.block_header_type.pack(bb)))
                 t = dict(
                     version=bb['version'],
-                    previous_block=bitcoin_data.hash256(bitcoin_data.block_header_type.pack(bb)),
-                    bits=bb['bits'], # not always true
+                    previous_block=bitcoin_data.scrypt(bitcoin_data.block_header_type.pack(bb)),
+                    bits=self.node.pow_bits, # not always true
                     coinbaseflags='',
                     height=t['height'] + 1,
-                    time=bb['timestamp'] + 600, # better way?
+                    time=t['time'] + 30, # better way?
                     transactions=[],
                     transaction_fees=[],
+                    txn_timestamp=0,
                     merkle_link=bitcoin_data.calculate_merkle_link([None], 0),
-                    subsidy=self.node.net.PARENT.SUBSIDY_FUNC(self.node.bitcoind_work.value['height']),
+                    subsidy=self.node.pow_subsidy,
                     last_update=self.node.bitcoind_work.value['last_update'],
                 )
             
@@ -219,6 +220,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']
         
         previous_share = self.node.tracker.items[self.node.best_share_var.value] if self.node.best_share_var.value is not None else None
         if previous_share is None:
@@ -262,6 +264,7 @@ class WorkerBridge(worker_interface.WorkerBridge):
                     )
         
         if True:
+            desired_timestamp = int(time.time() + 0.5)
             share_info, gentx, other_transaction_hashes, get_share = share_type.generate_transaction(
                 tracker=self.node.tracker,
                 share_data=dict(
@@ -282,13 +285,14 @@ class WorkerBridge(worker_interface.WorkerBridge):
                     desired_version=(share_type.SUCCESSOR if share_type.SUCCESSOR is not None else share_type).VOTING_VERSION,
                 ),
                 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']),
                 net=self.node.net,
                 known_txs=tx_map,
-                base_subsidy=self.node.net.PARENT.SUBSIDY_FUNC(self.current_work.value['height']),
+                base_subsidy=self.node.pow_subsidy,
+                #base_subsidy=self.node.net.PARENT.SUBSIDY_FUNC(self.current_work.value['height']),
             )
         
         packed_gentx = bitcoin_data.tx_type.pack(gentx)
@@ -316,7 +320,7 @@ class WorkerBridge(worker_interface.WorkerBridge):
         print 'New work for worker! Difficulty: %.06f Share difficulty: %.06f Total block value: %.6f %s including %i transactions' % (
             bitcoin_data.target_to_difficulty(target),
             bitcoin_data.target_to_difficulty(share_info['bits'].target),
-            self.current_work.value['subsidy']*1e-8, self.node.net.PARENT.SYMBOL,
+            self.current_work.value['subsidy']*1e-6, self.node.net.PARENT.SYMBOL,
             len(self.current_work.value['transactions']),
         )
         
@@ -338,11 +342,10 @@ class WorkerBridge(worker_interface.WorkerBridge):
             new_packed_gentx = packed_gentx[:-self.COINBASE_NONCE_LENGTH-4] + coinbase_nonce + packed_gentx[-4:] if coinbase_nonce != '\0'*self.COINBASE_NONCE_LENGTH else packed_gentx
             new_gentx = bitcoin_data.tx_type.unpack(new_packed_gentx) if coinbase_nonce != '\0'*self.COINBASE_NONCE_LENGTH else gentx
             
-            header_hash = bitcoin_data.hash256(bitcoin_data.block_header_type.pack(header))
-            pow_hash = self.node.net.PARENT.POW_FUNC(bitcoin_data.block_header_type.pack(header))
+            header_hash = pow_hash = bitcoin_data.scrypt(bitcoin_data.block_header_type.pack(header))
             try:
                 if pow_hash <= header['bits'].target or p2pool.DEBUG:
-                    helper.submit_block(dict(header=header, txs=[new_gentx] + other_transactions), False, self.node.factory, self.node.bitcoind, self.node.bitcoind_work, self.node.net)
+                    helper.submit_block(dict(header=header, txs=[new_gentx] + other_transactions, signature=''), False, self.node.factory, self.node.bitcoind, self.node.bitcoind_work, self.node.net)
                     if pow_hash <= header['bits'].target:
                         print
                         print 'GOT BLOCK FROM MINER! Passing to bitcoind! %s%064x' % (self.node.net.PARENT.BLOCK_EXPLORER_URL_PREFIX, header_hash)