def __init__(self, coin=None): super().__init__() self.obsolete([ "MAX_SUBSCRIPTIONS", "MAX_SUBS", "MAX_SESSION_SUBS", "BANDWIDTH_LIMIT" ]) self.db_dir = self.required('DB_DIRECTORY') self.db_engine = self.default('DB_ENGINE', 'leveldb') self.daemon_url = self.required('DAEMON_URL') if coin is not None: assert issubclass(coin, Coin) self.coin = coin else: coin_name = self.required('COIN').strip() network = self.default('NET', 'mainnet').strip() self.coin = Coin.lookup_coin_class(coin_name, network) self.cache_MB = self.integer('CACHE_MB', 1200) self.host = self.default('HOST', 'localhost') self.reorg_limit = self.integer('REORG_LIMIT', self.coin.REORG_LIMIT) # Server stuff self.tcp_port = self.integer('TCP_PORT', None) self.ssl_port = self.integer('SSL_PORT', None) if self.ssl_port: self.ssl_certfile = self.required('SSL_CERTFILE') self.ssl_keyfile = self.required('SSL_KEYFILE') self.rpc_port = self.integer('RPC_PORT', 8000) self.banner_file = self.default('BANNER_FILE', None) self.tor_banner_file = self.default('TOR_BANNER_FILE', self.banner_file) self.anon_logs = self.boolean('ANON_LOGS', False) self.log_sessions = self.integer('LOG_SESSIONS', 3600) # Peer discovery self.peer_discovery = self.peer_discovery_enum() self.peer_announce = self.boolean('PEER_ANNOUNCE', True) self.force_proxy = self.boolean('FORCE_PROXY', False) self.tor_proxy_host = self.default('TOR_PROXY_HOST', 'localhost') self.tor_proxy_port = self.integer('TOR_PROXY_PORT', None) # The electrum client takes the empty string as unspecified self.donation_address = self.default('DONATION_ADDRESS', '') # Server limits to help prevent DoS self.max_send = self.integer('MAX_SEND', self.coin.DEFAULT_MAX_SEND) self.max_sessions = self.sane_max_sessions() self.cost_soft_limit = self.integer('COST_SOFT_LIMIT', 1000) self.cost_hard_limit = self.integer('COST_HARD_LIMIT', 10000) self.bw_unit_cost = self.integer('BANDWIDTH_UNIT_COST', 5000) self.initial_concurrent = self.integer('INITIAL_CONCURRENT', 10) self.request_sleep = self.integer('REQUEST_SLEEP', 2500) self.request_timeout = self.integer('REQUEST_TIMEOUT', 15) self.session_timeout = self.integer('SESSION_TIMEOUT', 600) self.drop_client = self.custom("DROP_CLIENT", None, re.compile) self.blacklist_url = self.default('BLACKLIST_URL', self.coin.BLACKLIST_URL) # Identities clearnet_identity = self.clearnet_identity() tor_identity = self.tor_identity(clearnet_identity) self.identities = [ identity for identity in (clearnet_identity, tor_identity) if identity is not None ]
def __init__(self, coin=None): super().__init__() self.obsolete(["MAX_SUBSCRIPTIONS", "MAX_SUBS", "MAX_SESSION_SUBS", "BANDWIDTH_LIMIT", "HOST", "TCP_PORT", "SSL_PORT", "RPC_HOST", "RPC_PORT", "REPORT_HOST", "REPORT_TCP_PORT", "REPORT_SSL_PORT", "REPORT_HOST_TOR", "REPORT_TCP_PORT_TOR", "REPORT_SSL_PORT_TOR"]) # Core items self.db_dir = self.required('DB_DIRECTORY') self.daemon_url = self.required('DAEMON_URL') coin_name = 'PricecoinX' network = 'mainnet' self.coin = Coin.lookup_coin_class(coin_name, network) # Peer discovery self.peer_discovery = self.peer_discovery_enum() self.peer_announce = self.boolean('PEER_ANNOUNCE', True) self.force_proxy = self.boolean('FORCE_PROXY', False) self.tor_proxy_host = self.default('TOR_PROXY_HOST', 'localhost') self.tor_proxy_port = self.integer('TOR_PROXY_PORT', None) # Misc self.db_engine = self.default('DB_ENGINE', 'leveldb') self.banner_file = self.default('BANNER_FILE', None) self.tor_banner_file = self.default('TOR_BANNER_FILE', self.banner_file) self.anon_logs = self.boolean('ANON_LOGS', False) self.log_sessions = self.integer('LOG_SESSIONS', 3600) self.log_level = self.default('LOG_LEVEL', 'info').upper() self.donation_address = self.default('DONATION_ADDRESS', '') self.drop_client = self.custom("DROP_CLIENT", None, re.compile) self.blacklist_url = self.default('BLACKLIST_URL', self.coin.BLACKLIST_URL) self.cache_MB = self.integer('CACHE_MB', 1200) self.reorg_limit = self.integer('REORG_LIMIT', self.coin.REORG_LIMIT) # Server limits to help prevent DoS self.max_send = self.integer('MAX_SEND', self.coin.DEFAULT_MAX_SEND) self.max_sessions = self.sane_max_sessions() self.cost_soft_limit = self.integer('COST_SOFT_LIMIT', 1000) self.cost_hard_limit = self.integer('COST_HARD_LIMIT', 10000) self.bw_unit_cost = self.integer('BANDWIDTH_UNIT_COST', 5000) self.initial_concurrent = self.integer('INITIAL_CONCURRENT', 10) self.request_sleep = self.integer('REQUEST_SLEEP', 2500) self.request_timeout = self.integer('REQUEST_TIMEOUT', 30) self.session_timeout = self.integer('SESSION_TIMEOUT', 600) # Services last - uses some env vars above self.services = self.services_to_run() if {service.protocol for service in self.services}.intersection(self.SSL_PROTOCOLS): self.ssl_certfile = self.required('SSL_CERTFILE') self.ssl_keyfile = self.required('SSL_KEYFILE') self.report_services = self.services_to_report()
def __init__(self, coin=None): super().__init__() self.obsolete(['UTXO_MB', 'HIST_MB', 'NETWORK']) self.db_dir = self.required('DB_DIRECTORY') self.db_engine = self.default('DB_ENGINE', 'leveldb') self.daemon_url = self.required('DAEMON_URL') coin_name = 'SIN' network = 'mainnet' self.coin = Coin.lookup_coin_class(coin_name, network) self.cache_MB = self.integer('CACHE_MB', 1200) self.host = self.default('HOST', 'localhost') self.reorg_limit = self.integer('REORG_LIMIT', self.coin.REORG_LIMIT) # Server stuff self.tcp_port = self.integer('TCP_PORT', None) self.ssl_port = self.integer('SSL_PORT', None) if self.ssl_port: self.ssl_certfile = self.required('SSL_CERTFILE') self.ssl_keyfile = self.required('SSL_KEYFILE') self.rpc_port = self.integer('RPC_PORT', 8000) self.max_subscriptions = self.integer('MAX_SUBSCRIPTIONS', 10000) self.banner_file = self.default('BANNER_FILE', None) self.tor_banner_file = self.default('TOR_BANNER_FILE', self.banner_file) self.anon_logs = self.boolean('ANON_LOGS', False) self.log_sessions = self.integer('LOG_SESSIONS', 3600) # Peer discovery self.peer_discovery = self.peer_discovery_enum() self.peer_announce = self.boolean('PEER_ANNOUNCE', True) self.force_proxy = self.boolean('FORCE_PROXY', False) self.tor_proxy_host = self.default('TOR_PROXY_HOST', 'localhost') self.tor_proxy_port = self.integer('TOR_PROXY_PORT', None) # The electrum client takes the empty string as unspecified self.donation_address = self.default('DONATION_ADDRESS', '') # Server limits to help prevent DoS self.max_send = self.integer('MAX_SEND', 1000000) self.max_subs = self.integer('MAX_SUBS', 250000) self.max_sessions = self.sane_max_sessions() self.max_session_subs = self.integer('MAX_SESSION_SUBS', 50000) self.bandwidth_limit = self.integer('BANDWIDTH_LIMIT', 2000000) self.session_timeout = self.integer('SESSION_TIMEOUT', 600) self.drop_client = self.custom("DROP_CLIENT", None, re.compile) # Identities clearnet_identity = self.clearnet_identity() tor_identity = self.tor_identity(clearnet_identity) self.identities = [ identity for identity in (clearnet_identity, tor_identity) if identity is not None ]
def test_transaction(transaction_details): coin, tx_info = transaction_details raw_tx = unhexlify(tx_info['hex']) tx, tx_hash = coin.DESERIALIZER(raw_tx, 0).read_tx_and_hash() assert tx_info['txid'] == hash_to_hex_str(tx_hash) vin = tx_info['vin'] for i in range(len(vin)): assert vin[i]['txid'] == hash_to_hex_str(tx.inputs[i].prev_hash) assert vin[i]['vout'] == tx.inputs[i].prev_idx vout = tx_info['vout'] for i in range(len(vout)): # value pk_script assert vout[i]['value'] == tx.outputs[i].value spk = vout[i]['scriptPubKey'] tx_pks = tx.outputs[i].pk_script assert spk['hex'] == tx_pks.hex() if "addresses" in spk: assert len(spk["addresses"]) == 1 address = spk["addresses"][0] else: address = spk["address"] assert coin.address_to_hashX(address) == coin.hashX_from_script(tx_pks) if issubclass(coin, Namecoin): if "nameOp" not in spk or "name" not in spk["nameOp"]: assert coin.name_hashX_from_script(tx_pks) is None else: OP_NAME_UPDATE = OpCodes.OP_3 normalized_name_op_script = bytearray() normalized_name_op_script.append(OP_NAME_UPDATE) normalized_name_op_script.extend( Script.push_data(spk["nameOp"]["name"].encode("ascii"))) normalized_name_op_script.extend(Script.push_data(bytes([]))) normalized_name_op_script.append(OpCodes.OP_2DROP) normalized_name_op_script.append(OpCodes.OP_DROP) normalized_name_op_script.append(OpCodes.OP_RETURN) assert coin.name_hashX_from_script( tx_pks) == Coin.hashX_from_script( normalized_name_op_script)
def _from_extended_key(ekey): '''Return a PubKey or PrivKey from an extended key raw bytes.''' if not isinstance(ekey, (bytes, bytearray)): raise TypeError('extended key must be raw bytes') if len(ekey) != 78: raise ValueError('extended key must have length 78') is_public, coin = Coin.lookup_xverbytes(ekey[:4]) depth = ekey[4] fingerprint = ekey[5:9] # Not used n, = struct.unpack('>I', ekey[9:13]) chain_code = ekey[13:45] if is_public: pubkey = ekey[45:] key = PubKey(pubkey, chain_code, n, depth) else: if ekey[45] is not 0: raise ValueError('invalid extended private key prefix byte') privkey = ekey[46:] key = PrivKey(privkey, chain_code, n, depth) return key, coin
from electrumx.lib.coins import Coin, MonetaryUnit from electrumx.lib.hash import hex_str_to_hash from electrumx.lib.util import pack_be_uint32 BLOCKS_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'blocks') # Find out which db engines to test # Those that are not installed will be skipped blocks = [] for name in os.listdir(BLOCKS_DIR): try: name_parts = name.split("_") coin = Coin.lookup_coin_class(name_parts[0], name_parts[1]) with open(os.path.join(BLOCKS_DIR, name)) as f: blocks.append((coin, json.load(f))) except Exception as e: blocks.append(pytest.fail(name)) @pytest.fixture(params=blocks) def block_details(request): return request.param def test_block(block_details): coin, block_info = block_details raw_block = unhexlify(block_info['block'])
def __init__(self, coin=None): super().__init__() self.obsolete(['UTXO_MB', 'HIST_MB', 'NETWORK']) self.db_dir = self.required('DB_DIRECTORY') self.db_engine = self.default('DB_ENGINE', 'leveldb') self.daemon_url = self.required('DAEMON_URL') if coin is not None: assert issubclass(coin, Coin) self.coin = coin else: coin_name = self.required('COIN').strip() network = self.default('NET', 'mainnet').strip() self.coin = Coin.lookup_coin_class(coin_name, network) self.cache_MB = self.integer('CACHE_MB', 1200) self.host = self.default('HOST', 'localhost') self.reorg_limit = self.integer('REORG_LIMIT', self.coin.REORG_LIMIT) # Server stuff self.tcp_port = self.integer('TCP_PORT', None) self.ssl_port = self.integer('SSL_PORT', None) if self.ssl_port: self.ssl_certfile = self.required('SSL_CERTFILE') self.ssl_keyfile = self.required('SSL_KEYFILE') self.rpc_port = self.integer('RPC_PORT', 8000) self.banner_file = self.default('BANNER_FILE', None) self.tor_banner_file = self.default('TOR_BANNER_FILE', self.banner_file) self.anon_logs = self.boolean('ANON_LOGS', False) self.log_sessions = self.integer('LOG_SESSIONS', 3600) # Peer discovery self.peer_discovery = self.peer_discovery_enum() self.peer_announce = self.boolean('PEER_ANNOUNCE', True) self.force_proxy = self.boolean('FORCE_PROXY', False) self.tor_proxy_host = self.default('TOR_PROXY_HOST', 'localhost') self.tor_proxy_port = self.integer('TOR_PROXY_PORT', None) self.peer_discovery_tor = self.peer_discovery_tor_parse() # The electrum client takes the empty string as unspecified self.donation_address = self.default('DONATION_ADDRESS', '') # Server limits to help prevent DoS self.max_send = self.integer('MAX_SEND', self.coin.DEFAULT_MAX_SEND) self.max_subs = self.integer('MAX_SUBS', 1000000) self.max_sessions = self.sane_max_sessions() self.max_sessions_per_ip = self.integer('MAX_SESSIONS_PER_IP', 50) self.max_sessions_tor = max( self.integer('MAX_SESSIONS_TOR', 1000), 10) # Require at least 10 for MAX_SESSIONS_TOR self.max_session_subs = self.integer('MAX_SESSION_SUBS', 50000) self.bandwidth_limit = self.integer('BANDWIDTH_LIMIT', 8000000) self.session_timeout = self.integer('SESSION_TIMEOUT', 600) self.drop_client = self.custom("DROP_CLIENT", None, re.compile) # Blacklist URL. Set this to the empty string in the environment if you want to disable this facility self.blacklist_url = self.default( 'BLACKLIST_URL', 'https://raw.githubusercontent.com/Electron-Cash/electronx-blacklist/master/blacklist.json' ) self.blacklist_poll_interval = self.custom( 'BLACKLIST_POLL_INTERVAL', 300, # parse as integer and limit it to >= 30 secs and <= 86400 (1 day) lambda x: (int(x) >= 30 and int(x) <= 86400 and int(x)) or 300) # If this is set, then we ban whenever an IP address has more than self.max_sessions_per_ip connections self.ban_excessive_connections = self.boolean( 'BAN_EXCESSIVE_CONNECTIONS', True) # Identities clearnet_identity = self.clearnet_identity() tor_identity = self.tor_identity(clearnet_identity) self.identities = [ identity for identity in (clearnet_identity, tor_identity) if identity is not None ]
def coin_class(self): return Coin.lookup_coin_class(self.coin, self.net)