diff --git a/electrumx/lib/coins.py b/electrumx/lib/coins.py index 932fd11..905b423 100644 --- a/electrumx/lib/coins.py +++ b/electrumx/lib/coins.py @@ -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('= 4: + return super().header_hash(header) + else: + import quark_hash + return quark_hash.getPoWHash(header) diff --git a/electrumx/lib/tx.py b/electrumx/lib/tx.py index 6239805..35fa419 100644 --- a/electrumx/lib/tx.py +++ b/electrumx/lib/tx.py @@ -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: diff --git a/electrumx/server/block_processor.py b/electrumx/server/block_processor.py index c9bde57..bea879e 100644 --- a/electrumx/server/block_processor.py +++ b/electrumx/server/block_processor.py @@ -411,7 +411,7 @@ class BlockProcessor(object): tx_numb = s_pack('