diff --git a/blockstore/blockstore.tac b/blockstore/blockstore.tac index 1917a7204..81264b8c3 100644 --- a/blockstore/blockstore.tac +++ b/blockstore/blockstore.tac @@ -1,8 +1,24 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- """ - Blockstored tac (config) file used by Twisted for launching the server + Blockstore ~~~~~ - :copyright: (c) 2014 by Openname.org - :license: MIT, see LICENSE for more details. + copyright: (c) 2014 by Halfmoon Labs, Inc. + copyright: (c) 2015 by Blockstack.org + + This file is part of Blockstore + + Blockstore is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Blockstore is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with Blockstore. If not, see . """ #hack around absolute paths @@ -15,27 +31,44 @@ from txjsonrpc.netstring import jsonrpc from twisted.application import service, internet from twisted.internet.task import LoopingCall -from kademlia.network import Server - -from dht.storage import BlockStorage, hostname_to_ip, DEFAULT_DHT_SERVERS, DHT_SERVER_PORT -# from dht.plugin import DEFAULT_DHT_SERVERS, DHT_SERVER_PORT - -dht_server = Server(storage=BlockStorage()) -bootstrap_servers = hostname_to_ip(DEFAULT_DHT_SERVERS) -dht_server.bootstrap(bootstrap_servers) - -from blockstored import BlockstoredRPC, reindex_blockchain -from lib.config import REINDEX_FREQUENCY, RPC_SERVER_PORT - application = service.Application("blockstored") +# ------------ +# blockstore +# ------------ +from blockstored import BlockstoredRPC, reindex_blockchain +import lib.config +from lib.config import REINDEX_FREQUENCY, RPC_SERVER_PORT + factory_blockstore = jsonrpc.RPCFactory(BlockstoredRPC()) server_blockstore = internet.TCPServer(RPC_SERVER_PORT, factory_blockstore) server_blockstore.setServiceParent(application) -server_dht = internet.UDPServer(DHT_SERVER_PORT, dht_server.protocol) -server_dht.setServiceParent(application) +# ----------- +# DHT +# ----------- +from kademlia.network import Server +from dht.storage import BlockStorage, hostname_to_ip +from lib import nameset as blockstore_state_engine +import virtualchain + +virtualchain.setup_virtualchain( blockstore_state_engine ) +dht_opts = lib.config.default_dht_opts() + +if not dht_opts['disable']: + + # start up Kademlia node + dht_servers = dht_opts['servers'] + dht_port = dht_opts['port'] + + dht_server = Server(storage=BlockStorage()) + bootstrap_servers = hostname_to_ip(dht_servers) + dht_server.bootstrap(bootstrap_servers) + + server_dht = internet.UDPServer(dht_port, dht_server.protocol) + server_dht.setServiceParent(application) + lc = LoopingCall(reindex_blockchain) lc.start(REINDEX_FREQUENCY) \ No newline at end of file diff --git a/blockstore/lib/config.py b/blockstore/lib/config.py index cc771b753..d5fa6eb32 100644 --- a/blockstore/lib/config.py +++ b/blockstore/lib/config.py @@ -57,7 +57,19 @@ RPC_SERVER_PORT = 6264 """ DHT configs """ +# 3 years +STORAGE_TTL = 3 * 60 * 60 * 24 * 365 +DHT_SERVER_PORT = 6265 # blockstored default to port 6264 + +DEFAULT_DHT_SERVERS = [('dht.openname.org', DHT_SERVER_PORT), + ('dht.onename.com', DHT_SERVER_PORT), + ('dht.halfmoonlabs.com', DHT_SERVER_PORT), + ('127.0.0.1', DHT_SERVER_PORT)] + + +""" Bitcoin configs +""" DEFAULT_BITCOIND_SERVER = 'btcd.onename.com' DEFAULT_BITCOIND_PORT = 8332 DEFAULT_BITCOIND_PORT_TESTNET = 18332 @@ -305,6 +317,84 @@ def default_chaincom_opts( config_file=None ): return chaincom_opts +def default_dht_opts( config_file=None ): + """ + Get our default DHT options from the config file. + """ + + global DHT_SERVER_PORT, DEFAULT_DHT_SERVERS + + if config_file is None: + config_file = virtualchain.get_config_filename() + + + defaults = { + 'disable': str(False), + 'port': str(DHT_SERVER_PORT), + 'servers': ",".join( ["%s:%s" % (host, port) for (host, port) in DEFAULT_DHT_SERVERS] ) + } + + parser = SafeConfigParser( defaults ) + parser.read( config_file ) + + if parser.has_section('dht'): + + disable = parser.get('dht', 'disable') + port = parser.get('dht', 'port') + servers = parser.get('dht', 'servers') # expect comma-separated list of host:port + + if disable is None: + disable = False + + if port is None: + port = DHT_SERVER_PORT + + if servers is None: + servers = DEFAULT_DHT_SERVERS + + try: + disable = bool(disable) + except: + raise Exception("Invalid field value for dht.disable: expected bool") + + try: + port = int(port) + except: + raise Exception("Invalid field value for dht.port: expected int") + + parsed_servers = [] + try: + server_list = servers.split(",") + for server in server_list: + server_host, server_port = server.split(":") + server_port = int(server_port) + + parsed_servers.append( (server_host, server_port) ) + + except: + raise Exception("Invalid field value for dht.servers: expected 'HOST:PORT[,HOST:PORT...]'") + + dht_opts = { + 'disable': disable, + 'port': port, + 'servers': parsed_servers + } + + return dht_opts + + else: + + # use defaults + dht_opts = { + 'disable': False, + 'port': DHT_SERVER_PORT, + 'servers': DEFAULT_DHT_SERVERS + } + + return dht_opts + + + def opt_strip( prefix, opts ): """ Given a dict of opts that start with prefix,