Merge branch 'master' into devel

This commit is contained in:
Neil Booth 2018-08-14 11:34:18 +09:00
commit a108817dd4
8 changed files with 113 additions and 26 deletions

View File

@ -2100,3 +2100,42 @@ class GroestlcoinTestnet(Groestlcoin):
'7frvhgofuf522b5i.onion t',
'aocojvqcybdoxekv.onion t',
]
class Pivx(Coin):
NAME = "Pivx"
SHORTNAME = "PIVX"
NET = "mainnet"
XPUB_VERBYTES = bytes.fromhex("022D2533")
XPRV_VERBYTES = bytes.fromhex("0221312B")
P2PKH_VERBYTE = bytes.fromhex("1e")
P2SH_VERBYTES = [bytes.fromhex("0d")]
WIF_BYTE = bytes.fromhex("d4")
GENESIS_HASH = ('0000041e482b9b9691d98eefb4847340'
'5c0b8ec31b76df3797c74a78680ef818')
BASIC_HEADER_SIZE = 80
HDR_V4_SIZE = 112
HDR_V4_HEIGHT = 863787
HDR_V4_START_OFFSET = HDR_V4_HEIGHT * BASIC_HEADER_SIZE
TX_COUNT = 2930206
TX_COUNT_HEIGHT = 1299212
TX_PER_BLOCK = 2
RPC_PORT = 51473
@classmethod
def static_header_offset(cls, height):
assert cls.STATIC_BLOCK_HEADERS
if height >= cls.HDR_V4_HEIGHT:
relative_v4_offset = (height - cls.HDR_V4_HEIGHT) * cls.HDR_V4_SIZE
return cls.HDR_V4_START_OFFSET + relative_v4_offset
else:
return height * cls.BASIC_HEADER_SIZE
@classmethod
def header_hash(cls, header):
version, = struct.unpack('<I', header[:4])
if version >= 4:
return super().header_hash(header)
else:
import quark_hash
return quark_hash.getPoWHash(header)

View File

