Browse Source

Allow custom Daemon and BlockProcessor classes

master
John L. Jegutanis 8 years ago
parent
commit
a4e4f80ad7
  1. 38
      lib/coins.py
  2. 14
      server/controller.py
  3. 4
      server/mempool.py

38
lib/coins.py

@ -40,6 +40,8 @@ import lib.util as util
from lib.hash import Base58, hash160, double_sha256, hash_to_str from lib.hash import Base58, hash160, double_sha256, hash_to_str
from lib.script import ScriptPubKey from lib.script import ScriptPubKey
from lib.tx import Deserializer, DeserializerSegWit, DeserializerAuxPow, DeserializerZcash from lib.tx import Deserializer, DeserializerSegWit, DeserializerAuxPow, DeserializerZcash
from server.block_processor import BlockProcessor
from server.daemon import Daemon
Block = namedtuple("Block", "header transactions") Block = namedtuple("Block", "header transactions")
@ -56,12 +58,15 @@ class Coin(object):
RPC_URL_REGEX = re.compile('.+@(\[[0-9a-fA-F:]+\]|[^:]+)(:[0-9]+)?') RPC_URL_REGEX = re.compile('.+@(\[[0-9a-fA-F:]+\]|[^:]+)(:[0-9]+)?')
VALUE_PER_COIN = 100000000 VALUE_PER_COIN = 100000000
CHUNK_SIZE = 2016 CHUNK_SIZE = 2016
HASHX_LEN = 11
BASIC_HEADER_SIZE = 80 BASIC_HEADER_SIZE = 80
STATIC_BLOCK_HEADERS = True STATIC_BLOCK_HEADERS = True
DESERIALIZER = Deserializer
DAEMON = Daemon
BLOCK_PROCESSOR = BlockProcessor
IRC_PREFIX = None IRC_PREFIX = None
IRC_SERVER = "irc.freenode.net" IRC_SERVER = "irc.freenode.net"
IRC_PORT = 6667 IRC_PORT = 6667
HASHX_LEN = 11
# Peer discovery # Peer discovery
PEER_DEFAULT_PORTS = {'t': '50001', 's': '50002'} PEER_DEFAULT_PORTS = {'t': '50001', 's': '50002'}
PEERS = [] PEERS = []
@ -261,8 +266,7 @@ class Coin(object):
'''Returns (header, [(deserialized_tx, tx_hash), ...]) given a '''Returns (header, [(deserialized_tx, tx_hash), ...]) given a
block and its height.''' block and its height.'''
header = cls.block_header(block, height) header = cls.block_header(block, height)
deserializer = cls.deserializer() txs = cls.DESERIALIZER(block[len(header):]).read_tx_block()
txs = deserializer(block[len(header):]).read_tx_block()
return Block(header, txs) return Block(header, txs)
@classmethod @classmethod
@ -289,15 +293,13 @@ class Coin(object):
'nonce': nonce, 'nonce': nonce,
} }
@classmethod
def deserializer(cls):
return Deserializer
class CoinAuxPow(Coin): class CoinAuxPow(Coin):
# Set NAME and NET to avoid exception in Coin::lookup_coin_class # Set NAME and NET to avoid exception in Coin::lookup_coin_class
NAME = '' NAME = ''
NET = '' NET = ''
STATIC_BLOCK_HEADERS = False STATIC_BLOCK_HEADERS = False
DESERIALIZER = DeserializerAuxPow
@classmethod @classmethod
def header_hash(cls, header): def header_hash(cls, header):
@ -307,7 +309,7 @@ class CoinAuxPow(Coin):
@classmethod @classmethod
def block_header(cls, block, height): def block_header(cls, block, height):
'''Return the AuxPow block header bytes''' '''Return the AuxPow block header bytes'''
block = DeserializerAuxPow(block) block = cls.DESERIALIZER(block)
return block.read_header(height, cls.BASIC_HEADER_SIZE) return block.read_header(height, cls.BASIC_HEADER_SIZE)
@ -382,10 +384,7 @@ class BitcoinTestnetSegWit(BitcoinTestnet):
bitcoind on testnet, you must use this class as your "COIN". bitcoind on testnet, you must use this class as your "COIN".
''' '''
NET = "testnet-segwit" NET = "testnet-segwit"
DESERIALIZER = DeserializerSegWit
@classmethod
def deserializer(cls):
return DeserializerSegWit
class BitcoinNolnet(Bitcoin): class BitcoinNolnet(Bitcoin):
@ -417,6 +416,7 @@ class Litecoin(Coin):
WIF_BYTE = bytes.fromhex("b0") WIF_BYTE = bytes.fromhex("b0")
GENESIS_HASH = ('12a765e31ffd4059bada1e25190f6e98' GENESIS_HASH = ('12a765e31ffd4059bada1e25190f6e98'
'c99d9714d334efa41a195a7e7e04bfe2') 'c99d9714d334efa41a195a7e7e04bfe2')
DESERIALIZER = DeserializerSegWit
TX_COUNT = 8908766 TX_COUNT = 8908766
TX_COUNT_HEIGHT = 1105256 TX_COUNT_HEIGHT = 1105256
TX_PER_BLOCK = 10 TX_PER_BLOCK = 10
@ -433,10 +433,6 @@ class Litecoin(Coin):
'eywr5eubdbbe2laq.onion s50008 t50007', 'eywr5eubdbbe2laq.onion s50008 t50007',
] ]
@classmethod
def deserializer(cls):
return DeserializerSegWit
class LitecoinTestnet(Litecoin): class LitecoinTestnet(Litecoin):
SHORTNAME = "XLT" SHORTNAME = "XLT"
@ -505,10 +501,7 @@ class ViacoinTestnet(Viacoin):
class ViacoinTestnetSegWit(ViacoinTestnet): class ViacoinTestnetSegWit(ViacoinTestnet):
NET = "testnet-segwit" NET = "testnet-segwit"
DESERIALIZER = DeserializerSegWit
@classmethod
def deserializer(cls):
return DeserializerSegWit
# Source: namecoin.org # Source: namecoin.org
@ -756,6 +749,7 @@ class Zcash(Coin):
'd06b4a8a5c453883c000b031973dce08') 'd06b4a8a5c453883c000b031973dce08')
STATIC_BLOCK_HEADERS = False STATIC_BLOCK_HEADERS = False
BASIC_HEADER_SIZE = 140 # Excluding Equihash solution BASIC_HEADER_SIZE = 140 # Excluding Equihash solution
DESERIALIZER = DeserializerZcash
TX_COUNT = 329196 TX_COUNT = 329196
TX_COUNT_HEIGHT = 68379 TX_COUNT_HEIGHT = 68379
TX_PER_BLOCK = 5 TX_PER_BLOCK = 5
@ -782,13 +776,9 @@ class Zcash(Coin):
@classmethod @classmethod
def block_header(cls, block, height): def block_header(cls, block, height):
'''Return the block header bytes''' '''Return the block header bytes'''
block = DeserializerZcash(block) block = cls.DESERIALIZER(block)
return block.read_header(height, cls.BASIC_HEADER_SIZE) return block.read_header(height, cls.BASIC_HEADER_SIZE)
@classmethod
def deserializer(cls):
return DeserializerZcash
class Einsteinium(Coin): class Einsteinium(Coin):
NAME = "Einsteinium" NAME = "Einsteinium"

