Check Genesis hash
Testnet RPC_PORT is 18332
This commit is contained in:
parent
852753cb94
commit
4d62019b07
41
lib/coins.py
41
lib/coins.py
@ -22,7 +22,7 @@ import sys
|
|||||||
from lib.hash import Base58, hash160, ripemd160, double_sha256, hash_to_str
|
from lib.hash import Base58, hash160, ripemd160, double_sha256, hash_to_str
|
||||||
from lib.script import ScriptPubKey
|
from lib.script import ScriptPubKey
|
||||||
from lib.tx import Deserializer, DeserializerSegWit
|
from lib.tx import Deserializer, DeserializerSegWit
|
||||||
from lib.util import cachedproperty, subclasses
|
import lib.util as util
|
||||||
|
|
||||||
|
|
||||||
class CoinError(Exception):
|
class CoinError(Exception):
|
||||||
@ -46,7 +46,7 @@ class Coin(object):
|
|||||||
'''Return a coin class given name and network.
|
'''Return a coin class given name and network.
|
||||||
|
|
||||||
Raise an exception if unrecognised.'''
|
Raise an exception if unrecognised.'''
|
||||||
for coin in subclasses(Coin):
|
for coin in util.subclasses(Coin):
|
||||||
if (coin.NAME.lower() == name.lower()
|
if (coin.NAME.lower() == name.lower()
|
||||||
and coin.NET.lower() == net.lower()):
|
and coin.NET.lower() == net.lower()):
|
||||||
return coin
|
return coin
|
||||||
@ -70,6 +70,20 @@ class Coin(object):
|
|||||||
def daemon_urls(cls, urls):
|
def daemon_urls(cls, urls):
|
||||||
return [cls.sanitize_url(url) for url in urls.split(',')]
|
return [cls.sanitize_url(url) for url in urls.split(',')]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def genesis_block(cls, block):
|
||||||
|
'''Check the Genesis block is the right one for this coin.
|
||||||
|
|
||||||
|
Return the block less its unspendable coinbase.
|
||||||
|
'''
|
||||||
|
header = block[:cls.header_len(0)]
|
||||||
|
header_hex_hash = hash_to_str(cls.header_hash(header))
|
||||||
|
if header_hex_hash != cls.GENESIS_HASH:
|
||||||
|
raise CoinError('genesis block has hash {} expected {}'
|
||||||
|
.format(header_hex_hash, cls.GENESIS_HASH))
|
||||||
|
|
||||||
|
return header + bytes(1)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def hashX_from_script(cls, script):
|
def hashX_from_script(cls, script):
|
||||||
'''Returns a hashX from a script.'''
|
'''Returns a hashX from a script.'''
|
||||||
@ -78,7 +92,7 @@ class Coin(object):
|
|||||||
return None
|
return None
|
||||||
return sha256(script).digest()[:cls.HASHX_LEN]
|
return sha256(script).digest()[:cls.HASHX_LEN]
|
||||||
|
|
||||||
@cachedproperty
|
@util.cachedproperty
|
||||||
def address_handlers(cls):
|
def address_handlers(cls):
|
||||||
return ScriptPubKey.PayToHandlers(
|
return ScriptPubKey.PayToHandlers(
|
||||||
address = cls.P2PKH_address_from_hash160,
|
address = cls.P2PKH_address_from_hash160,
|
||||||
@ -251,8 +265,8 @@ class Bitcoin(Coin):
|
|||||||
P2PKH_VERBYTE = 0x00
|
P2PKH_VERBYTE = 0x00
|
||||||
P2SH_VERBYTE = 0x05
|
P2SH_VERBYTE = 0x05
|
||||||
WIF_BYTE = 0x80
|
WIF_BYTE = 0x80
|
||||||
GENESIS_HASH=(b'000000000019d6689c085ae165831e93'
|
GENESIS_HASH=('000000000019d6689c085ae165831e93'
|
||||||
b'4ff763ae46a2a6c172b3f1b60a8ce26f')
|
'4ff763ae46a2a6c172b3f1b60a8ce26f')
|
||||||
TX_COUNT = 156335304
|
TX_COUNT = 156335304
|
||||||
TX_COUNT_HEIGHT = 429972
|
TX_COUNT_HEIGHT = 429972
|
||||||
TX_PER_BLOCK = 1800
|
TX_PER_BLOCK = 1800
|
||||||
@ -269,13 +283,14 @@ class BitcoinTestnet(Bitcoin):
|
|||||||
P2PKH_VERBYTE = 0x6f
|
P2PKH_VERBYTE = 0x6f
|
||||||
P2SH_VERBYTE = 0xc4
|
P2SH_VERBYTE = 0xc4
|
||||||
WIF_BYTE = 0xef
|
WIF_BYTE = 0xef
|
||||||
GENESIS_HASH=(b'000000000933ea01ad0ee984209779ba'
|
GENESIS_HASH=('000000000933ea01ad0ee984209779ba'
|
||||||
b'aec3ced90fa3f408719526f8d77f4943')
|
'aec3ced90fa3f408719526f8d77f4943')
|
||||||
REORG_LIMIT = 2000
|
REORG_LIMIT = 2000
|
||||||
TX_COUNT = 12242438
|
TX_COUNT = 12242438
|
||||||
TX_COUNT_HEIGHT = 1035428
|
TX_COUNT_HEIGHT = 1035428
|
||||||
TX_PER_BLOCK = 21
|
TX_PER_BLOCK = 21
|
||||||
IRC_PREFIX = "ET_"
|
IRC_PREFIX = "ET_"
|
||||||
|
RPC_PORT = 18332
|
||||||
|
|
||||||
|
|
||||||
class BitcoinTestnetSegWit(BitcoinTestnet):
|
class BitcoinTestnetSegWit(BitcoinTestnet):
|
||||||
@ -300,8 +315,8 @@ class Litecoin(Coin):
|
|||||||
P2PKH_VERBYTE = 0x30
|
P2PKH_VERBYTE = 0x30
|
||||||
P2SH_VERBYTE = 0x05
|
P2SH_VERBYTE = 0x05
|
||||||
WIF_BYTE = 0xb0
|
WIF_BYTE = 0xb0
|
||||||
GENESIS_HASH=(b'000000000019d6689c085ae165831e93'
|
GENESIS_HASH=('000000000019d6689c085ae165831e93'
|
||||||
b'4ff763ae46a2a6c172b3f1b60a8ce26f')
|
'4ff763ae46a2a6c172b3f1b60a8ce26f')
|
||||||
TX_COUNT = 8908766
|
TX_COUNT = 8908766
|
||||||
TX_COUNT_HEIGHT = 1105256
|
TX_COUNT_HEIGHT = 1105256
|
||||||
TX_PER_BLOCK = 10
|
TX_PER_BLOCK = 10
|
||||||
@ -375,8 +390,8 @@ class Dash(Coin):
|
|||||||
NET = "mainnet"
|
NET = "mainnet"
|
||||||
XPUB_VERBYTES = bytes.fromhex("02fe52cc")
|
XPUB_VERBYTES = bytes.fromhex("02fe52cc")
|
||||||
XPRV_VERBYTES = bytes.fromhex("02fe52f8")
|
XPRV_VERBYTES = bytes.fromhex("02fe52f8")
|
||||||
GENESIS_HASH = (b'00000ffd590b1485b3caadc19b22e637'
|
GENESIS_HASH = ('00000ffd590b1485b3caadc19b22e637'
|
||||||
b'9c733355108f107a430458cdf3407ab6')
|
'9c733355108f107a430458cdf3407ab6')
|
||||||
P2PKH_VERBYTE = 0x4c
|
P2PKH_VERBYTE = 0x4c
|
||||||
P2SH_VERBYTE = 0x10
|
P2SH_VERBYTE = 0x10
|
||||||
WIF_BYTE = 0xcc
|
WIF_BYTE = 0xcc
|
||||||
@ -398,8 +413,8 @@ class DashTestnet(Dash):
|
|||||||
NET = "testnet"
|
NET = "testnet"
|
||||||
XPUB_VERBYTES = bytes.fromhex("3a805837")
|
XPUB_VERBYTES = bytes.fromhex("3a805837")
|
||||||
XPRV_VERBYTES = bytes.fromhex("3a8061a0")
|
XPRV_VERBYTES = bytes.fromhex("3a8061a0")
|
||||||
GENESIS_HASH = (b'00000bafbc94add76cb75e2ec9289483'
|
GENESIS_HASH = ('00000bafbc94add76cb75e2ec9289483'
|
||||||
b'7288a481e5c005f6563d91623bf8bc2c')
|
'7288a481e5c005f6563d91623bf8bc2c')
|
||||||
P2PKH_VERBYTE = 0x8c
|
P2PKH_VERBYTE = 0x8c
|
||||||
P2SH_VERBYTE = 0x13
|
P2SH_VERBYTE = 0x13
|
||||||
WIF_BYTE = 0xef
|
WIF_BYTE = 0xef
|
||||||
|
|||||||
@ -125,9 +125,11 @@ class Prefetcher(LoggedClass):
|
|||||||
|
|
||||||
assert count == len(blocks)
|
assert count == len(blocks)
|
||||||
|
|
||||||
# Strip the unspendable genesis coinbase
|
# Special handling for genesis block
|
||||||
if first == 0:
|
if first == 0:
|
||||||
blocks[0] = blocks[0][:self.coin.header_len(0)] + bytes(1)
|
blocks[0] = self.coin.genesis_block(blocks[0])
|
||||||
|
self.logger.info('verified genesis block with hash {}'
|
||||||
|
.format(hex_hashes[0]))
|
||||||
|
|
||||||
# Update our recent average block size estimate
|
# Update our recent average block size estimate
|
||||||
size = sum(len(block) for block in blocks)
|
size = sum(len(block) for block in blocks)
|
||||||
|
|||||||
@ -142,7 +142,11 @@ class DB(util.LoggedClass):
|
|||||||
raise self.DBError('your DB version is {} but this software '
|
raise self.DBError('your DB version is {} but this software '
|
||||||
'only handles versions {}'
|
'only handles versions {}'
|
||||||
.format(self.db_version, self.DB_VERSIONS))
|
.format(self.db_version, self.DB_VERSIONS))
|
||||||
if state['genesis'] != self.coin.GENESIS_HASH:
|
# backwards compat
|
||||||
|
genesis_hash = state['genesis']
|
||||||
|
if isinstance(genesis_hash, bytes):
|
||||||
|
genesis_hash = genesis_hash.decode()
|
||||||
|
if genesis_hash != self.coin.GENESIS_HASH:
|
||||||
raise self.DBError('DB genesis hash {} does not match coin {}'
|
raise self.DBError('DB genesis hash {} does not match coin {}'
|
||||||
.format(state['genesis_hash'],
|
.format(state['genesis_hash'],
|
||||||
self.coin.GENESIS_HASH))
|
self.coin.GENESIS_HASH))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user