@ -42,8 +42,8 @@ class Tx(namedtuple("Tx", "version inputs outputs locktime")):
'''Class representing a transaction.'''
@cachedproperty
def is_coinbase(self):
return self.inputs[0].is_coinbase
def is_generation(self):
return self.inputs[0].is_generation
def serialize(self):
return b''.join((
@ -63,9 +63,9 @@ class TxInput(namedtuple("TxInput", "prev_hash prev_idx script sequence")):
MINUS_1 = 4294967295
@cachedproperty
def is_coinbase(self):
return (self.prev_hash == TxInput.ZERO and
self.prev_idx == TxInput.MINUS_1)
def is_generation(self):
return (self.prev_idx == TxInput.MINUS_1 and
self.prev_hash == TxInput.ZERO)
def __str__(self):
script = self.script.hex()
@ -215,8 +215,8 @@ class TxSegWit(namedtuple("Tx", "version marker flag inputs outputs "
'''Class representing a SegWit transaction.'''
@cachedproperty
def is_coinbase(self):
return self.inputs[0].is_coinbase
def is_generation(self):
return self.inputs[0].is_generation
class DeserializerSegWit(Deserializer):
@ -327,8 +327,8 @@ class TxJoinSplit(namedtuple("Tx", "version inputs outputs locktime")):
'''Class representing a JoinSplit transaction.'''
@cachedproperty
def is_coinbase(self):
return self.inputs[0].is_coinbase if len(self.inputs) > 0 else False
def is_generation(self):
return self.inputs[0].is_generation if len(self.inputs) > 0 else False
class DeserializerZcash(DeserializerEquihash):
@ -361,8 +361,8 @@ class TxTime(namedtuple("Tx", "version time inputs outputs locktime")):
'''Class representing transaction that has a time field.'''
@cachedproperty
def is_coinbase(self):
return self.inputs[0].is_coinbase
def is_generation(self):
return self.inputs[0].is_generation
class DeserializerTxTime(Deserializer):
@ -445,13 +445,10 @@ class DeserializerGroestlcoin(DeserializerSegWit):
class TxInputDcr(namedtuple("TxInput", "prev_hash prev_idx tree sequence")):
'''Class representing a Decred transaction input.'''
ZERO = bytes(32)
MINUS_1 = 4294967295
@cachedproperty
def is_coinbase(self):
return (self.prev_hash == TxInputDcr.ZERO and
self.prev_idx == TxInputDcr.MINUS_1)
def is_generation(self):
return (self.prev_idx == TxInput.MINUS_1 and
self.prev_hash == TxInput.ZERO)
def __str__(self):
prev_hash = hash_to_hex_str(self.prev_hash)
@ -469,8 +466,8 @@ class TxDcr(namedtuple("Tx", "version inputs outputs locktime expiry "
'''Class representing a Decred transaction.'''
@cachedproperty
def is_coinbase(self):
return self.inputs[0].is_coinbase
def is_generation(self):
return self.inputs[0].is_generation
class DeserializerDecred(Deserializer):
@ -546,7 +543,7 @@ class DeserializerDecred(Deserializer):
# Drop the coinbase-like input from a vote tx as it creates problems
# with UTXOs lookups and mempool management
if inputs[0].is_coinbase and len(inputs) > 1:
if inputs[0].is_generation and len(inputs) > 1:
inputs = inputs[1:]
if produce_hash:

View File

@ -411,7 +411,7 @@ class BlockProcessor(object):
tx_numb = s_pack('<I', tx_num)
# Spend the inputs
if not tx.is_coinbase:
if not tx.is_generation:
for txin in tx.inputs:
cache_value = spend_utxo(txin.prev_hash, txin.prev_idx)
undo_info_append(cache_value)
@ -490,7 +490,7 @@ class BlockProcessor(object):
touched.add(cache_value[:-12])
# Restore the inputs
if not tx.is_coinbase:
if not tx.is_generation:
for txin in reversed(tx.inputs):
n -= undo_entry_len
undo_item = undo_info[n:n + undo_entry_len]

View File

@ -586,9 +586,7 @@ class DB(object):
self.write_utxo_state(batch)
async def all_utxos(self, hashX):
'''Return all UTXOs for an address sorted in no particular order. By
default yields at most 1000 entries.
'''
'''Return all UTXOs for an address sorted in no particular order.'''
def read_utxos():
utxos = []
utxos_append = utxos.append

View File

@ -985,7 +985,7 @@ class ElectrumX(SessionBase):
'''Return a raw block header as a hexadecimal string.
height: the header's height'''
return self.block_header(height)
return await self.block_header(height)
async def block_headers(self, start_height, count, cp_height=0):
'''Return count concatenated block headers as hex for the main chain;

View File

@ -0,0 +1,14 @@
{
"hash": "00000000003ce77135d15257a57f7508b8c5021372de2eae554f3142b60944cc",
"size": 231,
"height": 10000,
"merkleroot": "bd27e18a8abbd501b775d32fc6402a1a474a0517c1c8b04b9d487b0203f6b0f0",
"tx": [
"bd27e18a8abbd501b775d32fc6402a1a474a0517c1c8b04b9d487b0203f6b0f0"
],
"time": 1454814715,
"nonce": 14876727,
"bits": "1c06b486",
"previousblockhash": "00000000023fecac81bc148c7ab26a0190dbabeac2e8e260f62dff5205596f02",
"block": "03000000026f590552ff2df660e2e8c2eaabdb90016ab27a8c14bc81acec3f0200000000f0b0f603027b489d4bb0c8c117054a471a2a40c62fd375b701d5bb8a8ae127bdfbb5b65686b4061c3700e3000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff1f02102704fbb5b65608380001169c6108000d2f6e6f64655374726174756d2f000000000200c817a8040000001976a91493d5f8ec14e203ef275ebfe942bc6a1e2784f95088ac00f2052a010000001976a914d6716d39693e034596a1e8546b4d65e4a06159cc88ac00000000"
}

View File

@ -0,0 +1,15 @@
{
"hash": "bb6127b99bf96b150c86ac38fde17c47d6c95b460c462ef45fd5043a44479068",
"size": 461,
"height": 1000000,
"merkleroot": "ecafe8267cbc5e4b6f4aec0978b02f0ba47a19828b0f8780e25685184d61c9e2",
"tx": [
"290871d1dc1673069a4c3efef424278b377becbff0c776e20972d212daa4a3d4",
"e217611a8db9ec5994632e1f66727c53e0ba09c406f6c993c8d52f5474efe620"
],
"time": 1516510311,
"nonce": 0,
"bits": "1a7128a9",
"previousblockhash": "795ab132be197a0a173cbe3590660235d906e0011052a10206244e0eae4b5152",
"block": "0400000052514bae0e4e240602a1521001e006d93502669035be3c170a7a19be32b15a79e2c9614d188556e280870f8b82197aa40b2fb07809ec4a6f4b5ebc7c26e8afec671c645aa928711a000000004ff5c33f2832ca5fa5ecbefb33c068e32ad0ae6e47c71be916fc34615c299b8c0201000000010000000000000000000000000000000000000000000000000000000000000000ffffffff060340420f0101ffffffff01000000000000000000000000000100000001eb79b426b80013c330e13e49764deeba311f8be69d0ec117d5b4f11d72215f3e0100000049483045022100f495580e30a64b4945582fe3e9a9118a60b53ca22c44232c170ff99a9fa7e8210220712921e4ddda1afe47b2481f2d1512759aaa0ab584f16ffe4b28771437c716be01ffffffff03000000000000000000500ae8470c0000002321037e0b96219461080ce2f837825fd3c52b08199c404a0d6d59f026a6a890dc4b15ac808ef20d000000001976a914f0364dfac5fca72abd79085c6b00f9e8f35bbff688ac0000000046304402203b270304b2fa14362d9718c16bf20e5c6ede49abfa7fe5fc5326b9f598d592d402203b32fda981ead1df35aebc1eca9b4766555dd2f200538f6b3d62d6ccc5180aa7"
}

24
tests/lib/test_coins.py Normal file
View File

@ -0,0 +1,24 @@
import electrumx.lib.coins as coins
def test_bitcoin_cash():
raw_header = bytes.fromhex(
"00000020df975c121dcbc18bbb7ddfd0419fc368b45db86b48c87e0"
"1000000000000000036ae3dd40a10a40d3050de13ca546a2f81589d"
"e2d2f317925a43a115437e2381f5bf535b94da0118ac8df8c5"
)
height = 540000
electrum_header = {
'block_height': 540000,
'version': 536870912,
'prev_block_hash':
'0000000000000000017ec8486bb85db468c39f41d0df7dbb8bc1cb1d125c97df',
'merkle_root':
'81237e4315a1435a9217f3d2e29d58812f6a54ca13de50300da4100ad43dae36',
'timestamp': 1532215285,
'bits': 402774676,
'nonce': 3321400748
}
assert coins.BitcoinCash.electrum_header(
raw_header, height) == electrum_header