Use the new namedb state engine and pybitcoin interface to chaincom.

This commit is contained in:
Jude Nelson
2015-08-11 14:34:13 -04:00
parent f9d17287f2
commit 8a5cb7cd1e

View File

@@ -3,8 +3,22 @@
"""
Blockstore
~~~~~
:copyright: (c) 2015 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 <http://www.gnu.org/licenses/>.
"""
import argparse
@@ -24,7 +38,6 @@ from ConfigParser import SafeConfigParser
import pybitcoin
from txjsonrpc.netstring import jsonrpc
from twisted.internet import reactor
from lib import nameset as blockstore_state_engine
from lib import get_db_state
@@ -190,7 +203,7 @@ def get_utxo_provider_client():
chaincom_secret = chaincom_opts['api_key_secret']
try:
blockchain_client = ChainComClient( chaincom_id, chaincom_secret )
blockchain_client = pybitcoin.ChainComClient( chaincom_id, chaincom_secret )
return blockchain_client
except Exception, e:
@@ -226,6 +239,7 @@ class BlockstoredRPC(jsonrpc.JSONRPC):
reply['status'] = "alive"
return reply
def jsonrpc_lookup(self, name):
"""
Lookup the profile for a name.
@@ -240,118 +254,7 @@ class BlockstoredRPC(jsonrpc.JSONRPC):
else:
return name_record
def jsonrpc_put(self, key, value):
"""
Put data into the DHT. Do not put the signed
hash into the blockchain.
"""
reply = {}
try:
test_value = json.loads(value)
except Exception as e:
print e
reply['error'] = "value not JSON, not storing"
return reply
hash = pybitcoin.hash.hex_hash160(value)
test_key = hash
if key != test_key:
reply['error'] = "hash(value) doesn't match, not storing"
return reply
result = self.dht_server.set(key, value)
if result:
reply['key'] = hash
reply['result'] = True
else:
reply['result'] = False
return reply
def jsonrpc_signdata(self, name, key, value, privatekey):
"""
Given a usenrame and data, put its signed hash into the blockchain.
Follow this call up with jsonrpc_put to put it into the DHT.
"""
reply = {}
blockchain_client_inst = get_utxo_provider_client()
try:
test_value = json.loads(value)
except Exception as e:
print principale
reply['error'] = "value not JSON, not storing"
return reply
hash = pybitcoin.hash.hex_hash160(value)
test_key = hash
if key != test_key:
reply['error'] = "hash(value) doesn't match, not storing"
return reply
try:
resp = putdata_storage( str(name), str(key), str(privatekey), blockchain_client_inst, testset=True)
except:
return json_traceback()
log.debug('setsigned <%s, %s, %s>' % (name, privatekey, value))
return resp
def jsonrpc_putsigned( self, name, key, value, privatekey):
"""
Given a username and data, sign it, broadcast the signature to the blockchain,
and then if successful, put the data into the DHT.
"""
reply = self.jsonrpc_signdata( self, name, key, value, privatekey )
if reply.has_key('error'):
# error
return reply
else:
return self.jsonrpc_put( self, key, value )
def jsonrpc_get(self, key):
"""
Given a key to data, look it up and return it.
"""
return self.dht_server.get(key)
def jsonrpc_verifydata(self, name, key ):
"""
Given a username and hash, verify that the user that owns
the name has signed the hash in the blockchain.
"""
db = get_state_engine()
return verify_signed_data( name, key, db )
def jsonrpc_getverified( self, name, key ):
"""
Given a username and a hash, verify that the user that owns
the name has signed the hash in the blockchain, and if so,
return the data.
"""
reply = self.jsonrpc_verifydata( name, key )
if reply.has_key('error'):
# error
return reply
else:
return self.jsonrpc_get( self, key )
def jsonrpc_getinfo(self):
"""
"""
@@ -359,22 +262,26 @@ class BlockstoredRPC(jsonrpc.JSONRPC):
info = bitcoind.getinfo()
reply = {}
reply['blocks'] = info['blocks']
db = get_state_engine()
reply['consensus'] = db.get_current_consensus()
return reply
def jsonrpc_preorder(self, name, privatekey):
""" Preorder a name
"""
blockchain_client_inst = get_utxo_provider_client()
if blockchain_client_inst is None:
return {'error': 'Failed to connect to blockchain'}
return {"error": "Failed to connect to blockchain UTXO provider"}
db = blockstore_state_engine()
db = get_state_engine()
consensus_hash = db.get_current_consensus()
if not consensus_hash:
return {"error": "Nameset snapshot not found."}
if str(name) in db.name_records:
if db.is_name_registered( name ):
return {"error": "Name already registered"}
try:
@@ -386,17 +293,19 @@ class BlockstoredRPC(jsonrpc.JSONRPC):
return resp
def jsonrpc_register(self, name, privatekey):
""" Register a name
"""
blockchain_client_inst = get_utxo_provider_client()
if blockchain_client_inst is None:
return {'error': 'Failed to connect to blockchain'}
return {"error": "Failed to connect to blockchain UTXO provider"}
log.info("name: %s" % name)
db = blockstore_state_engine()
if str(name) in db.name_records:
db = get_state_engine()
if db.is_name_registered( name ):
return {"error": "Name already registered"}
try:
@@ -404,40 +313,48 @@ class BlockstoredRPC(jsonrpc.JSONRPC):
except:
return json_traceback()
log.debug('register <%s, %s>' % (name, privatekey))
log.debug('register/renew <%s, %s>' % (name, privatekey))
return resp
def jsonrpc_update(self, name, data, privatekey):
def jsonrpc_update(self, name, data_hash, privatekey):
"""
Update a name with new data.
"""
blockchain_client_inst = get_utxo_provider_client()
db = get_state_engine()
consensus_hash = db.get_current_consensus()
if blockchain_client_inst is None:
return {'error': 'Failed to connect to blockchain'}
return {"error": "Failed to connect to blockchain UTXO provider"}
try:
resp = update_name(str(name), str(data), str(consensus_hash), str(privatekey), blockchain_client_inst, testset=True)
resp = update_name(str(name), str(data_hash), str(consensus_hash), str(privatekey), blockchain_client_inst, testset=True)
except:
return json_traceback()
log.debug('update <%s, %s, %s>' % (name, data, privatekey))
log.debug('update <%s, %s, %s>' % (name, data_hash, privatekey))
return resp
def jsonrpc_transfer(self, name, address, privatekey):
def jsonrpc_transfer(self, name, address, keep_data, privatekey):
""" Transfer a name
"""
blockchain_client_inst = get_utxo_provider_client()
db = get_state_engine()
consensus_hash = db.get_current_consensus()
if blockchain_client_inst is None:
return {'error': 'Failed to connect to blockchain'}
return {"error": "Failed to connect to blockchain UTXO provider"}
try:
resp = transfer_name(str(name), str(address), str(privatekey), blockchain_client_inst, testset=True)
resp = transfer_name(str(name), str(address), bool(keep_data), str(consensus_hash), str(privatekey), blockchain_client_inst, testset=True)
except:
return json_traceback()
@@ -449,12 +366,28 @@ class BlockstoredRPC(jsonrpc.JSONRPC):
def jsonrpc_renew(self, name, privatekey):
""" Renew a name
"""
log.debug('renew <%s, %s>' % (name, privatekey))
# TODO
return
return self.jsonrpc_register( name, privatekey )
def jsonrpc_revoke( self, name, privatekey ):
""" Revoke a name and all of its data.
"""
blockchain_client_inst = get_utxo_provider_client()
if blockchain_client_inst is None:
return {"error": "Failed to connect to blockchain UTXO provider"}
try:
resp = revoke_name(str(name), str(privatekey), blockchain_client_inst, testset=True)
except:
return json_traceback()
log.debug("revoke <%s>" % name )
return resp
def jsonrpc_namespace_preorder( self, namespace_id, privatekey ):
"""
@@ -463,11 +396,11 @@ class BlockstoredRPC(jsonrpc.JSONRPC):
user who created the namespace can create names in it.
"""
db = blockstore_state_engine()
db = get_state_engine()
blockchain_client_inst = get_utxo_provider_client()
if blockchain_client_inst is None:
return {'error': 'Failed to connect to blockchain'}
return {"error": "Failed to connect to blockchain UTXO provider"}
consensus_hash = db.get_current_consensus()
@@ -489,7 +422,7 @@ class BlockstoredRPC(jsonrpc.JSONRPC):
blockchain_client_inst = get_utxo_provider_client()
if blockchain_client_inst is None:
return {'error': 'Failed to connect to blockchain'}
return {"error": "Failed to connect to blockchain UTXO provider"}
try:
resp = namespace_define( str(namespace_id), int(lifetime), int(base_name_cost), float(cost_decay_rate), blockchain_client_inst, testset=True )
@@ -507,7 +440,7 @@ class BlockstoredRPC(jsonrpc.JSONRPC):
blockchain_client_inst = get_utxo_provider_client()
if blockchain_client_inst is None:
return {'error': 'Failed to connect to blockchain'}
return {"error": "Failed to connect to blockchain UTXO provider"}
try:
resp = namespace_begin( str(namespace_id), str(privatekey), blockchain_client_inst, testset=True )
@@ -557,6 +490,9 @@ def run_server( foreground=False):
pid_file = get_pidfile_path()
start_block, current_block = virtualchain.get_index_range( bitcoind )
#current_block = start_block + 4
#print "\n\nStart debug run %s-%s\n\n" % (start_block, current_block)
if foreground:
command = 'twistd --pidfile=%s -noy %s' % (pid_file, tac_file)
@@ -571,13 +507,19 @@ def run_server( foreground=False):
blockstore_state_engine = get_state_engine()
virtualchain.sync_virtualchain( bitcoin_opts, current_block, blockstore_state_engine )
#print "\n\nStop debug run\n\n"
#stop_server()
#sys.exit(0)
try:
# fork the server
blockstored = subprocess.Popen( command, shell=True, preexec_fn=os.setsid)
log.info('Blockstored successfully started')
blockstored.wait()
return blockstored.returncode
except IndexError, ie:
traceback.print_exc()
@@ -663,12 +605,14 @@ def run_blockstored():
# get RPC server options
subparsers = argparser.add_subparsers(
dest='action', help='the action to be taken')
parser_server = subparsers.add_parser(
'start',
help='start the blockstored server')
parser_server.add_argument(
'--foreground', action='store_true',
help='start the blockstored server in foreground')
parser_server = subparsers.add_parser(
'stop',
help='stop the blockstored server')
@@ -685,11 +629,9 @@ def run_blockstored():
if args.foreground:
log.info('Initializing blockstored server in foreground ...')
run_server( foreground=True )
exit_status = run_server( foreground=True )
log.info("Service endpoint exited with status code %s" % exit_status )
while(1):
stay_alive = True
else:
log.info('Starting blockstored server ...')