Add SmartCash Support (#640)
This commit is contained in:
parent
cf92ece302
commit
acd414460b
@ -36,6 +36,7 @@ install:
|
|||||||
- pip install groestlcoin_hash
|
- pip install groestlcoin_hash
|
||||||
- pip install git+https://github.com/goacoincore/neoscrypt
|
- pip install git+https://github.com/goacoincore/neoscrypt
|
||||||
- pip install git+https://github.com/motioncrypto/x16r_hash
|
- pip install git+https://github.com/motioncrypto/x16r_hash
|
||||||
|
- pip install pycryptodomex
|
||||||
# command to run tests
|
# command to run tests
|
||||||
script:
|
script:
|
||||||
- pytest --cov=electrumx
|
- pytest --cov=electrumx
|
||||||
|
|||||||
@ -45,7 +45,8 @@ from electrumx.lib.script import ScriptPubKey, OpCodes
|
|||||||
import electrumx.lib.tx as lib_tx
|
import electrumx.lib.tx as lib_tx
|
||||||
import electrumx.server.block_processor as block_proc
|
import electrumx.server.block_processor as block_proc
|
||||||
import electrumx.server.daemon as daemon
|
import electrumx.server.daemon as daemon
|
||||||
from electrumx.server.session import ElectrumX, DashElectrumX
|
from electrumx.server.session import (ElectrumX, DashElectrumX,
|
||||||
|
SmartCashElectrumX)
|
||||||
|
|
||||||
|
|
||||||
Block = namedtuple("Block", "raw header transactions")
|
Block = namedtuple("Block", "raw header transactions")
|
||||||
@ -2300,3 +2301,32 @@ class CivXTestnet(CivX):
|
|||||||
return double_sha256(header)
|
return double_sha256(header)
|
||||||
else:
|
else:
|
||||||
return hex_str_to_hash(CivXTestnet.GENESIS_HASH)
|
return hex_str_to_hash(CivXTestnet.GENESIS_HASH)
|
||||||
|
|
||||||
|
|
||||||
|
class SmartCash(Coin):
|
||||||
|
NAME = "SmartCash"
|
||||||
|
SHORTNAME = "SMART"
|
||||||
|
NET = "mainnet"
|
||||||
|
P2PKH_VERBYTE = bytes.fromhex("3f")
|
||||||
|
P2SH_VERBYTES = [bytes.fromhex("12")]
|
||||||
|
WIF_BYTE = bytes.fromhex("bf")
|
||||||
|
GENESIS_HASH = ('000007acc6970b812948d14ea5a0a13d'
|
||||||
|
'b0fdd07d5047c7e69101fa8b361e05a4')
|
||||||
|
DESERIALIZER = lib_tx.DeserializerSmartCash
|
||||||
|
RPC_PORT = 9679
|
||||||
|
REORG_LIMIT = 5000
|
||||||
|
TX_COUNT = 1115016
|
||||||
|
TX_COUNT_HEIGHT = 541656
|
||||||
|
TX_PER_BLOCK = 1
|
||||||
|
ENCODE_CHECK = partial(Base58.encode_check,
|
||||||
|
hash_fn=lib_tx.DeserializerSmartCash.keccak)
|
||||||
|
DECODE_CHECK = partial(Base58.decode_check,
|
||||||
|
hash_fn=lib_tx.DeserializerSmartCash.keccak)
|
||||||
|
HEADER_HASH = lib_tx.DeserializerSmartCash.keccak
|
||||||
|
DAEMON = daemon.SmartCashDaemon
|
||||||
|
SESSIONCLS = SmartCashElectrumX
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def header_hash(cls, header):
|
||||||
|
'''Given a header return the hash.'''
|
||||||
|
return cls.HEADER_HASH(header)
|
||||||
|
|||||||
@ -623,3 +623,18 @@ class DeserializerDecred(Deserializer):
|
|||||||
expiry,
|
expiry,
|
||||||
witness
|
witness
|
||||||
), tx_hash, self.cursor - start
|
), tx_hash, self.cursor - start
|
||||||
|
|
||||||
|
|
||||||
|
class DeserializerSmartCash(Deserializer):
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def keccak(data):
|
||||||
|
from Cryptodome.Hash import keccak
|
||||||
|
keccak_hash = keccak.new(digest_bits=256)
|
||||||
|
keccak_hash.update(data)
|
||||||
|
return keccak_hash.digest()
|
||||||
|
|
||||||
|
def read_tx_and_hash(self):
|
||||||
|
from electrumx.lib.hash import sha256
|
||||||
|
start = self.cursor
|
||||||
|
return self.read_tx(), sha256(self.binary[start:self.cursor])
|
||||||
|
|||||||
@ -457,3 +457,18 @@ class PreLegacyRPCDaemon(LegacyRPCDaemon):
|
|||||||
async def deserialised_block(self, hex_hash):
|
async def deserialised_block(self, hex_hash):
|
||||||
'''Return the deserialised block with the given hex hash.'''
|
'''Return the deserialised block with the given hex hash.'''
|
||||||
return await self._send_single('getblock', (hex_hash, False))
|
return await self._send_single('getblock', (hex_hash, False))
|
||||||
|
|
||||||
|
|
||||||
|
class SmartCashDaemon(Daemon):
|
||||||
|
|
||||||
|
async def masternode_broadcast(self, params):
|
||||||
|
'''Broadcast a smartnode to the network.'''
|
||||||
|
return await self._send_single('smartnodebroadcast', params)
|
||||||
|
|
||||||
|
async def masternode_list(self, params):
|
||||||
|
'''Return the smartnode status.'''
|
||||||
|
return await self._send_single('smartnodelist', params)
|
||||||
|
|
||||||
|
async def smartrewards(self, params):
|
||||||
|
'''Return smartrewards data.'''
|
||||||
|
return await self._send_single('smartrewards', params)
|
||||||
|
|||||||
@ -1430,3 +1430,32 @@ class DashElectrumX(ElectrumX):
|
|||||||
return [mn for mn in cache if mn['payee'] in payees]
|
return [mn for mn in cache if mn['payee'] in payees]
|
||||||
else:
|
else:
|
||||||
return cache
|
return cache
|
||||||
|
|
||||||
|
|
||||||
|
class SmartCashElectrumX(DashElectrumX):
|
||||||
|
'''A TCP server that handles incoming Electrum-SMART connections.'''
|
||||||
|
|
||||||
|
def set_request_handlers(self, ptuple):
|
||||||
|
super().set_request_handlers(ptuple)
|
||||||
|
self.request_handlers.update({
|
||||||
|
'smartrewards.current': self.smartrewards_current,
|
||||||
|
'smartrewards.check': self.smartrewards_check
|
||||||
|
})
|
||||||
|
|
||||||
|
async def smartrewards_current(self):
|
||||||
|
'''Returns the current smartrewards info.'''
|
||||||
|
result = await self.daemon_request('smartrewards', ['current'])
|
||||||
|
if result is not None:
|
||||||
|
return result
|
||||||
|
return None
|
||||||
|
|
||||||
|
async def smartrewards_check(self, addr):
|
||||||
|
'''
|
||||||
|
Returns the status of an address
|
||||||
|
|
||||||
|
addr: a single smartcash address
|
||||||
|
'''
|
||||||
|
result = await self.daemon_request('smartrewards', ['check', addr])
|
||||||
|
if result is not None:
|
||||||
|
return result
|
||||||
|
return None
|
||||||
|
|||||||
1
setup.py
1
setup.py
@ -12,6 +12,7 @@ setuptools.setup(
|
|||||||
# "blake256" package is required to sync Decred network.
|
# "blake256" package is required to sync Decred network.
|
||||||
# "xevan_hash" package is required to sync Xuez network.
|
# "xevan_hash" package is required to sync Xuez network.
|
||||||
# "groestlcoin_hash" package is required to sync Groestlcoin network.
|
# "groestlcoin_hash" package is required to sync Groestlcoin network.
|
||||||
|
# "pycryptodomex" package is required to sync SmartCash network.
|
||||||
install_requires=['aiorpcX>=0.10.1,<0.11', 'attrs',
|
install_requires=['aiorpcX>=0.10.1,<0.11', 'attrs',
|
||||||
'plyvel', 'pylru', 'aiohttp >= 2'],
|
'plyvel', 'pylru', 'aiohttp >= 2'],
|
||||||
packages=setuptools.find_packages(include=('electrumx*',)),
|
packages=setuptools.find_packages(include=('electrumx*',)),
|
||||||
|
|||||||
16
tests/blocks/smartcash_mainnet_200000.json
Normal file
16
tests/blocks/smartcash_mainnet_200000.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"hash": "000000000000d1772b7e3ffc661133c252faedcc52b3dd186b83da4b2f2f8cbe",
|
||||||
|
"size": 692,
|
||||||
|
"height": 200000,
|
||||||
|
"merkleroot": "f8f490671e499b66a73e3fe37f3b2288b82e3d359fc3c18938f32e9e830928d2",
|
||||||
|
"tx": [
|
||||||
|
"c19c6e1dd5ca9d06b046a2962782293cdd9be39bb006ce65add0ad945c9eaeec",
|
||||||
|
"0151e788a439caa317dce1cf5a754f0b5bb8639d4f1073e89d3baa450fda5306",
|
||||||
|
"a4217a9a787b66a597efae52b24e2c88d1700cf5661bac6ed58c718f90a98b97"
|
||||||
|
],
|
||||||
|
"time": 1511678597,
|
||||||
|
"nonce": 3716569074,
|
||||||
|
"bits": "1b01c757",
|
||||||
|
"previousblockhash": "0000000000016e6bcdbe8af532509cf5aaf99e74b8b0346a59d360beb460e0bf",
|
||||||
|
"block": "02000000bfe060b4be60d3596a34b0b8749ef9aaf59c5032f58abecd6b6e010000000000d22809839e2ef33889c1c39f353d2eb888223b7fe33f3ea7669b491e6790f4f885621a5a57c7011bf25786dd0301000000010000000000000000000000000000000000000000000000000000000000000000ffffffff2703400d03062f503253482f0485621a5a087ffd6961cf0000000d2f6e6f64655374726174756d2f000000000240e6202d040000001976a9145dd99e7cfdee45d47edf9b2d92df27961241145e88ac40412d574f0000001976a9144a7018841fc6003d66b6a1b859e73b4cc3e621b488ac0000000001000000019521d2cde436c42b81158198b2cd8b9d52dc093d4f8465163ecc98a134dd12a6000000006b483045022100ddad79fd8a9fa0ca664ac8e91aa7c8dcc7cad8c4894e1a7d9143de4bdedeef9f022013dfd0605b50d22d2675e21a27255540fa48263ab44801d287a61883ee8074c3012103635fd7668414f4eb1d6088cac789e58709cae9c3c07a00791f415164b67cda4cffffffff0281c03b9e000000001976a9141dc91417504cb86ac5eea49d85a4d3fd51f72db988acbc91e5cb000000001976a914ecdccf8dec8482314050acd84f72d6559a19b30d88ac0000000001000000011a8b6c07eb61bb5e9910de4d31a410a5b69de2bde8a3cb9df599ddaccd373d95000000006c493046022100d1bf91d45a0d53bfad9aa0d226be625f667641fa53661e2cdc21526cf84ede21022100d0cbf38220d789c9b1a5c6288ebfe2e5ddd4ceb5714881d0f43a27d06a6e9649012103133678a3c4d9855f4a25ab318619fe68e0ed67d67c14fa9be678cb561a75f71bffffffff027fd500fc000000001976a914098cd3573bcca56674eb6eeb51fad42ff353945088ac58bda83d000000001976a91456feb1c72217b8f45aa4183da1c81b314a47f5f388ac00000000"
|
||||||
|
}
|
||||||
@ -67,6 +67,8 @@ addresses = [
|
|||||||
"ab72728952c06dfc0f6cf21449dd645422731ec4", "eb3a3155215538d51de7cc"),
|
"ab72728952c06dfc0f6cf21449dd645422731ec4", "eb3a3155215538d51de7cc"),
|
||||||
(coins.TokenPay, "TDE2X28FGtckatxuP3d8s3V726G4TLNHpT",
|
(coins.TokenPay, "TDE2X28FGtckatxuP3d8s3V726G4TLNHpT",
|
||||||
"23b5dd9b7b402388c7a40bc88c261f3178acf30d", "7c7bdf0e0713f3752f4b88"),
|
"23b5dd9b7b402388c7a40bc88c261f3178acf30d", "7c7bdf0e0713f3752f4b88"),
|
||||||
|
(coins.SmartCash, "SQFDM9NtRRmpHebq3H5RA3qpGJfGqp8Xgw",
|
||||||
|
"206168f5322583ff37f8e55665a4789ae8963532", "b8cb80b26e8932f5b12a7e"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user