mirror of
https://github.com/alexgo-io/stacks-puppet-node.git
synced 2026-06-16 09:43:45 +08:00
Use the new namedb state engine and pybitcoin interface to chaincom.
This commit is contained in:
@@ -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 ...')
|
||||
|
||||
Reference in New Issue
Block a user