made iongchun's genesis block patch handle failure correctly
[p2pool.git] / p2pool / bitcoin / networks.py
index 3481975..c604696 100644 (file)
-from twisted.internet import defer
-
-
-class BitcoinMainnet(object):
-    BITCOIN_P2P_PREFIX = 'f9beb4d9'.decode('hex')
-    BITCOIN_P2P_PORT = 8333
-    BITCOIN_ADDRESS_VERSION = 0
-    BITCOIN_RPC_PORT = 8332
-    BITCOIN_RPC_CHECK = staticmethod(defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-        'name_firstupdate' not in (yield bitcoind.rpc_help()) and
-        'ixcoinaddress' not in (yield bitcoind.rpc_help()) and
-        not (yield bitcoind.rpc_getinfo())['testnet']
-    )))
-    BITCOIN_SUBSIDY_FUNC = staticmethod(lambda height: 50*100000000 >> (height + 1)//210000)
-    BITCOIN_SYMBOL = 'BTC'
-
-class BitcoinTestnet(object):
-    BITCOIN_P2P_PREFIX = 'fabfb5da'.decode('hex')
-    BITCOIN_P2P_PORT = 18333
-    BITCOIN_ADDRESS_VERSION = 111
-    BITCOIN_RPC_PORT = 8332
-    BITCOIN_RPC_CHECK = staticmethod(defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-        'name_firstupdate' not in (yield bitcoind.rpc_help()) and
-        'ixcoinaddress' not in (yield bitcoind.rpc_help()) and
-        (yield bitcoind.rpc_getinfo())['testnet']
-    )))
-    BITCOIN_SUBSIDY_FUNC = staticmethod(lambda height: 50*100000000 >> (height + 1)//210000)
-    BITCOIN_SYMBOL = 'tBTC'
-
-
-class NamecoinMainnet(object):
-    BITCOIN_P2P_PREFIX = 'f9beb4fe'.decode('hex')
-    BITCOIN_P2P_PORT = 8334
-    BITCOIN_ADDRESS_VERSION = 52
-    BITCOIN_RPC_PORT = 8332
-    BITCOIN_RPC_CHECK = staticmethod(defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-        'name_firstupdate' in (yield bitcoind.rpc_help()) and
-        'ixcoinaddress' not in (yield bitcoind.rpc_help()) and
-        not (yield bitcoind.rpc_getinfo())['testnet']
-    )))
-    BITCOIN_SUBSIDY_FUNC = staticmethod(lambda height: 50*100000000 >> (height + 1)//210000)
-    BITCOIN_SYMBOL = 'NMC'
-
-class NamecoinTestnet(object):
-    BITCOIN_P2P_PREFIX = 'fabfb5fe'.decode('hex')
-    BITCOIN_P2P_PORT = 18334
-    BITCOIN_ADDRESS_VERSION = 111
-    BITCOIN_RPC_PORT = 8332
-    BITCOIN_RPC_CHECK = staticmethod(defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-        'name_firstupdate' in (yield bitcoind.rpc_help()) and
-        'ixcoinaddress' not in (yield bitcoind.rpc_help()) and
-        (yield bitcoind.rpc_getinfo())['testnet']
-    )))
-    BITCOIN_SUBSIDY_FUNC = staticmethod(lambda height: 50*100000000 >> (height + 1)//210000)
-    BITCOIN_SYMBOL = 'tNMC'
-
-
-class IxcoinMainnet(object):
-    BITCOIN_P2P_PREFIX = 'f9beb4d9'.decode('hex')
-    BITCOIN_P2P_PORT = 8337
-    BITCOIN_ADDRESS_VERSION = 138
-    BITCOIN_RPC_PORT = 8338
-    BITCOIN_RPC_CHECK = staticmethod(defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-        'name_firstupdate' not in (yield bitcoind.rpc_help()) and
-        'ixcoinaddress' in (yield bitcoind.rpc_help()) and
-        not (yield bitcoind.rpc_getinfo())['testnet']
-    )))
-    BITCOIN_SUBSIDY_FUNC = staticmethod(lambda height: 96*100000000 >> (height + 1)//210000)
-    BITCOIN_SYMBOL = 'IXC'
+import os
+import platform
 
-class IxcoinTestnet(object):
-    BITCOIN_P2P_PREFIX = 'fabfb5da'.decode('hex')
-    BITCOIN_P2P_PORT = 18337
-    BITCOIN_ADDRESS_VERSION = 111
-    BITCOIN_RPC_PORT = 8338
-    BITCOIN_RPC_CHECK = staticmethod(defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-        'name_firstupdate' not in (yield bitcoind.rpc_help()) and
-        'ixcoinaddress' in (yield bitcoind.rpc_help()) and
-        (yield bitcoind.rpc_getinfo())['testnet']
-    )))
-    BITCOIN_SUBSIDY_FUNC = staticmethod(lambda height: 96*100000000 >> (height + 1)//210000)
-    BITCOIN_SYMBOL = 'tIXC'
-
-
-class I0coinMainnet(object):
-    BITCOIN_P2P_PREFIX = 'f1b2b3d4'.decode('hex')
-    BITCOIN_P2P_PORT = 7333
-    BITCOIN_ADDRESS_VERSION = 105
-    BITCOIN_RPC_PORT = 7332
-    BITCOIN_RPC_CHECK = staticmethod(defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-        'name_firstupdate' not in (yield bitcoind.rpc_help()) and
-        'ixcoinaddress' not in (yield bitcoind.rpc_help()) and
-        'i0coinaddress' in (yield bitcoind.rpc_help()) and
-        not (yield bitcoind.rpc_getinfo())['testnet']
-    )))
-    BITCOIN_SUBSIDY_FUNC = staticmethod(lambda height: 48*100000000 >> (height + 1)//218750)
-    BITCOIN_SYMBOL = 'I0C'
-
-class I0coinTestnet(object):
-    BITCOIN_P2P_PREFIX = 'f5b6b7d8'.decode('hex')
-    BITCOIN_P2P_PORT = 17333
-    BITCOIN_ADDRESS_VERSION = 112
-    BITCOIN_RPC_PORT = 7332
-    BITCOIN_RPC_CHECK = staticmethod(defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-        'name_firstupdate' not in (yield bitcoind.rpc_help()) and
-        'ixcoinaddress' not in (yield bitcoind.rpc_help()) and
-        'i0coinaddress' in (yield bitcoind.rpc_help()) and
-        (yield bitcoind.rpc_getinfo())['testnet']
-    )))
-    BITCOIN_SUBSIDY_FUNC = staticmethod(lambda height: 48*100000000 >> (height + 1)//218750)
-    BITCOIN_SYMBOL = 'tI0C'
-
-
-class SolidcoinMainnet(object):
-    BITCOIN_P2P_PREFIX = 'deadbabe'.decode('hex')
-    BITCOIN_P2P_PORT = 7555
-    BITCOIN_ADDRESS_VERSION = 125
-    BITCOIN_RPC_PORT = 8332
-    BITCOIN_RPC_CHECK = staticmethod(defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-        'solidcoinaddress' in (yield bitcoind.rpc_help()) and
-        not (yield bitcoind.rpc_getinfo())['testnet']
-    )))
-    BITCOIN_SUBSIDY_FUNC = staticmethod(lambda height: 32*100000000 >> (height + 1)//300000)
-    BITCOIN_SYMBOL = 'SC'
-
-
-class LitecoinMainnet(object):
-    BITCOIN_P2P_PREFIX = 'fbc0b6db'.decode('hex')
-    BITCOIN_P2P_PORT = 9333
-    BITCOIN_ADDRESS_VERSION = 48
-    BITCOIN_RPC_PORT = 9332
-    BITCOIN_RPC_CHECK = staticmethod(defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-        'litecoinaddress' in (yield bitcoind.rpc_help()) and
-        not (yield bitcoind.rpc_getinfo())['testnet']
-    )))
-    BITCOIN_SUBSIDY_FUNC = staticmethod(lambda height: 50*100000000 >> (height + 1)//840000)
-    BITCOIN_POW_SCRYPT = True;
-    BITCOIN_SYMBOL = 'LTC'
+from twisted.internet import defer
 
-class LitecoinTestnet(object):
-    BITCOIN_P2P_PREFIX = 'fcc1b7dc'.decode('hex')
-    BITCOIN_P2P_PORT = 19333
-    BITCOIN_ADDRESS_VERSION = 111
-    BITCOIN_RPC_PORT = 19332
-    BITCOIN_RPC_CHECK = staticmethod(defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
-        'litecoinaddress' in (yield bitcoind.rpc_help()) and
-        (yield bitcoind.rpc_getinfo())['testnet']
-    )))
-    BITCOIN_SUBSIDY_FUNC = staticmethod(lambda height: 50*100000000 >> (height + 1)//840000)
-    BITCOIN_POW_SCRYPT = True;
-    BITCOIN_SYMBOL = 'tLTC'
+from . import data
+from p2pool.util import math, pack, jsonrpc
+
+@defer.inlineCallbacks
+def check_genesis_block(bitcoind, genesis_block_hash):
+    try:
+        yield bitcoind.rpc_getblock(genesis_block_hash)
+    except jsonrpc.Error_for_code(-5):
+        defer.returnValue(False)
+    else:
+        defer.returnValue(True)
+
+nets = dict(
+    bitcoin=math.Object(
+        P2P_PREFIX='f9beb4d9'.decode('hex'),
+        P2P_PORT=8333,
+        ADDRESS_VERSION=0,
+        RPC_PORT=8332,
+        RPC_CHECK=defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
+            (yield check_genesis_block(bitcoind, '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f')) 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,
+        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/',
+        SANE_TARGET_RANGE=(2**256//1000000000 - 1, 2**256//1000 - 1),
+        DUMB_SCRYPT_DIFF=2**16,
+        DUST_THRESHOLD=0.03e8,
+    ),
+    litecoin_testnet=math.Object(
+        P2P_PREFIX='fcc1b7dc'.decode('hex'),
+        P2P_PORT=19333,
+        ADDRESS_VERSION=111,
+        RPC_PORT=19332,
+        RPC_CHECK=defer.inlineCallbacks(lambda bitcoind: defer.returnValue(
+            'litecoinaddress' in (yield bitcoind.rpc_help()) 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),
+        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,
+    ),
+    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