14
server/controller.py

@ -9,10 +9,8 @@ import asyncio
import json import json
import os import os
import ssl import ssl
import random
import time import time
import traceback import traceback
import warnings
from bisect import bisect_left from bisect import bisect_left
from collections import defaultdict from collections import defaultdict
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
@ -20,12 +18,11 @@ from functools import partial
import pylru import pylru
from lib.jsonrpc import JSONRPC, JSONSessionBase, RPCError from lib.jsonrpc import JSONSessionBase, RPCError
from lib.hash import double_sha256, hash_to_str, hex_str_to_hash from lib.hash import double_sha256, hash_to_str, hex_str_to_hash
from lib.peer import Peer from lib.peer import Peer
import lib.util as util import lib.util as util
from server.block_processor import BlockProcessor from server.daemon import DaemonError
from server.daemon import Daemon, DaemonError
from server.mempool import MemPool from server.mempool import MemPool
from server.peers import PeerManager from server.peers import PeerManager
from server.session import LocalRPC, ElectrumX from server.session import LocalRPC, ElectrumX
@ -50,8 +47,8 @@ class Controller(util.LoggedClass):
self.loop.set_default_executor(self.executor) self.loop.set_default_executor(self.executor)
self.start_time = time.time() self.start_time = time.time()
self.coin = env.coin self.coin = env.coin
self.daemon = Daemon(env.coin.daemon_urls(env.daemon_url)) self.daemon = self.coin.DAEMON(env.coin.daemon_urls(env.daemon_url))
self.bp = BlockProcessor(env, self, self.daemon) self.bp = self.coin.BLOCK_PROCESSOR(env, self, self.daemon)
self.mempool = MemPool(self.bp, self) self.mempool = MemPool(self.bp, self)
self.peer_mgr = PeerManager(env, self) self.peer_mgr = PeerManager(env, self)
self.env = env self.env = env
@ -864,8 +861,7 @@ class Controller(util.LoggedClass):
if not raw_tx: if not raw_tx:
return None return None
raw_tx = bytes.fromhex(raw_tx) raw_tx = bytes.fromhex(raw_tx)
deserializer = self.coin.deserializer() tx, tx_hash = self.coin.DESERIALIZER(raw_tx).read_tx()
tx, tx_hash = deserializer(raw_tx).read_tx()
if index >= len(tx.outputs): if index >= len(tx.outputs):
return None return None
return self.coin.address_from_script(tx.outputs[index].pk_script) return self.coin.address_from_script(tx.outputs[index].pk_script)

4
server/mempool.py

@ -198,7 +198,7 @@ class MemPool(util.LoggedClass):
not depend on the result remaining the same are fine. not depend on the result remaining the same are fine.
''' '''
script_hashX = self.coin.hashX_from_script script_hashX = self.coin.hashX_from_script
deserializer = self.coin.deserializer() deserializer = self.coin.DESERIALIZER
db_utxo_lookup = self.db.db_utxo_lookup db_utxo_lookup = self.db.db_utxo_lookup
txs = self.txs txs = self.txs
@ -270,7 +270,7 @@ class MemPool(util.LoggedClass):
if hashX not in self.hashXs: if hashX not in self.hashXs:
return [] return []
deserializer = self.coin.deserializer() deserializer = self.coin.DESERIALIZER
hex_hashes = self.hashXs[hashX] hex_hashes = self.hashXs[hashX]
raw_txs = await self.daemon.getrawtransactions(hex_hashes) raw_txs = await self.daemon.getrawtransactions(hex_hashes)
result = [] result = []

Loading…
Cancel
Save