From 93031531501cd5131fb6ec84c498e7682af12320 Mon Sep 17 00:00:00 2001 From: Sergii Vakula Date: Fri, 13 Oct 2017 04:12:24 +0300 Subject: [PATCH] Add support for Emercoin (#284) * Add parameters for emercoin. * Add tests for emercoin. * add block for test new read_header function * add to daemon https protocol support --- lib/coins.py | 41 +++++++++++++++++++++-- lib/tx.py | 36 ++++++++++++++++++++ tests/blocks/emercoin_mainnet_255544.json | 14 ++++++++ tests/blocks/emercoin_mainnet_80312.json | 15 +++++++++ tests/lib/test_addresses.py | 4 ++- 5 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 tests/blocks/emercoin_mainnet_255544.json create mode 100644 tests/blocks/emercoin_mainnet_80312.json diff --git a/lib/coins.py b/lib/coins.py index b8c8a93..989f0cc 100644 --- a/lib/coins.py +++ b/lib/coins.py @@ -40,7 +40,8 @@ import lib.util as util from lib.hash import Base58, hash160, double_sha256, hash_to_str from lib.script import ScriptPubKey, OpCodes from lib.tx import Deserializer, DeserializerSegWit, DeserializerAuxPow, \ - DeserializerZcash, DeserializerTxTime, DeserializerReddcoin + DeserializerZcash, DeserializerTxTime, DeserializerReddcoin, \ + DeserializerTxTimeAuxPow from server.block_processor import BlockProcessor import server.daemon as daemon from server.session import ElectrumX, DashElectrumX @@ -108,7 +109,7 @@ class Coin(object): raise CoinError('invalid daemon URL: "{}"'.format(url)) if match.groups()[1] is None: url += ':{:d}'.format(cls.RPC_PORT) - if not url.startswith('http://'): + if not url.startswith('http://') and not url.startswith('https://'): url = 'http://' + url return url + '/' @@ -373,6 +374,42 @@ class BitcoinSegwit(BitcoinMixin, Coin): ] +class Emercoin(Coin): + NAME = "Emercoin" + SHORTNAME = "EMC" + NET = "mainnet" + XPUB_VERBYTES = bytes.fromhex("0488b21e") + XPRV_VERBYTES = bytes.fromhex("0488ade4") + P2PKH_VERBYTE = bytes.fromhex("21") + P2SH_VERBYTES = [bytes.fromhex("5c")] + WIF_BYTE = bytes.fromhex("80") + GENESIS_HASH = ('00000000bcccd459d036a588d1008fce' + '8da3754b205736f32ddfd35350e84c2d') + TX_COUNT = 217380620 + TX_COUNT_HEIGHT = 464000 + TX_PER_BLOCK = 1700 + VALUE_PER_COIN = 1000000 + RPC_PORT = 6662 + + DESERIALIZER = DeserializerTxTimeAuxPow + + PEERS = [] + + @classmethod + def block_header(cls, block, height): + '''Returns the block header given a block and its height.''' + deserializer = cls.DESERIALIZER(block) + + if deserializer.is_merged_block(): + return deserializer.read_header(height, cls.BASIC_HEADER_SIZE) + return block[:cls.static_header_len(height)] + + @classmethod + def header_hash(cls, header): + '''Given a header return hash''' + return double_sha256(header[:cls.BASIC_HEADER_SIZE]) + + class BitcoinTestnetMixin(object): SHORTNAME = "XTN" NET = "testnet" diff --git a/lib/tx.py b/lib/tx.py index e9342c5..bbba5cd 100644 --- a/lib/tx.py +++ b/lib/tx.py @@ -335,3 +335,39 @@ class DeserializerReddcoin(Deserializer): outputs, locktime, ), double_sha256(self.binary[start:self.cursor]) + + +class DeserializerTxTimeAuxPow(DeserializerTxTime): + VERSION_AUXPOW = (1 << 8) + + def is_merged_block(self): + start = self.cursor + self.cursor = 0 + version = self._read_le_uint32() + self.cursor = start + if version & self.VERSION_AUXPOW: + return True + return False + + def read_header(self, height, static_header_size): + '''Return the AuxPow block header bytes''' + start = self.cursor + version = self._read_le_uint32() + if version & self.VERSION_AUXPOW: + # We are going to calculate the block size then read it as bytes + self.cursor = start + self.cursor += static_header_size # Block normal header + self.read_tx() # AuxPow transaction + self.cursor += 32 # Parent block hash + merkle_size = self._read_varint() + self.cursor += 32 * merkle_size # Merkle branch + self.cursor += 4 # Index + merkle_size = self._read_varint() + self.cursor += 32 * merkle_size # Chain merkle branch + self.cursor += 4 # Chain index + self.cursor += 80 # Parent block header + header_end = self.cursor + else: + header_end = static_header_size + self.cursor = start + return self._read_nbytes(header_end) diff --git a/tests/blocks/emercoin_mainnet_255544.json b/tests/blocks/emercoin_mainnet_255544.json new file mode 100644 index 0000000..cde6175 --- /dev/null +++ b/tests/blocks/emercoin_mainnet_255544.json @@ -0,0 +1,14 @@ +{ + "hash": "0106a1f3a8f9ece5e213eb6e62d9b647724b7785bdc6b51737910a13dbbc3360", + "size": 1188, + "height": 255544, + "merkleroot": "6b72c4658cbc026c758d10d8bd1e434391d2b5eacda7b92e4b14901e18f59ce0", + "tx": [ + "6b72c4658cbc026c758d10d8bd1e434391d2b5eacda7b92e4b14901e18f59ce0" + ], + "time": 1507384461, + "nonce": 0, + "bits": "1800d0a5", + "previousblockhash": "c901fae6103621bd2d946d97eb2946ef8a0d5a6f0f524716d4783c6899f9c6e4", + "block": "05019a02e4c6f999683c78d41647520f6f5a0d8aef4629eb976d942dbd213610e6fa01c9e09cf5181e90144b2eb9a7cdeab5d29143431ebdd8108d756c02bc8c65c4726b8ddcd859a5d00018000000000100000087e0d859010000000000000000000000000000000000000000000000000000000000000000ffffffff610302750741d676381fc9c77841d676381ee793a52f4254432e544f502f4e59412f4542312f4144362ffabe6d6dbbe5aa12107008a60a220800a220fd068f6430b8a531c33d0db347272dc5292e8000000000000000cd006407894e000000000000ffffffff024242554e000000001976a914ba507bae8f1643d2556000ca26b9301b9069dc6b88ac0000000000000000266a24aa21a9ed3782874124388ef2e919659287e455d702146d547b41a56d12b1b89f40cbab6200000000d9bedd194a44d85d2b4f6380bcd5e11ea80bf74706dd0d0000000000000000000bca926bdaef806e6b02edf26f327b9323db51805976b55bb2281b833d938e5f7772473fcebf7e7b4af337949ef79c02a4081b34dff892f5ff7bfa6c9e562a41b430f88d80c6f3b9a31e373494b6c936edf1b11554ca685b6587c1c10c9723f17acc5d3e584ca249f1976cd8e9a7f7ce4b3e9bcaab49f604f8a1a1085872031ad7f7033256c58640d08109746085baa7c12a0653834bea13d56190d664707f575e6b80b08ae2f16be8f1a6f9c46231a66b75e82a6dd1fd628217c17eb332c0568812be071dc9aefe18450a400d00a75702c58fa7f48126afd1bfc1c32896fd022c18671829b85dcba51377276a73b36cb8d6c11a3c0de631aebb40776b56c6767d55324d7731ea510bc02a616a1f1c42cac707ee532ff1e1bbded068681194c40e02454362bedc584b4021986ed8f6fec206f143cd579b88b8f562969bc58d2e001c300be2f3c7f7026825e386608a37b2c6af981b770b784f5771cbb4c27d3df900000000070000000000000000000000000000000000000000000000000000000000000000e2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf97d24db2bfa41474bfb2f877d688fac5faa5e10a2808cf9de307370b93352e54894857d3e08918f70395d9206410fbfa942f1a889aa5ab8188ec33c2f6e207dc7f537f8222340379c1ec62fdf65fb8a39565503229bed1f818f38eb0bf41142f0ad83a7857080ddaac962e156e92e3f07d488bc7f06ca9c070ec0daeb7370ee88cbea15ce5bbf2b83da04eaaba12a4a398f72ff5c32813ff2e489d2f1337ca3dd1000000000000020638c009db3fb62933dd2b3be4602c2513892fa53ccf4f500000000000000000025dd3d6f8d741230a4b5b1847cbb2f9dfe822fc3832989fa0d409e83418ed3507ae0d85973fa0018d8e2ffe701010000008ddcd859010000000000000000000000000000000000000000000000000000000000000000ffffffff060338e6030101ffffffff01201b4700000000002321028caf0472ca07d4534a879aeab480531a68f47753e46118986882ef33b689e788ac0000000046304402201fc3bf8154434f37627333b3b228a4dbf95bcd5fc9def51be0afd40b6b010cc7022045e327bbd7460dfece08514e699afffb54c6881f352f67b5a6e7e50f03e31a1c" +} diff --git a/tests/blocks/emercoin_mainnet_80312.json b/tests/blocks/emercoin_mainnet_80312.json new file mode 100644 index 0000000..226b880 --- /dev/null +++ b/tests/blocks/emercoin_mainnet_80312.json @@ -0,0 +1,15 @@ +{ + "hash": "a43347ea24a5318f351c99344c5302f0362becc83c0741a4952f16af99d1d1a1", + "size": 455, + "height": 80312, + "merkleroot": "4f3cd539639fcdae1746962e59c69472f276915cc8372ce4b66995aa66edaeea", + "tx": [ + "73bb705dd47369cfdacc28277f2c15ab8132e9b7e3fe8b1ccff2085aa86ab171", + "43b5c1df58c047c5744253d7deb3eca213f4a6a6292eba01bcf0a37e57b558aa" + ], + "time": 1421971102, + "nonce": 0, + "bits": "1c2fff64", + "previousblockhash": "a98bcab52484bbef6b775cefc2bf05d413c868fe08c4bd60775ca30310b7bb8a", + "block": "010000008abbb71003a35c7760bdc408fe68c813d405bfc2ef5c776befbb8424b5ca8ba9eaaeed66aa9569b6e42c37c85c9176f27294c6592e964617aecd9f6339d53c4f9e8ec15464ff2f1c0000000002010000009e8ec154010000000000000000000000000000000000000000000000000000000000000000ffffffff0f049e8ec15402e200062f503253482fffffffff0100000000000000000000000000010000009e8ec154012dc1ac382b63ae8643661e09d6cd4000860ef347089dc32a8a54faa2dda730270100000048473044022077f8529c99913589961bb5934ea2dcba8ee3229b220e53c29d0003d80eaf8f99022071d331d092c8c69f114ee9676f2f22134e6515bf178c58aef422eebf629f5bb601ffffffff030000000000000000001097237b000000002321035f85c7b5fca2dbb7b92d3c37fd17d785e7a667fa7a061eda9136afde92160dcbac1097237b000000002321035f85c7b5fca2dbb7b92d3c37fd17d785e7a667fa7a061eda9136afde92160dcbac0000000046304402202c23574792d538607f718066a0d7aa4d373c39b80b1191d70b30e4993fe5a52a022078b4614c56b921d811065baf149476f3d9c3c49b3c66ee12cf2c4636cf0e74d8" +} diff --git a/tests/lib/test_addresses.py b/tests/lib/test_addresses.py index 9fceac1..e832f04 100644 --- a/tests/lib/test_addresses.py +++ b/tests/lib/test_addresses.py @@ -26,7 +26,7 @@ import pytest -from lib.coins import Litecoin, BitcoinCash, Zcash +from lib.coins import Litecoin, BitcoinCash, Zcash, Emercoin from lib.hash import Base58 addresses = [ @@ -34,6 +34,8 @@ addresses = [ "206168f5322583ff37f8e55665a4789ae8963532", "b8cb80b26e8932f5b12a7e"), (BitcoinCash, "3GxRZWkJufR5XA8hnNJgQ2gkASSheoBcmW", "a773db925b09add367dcc253c1f9bbc1d11ec6fd", "062d8515e50cb92b8a3a73"), + (Emercoin, "ELAeVHQg2mmdTTrTrZSzMgAQyXfC9TSRys", + "210c4482ad8eacb0d349992973608300677adb15", "d71f2df4ef1b397088d731"), (Litecoin, "LNBAaWuZmipg29WXfz5dtAm1pjo8FEH8yg", "206168f5322583ff37f8e55665a4789ae8963532", "b8cb80b26e8932f5b12a7e"), (Litecoin, "MPAZsQAGrnGWKfQbtFJ2Dfw9V939e7D3E2",