Files
stacks-puppet-node/blockstack_registrar/tools/namespace_state.py
2017-01-17 11:16:19 -05:00

631 lines
16 KiB
Python
Executable File

# -*- coding: utf-8 -*-
"""
Registrar
~~~~~
:copyright: (c) 2014-2016 by Halfmoon Labs, Inc.
:copyright: (c) 2016 blockstack.org
:license: MIT, see LICENSE for more details.
"""
import json
from time import sleep
from pymongo import MongoClient
from pybitcoin import hex_hash160, address_to_new_cryptocurrency
from pybitcoin.rpc import NamecoindClient
from pybitcoin.rpc.namecoind_cluster import check_address
from registrar.nameops import process_user, update_name, register_name
from registrar.nameops import get_namecoind
from registrar.transfer import transfer_name, nameTransferred
from registrar.config import NAMECOIND_PORT, NAMECOIND_USER, NAMECOIND_PASSWD
from registrar.config import NAMECOIND_USE_HTTPS, NAMECOIND_SERVER
from registrar.config import NAMECOIND_WALLET_PASSPHRASE
from registrar.config import MONGODB_URI, OLD_DB, AWSDB_URI, MONGOLAB_URI
from registrar.config import IGNORE_USERNAMES
namecoind = NamecoindClient(NAMECOIND_SERVER, NAMECOIND_PORT,
NAMECOIND_USER, NAMECOIND_PASSWD,
NAMECOIND_WALLET_PASSPHRASE, NAMECOIND_USE_HTTPS)
# -----------------------------------
remote_db = MongoClient(MONGODB_URI).get_default_database()
users = remote_db.user
old_db = MongoClient(OLD_DB).get_default_database()
old_users = old_db.user
c = MongoClient()
namespace_db = c['namespace']
nmc_state = namespace_db.nmc_state
registrar_state = namespace_db.registrar_state
btc_state = namespace_db.btc_state
btc_state_diff = namespace_db.btc_state_diff
btc_state_diff_2 = namespace_db.btc_state_diff_2
nmc_state.ensure_index('username')
registrar_state.ensure_index('username')
migration_db = c['migration']
migration_users = migration_db.migration_users
def get_hash(profile):
if type(profile) is not dict:
try:
print "WARNING: converting to json"
profile = json.loads(profile)
except:
print "WARNING: not valid json"
return hex_hash160(json.dumps(profile, sort_keys=True))
def fix_db():
c = MongoClient()
db = c['namespace']
print db.collection_names()
#print db.drop_collection('btc_state')
def create_test_namespace():
reply = namecoind.name_filter('u/', 200)
counter = 0
namespace = []
for entry in reply:
username = entry['name'].lstrip('u/')
if len(username) > 30:
continue
counter += 1
if counter >= 100:
break
new_entry = {}
new_entry['username'] = username
profile = namecoind.get_full_profile('u/' + username)
print username
print profile
new_entry['hash'] = hex_hash160(json.dumps(profile))
print new_entry['hash']
namespace.append(new_entry)
fout = open('output_file.txt', 'w')
fout.write(json.dumps(namespace))
print counter
print namespace
def check_test_namespace():
fin = open('namespace_test4.json', 'r')
namespace_file = json.loads(fin.read())
namespace = []
for entry in namespace_file:
profile = entry['profile']
test_hash = get_hash(profile)
if test_hash != entry['profile_hash']:
print "oops"
else:
print test_hash
print entry['profile_hash']
#new_entry = {}
#new_entry['username'] = entry['username']
#username = entry['username']
#profile = namecoind.get_full_profile('u/' + username)
#print json.dumps(profile)
#data = namecoind.name_show('u/' + username)
#nmc_address = data['address']
#print nmc_address
#print '-' * 5
#new_entry['profile'] = profile
#profile_hash = hex_hash160(json.dumps(profile))
#new_entry['hash'] = profile_hash
#new_entry['nmc_address'] = nmc_address
#namespace.append(new_entry)
#fout = open('output_file.txt', 'w')
#fout.write(json.dumps(namespace))
def check_total_users_in_states():
print "Total users nmc state: %s" % nmc_state.count()
print "Total users registrar state: %s" % registrar_state.count()
print "Total users btc state: %s" % btc_state.count()
def fix_nmc_state():
for entry in nmc_state.find():
if 'nmc_address' not in entry:
resp = namecoind.name_show('u/' + entry['username'])
if 'code' in resp:
nmc_state.remove(entry)
def create_migration_state():
for entry in migration_users.find():
check_entry = btc_state.find_one({"username": entry['username']})
if check_entry is not None:
print "%s already in btc_state" % entry['username']
continue
new_entry = {}
new_entry['username'] = entry['username']
new_entry['btc_address'] = entry['btc_address']
new_entry['profile'] = entry['profile']
new_entry['profile_hash'] = entry['profile_hash']
btc_state.insert(new_entry)
for entry in registrar_state.find():
check_entry = btc_state.find_one({"username": entry['username']})
if check_entry is not None:
print "%s already in btc_state" % entry['username']
continue
if 'needsTransfer' in entry and entry['needsTransfer'] is True:
new_entry = {}
new_entry['username'] = entry['username']
new_entry['btc_address'] = address_to_new_cryptocurrency(str(entry['nmc_address']), 0)
new_entry['profile'] = entry['profile']
new_entry['profile_hash'] = get_hash(entry['profile'])
btc_state.insert(new_entry)
for entry in nmc_state.find():
check_entry = btc_state.find_one({"username": entry['username']})
if check_entry is not None:
print "%s already in btc_state" % entry['username']
continue
if 'reservedByOnename' in entry and entry['reservedByOnename'] is False:
try:
new_entry = {}
new_entry['username'] = entry['username']
resp = namecoind.name_show('u/' + entry['username'])
new_entry['btc_address'] = address_to_new_cryptocurrency(str(entry['nmc_address']), 0)
new_entry['profile'] = entry['profile']
new_entry['profile_hash'] = entry['profile_hash']
except:
print "ERROR"
print entry
else:
btc_state.insert(new_entry)
else:
print entry
def get_reserved_usernames():
resp = namecoind.name_filter('u/')
counter = 0
for entry in resp:
new_entry = {}
try:
profile = json.loads(entry['value'])
except:
profile = entry['value']
if 'message' in profile:
print entry['name']
print profile
print '-' * 5
new_entry['username'] = entry['name'].lstrip('u/')
new_entry['profile'] = profile
migration_users.insert(new_entry)
counter += 1
print counter
def build_nmc_state():
namecoind = NamecoindClient('named8')
resp = namecoind.name_filter('u/')
counter = 0
for entry in resp:
counter += 1
print counter
new_entry = {}
new_entry['username'] = entry['name'].lstrip('u/')
profile = entry['value']
new_entry['profile'] = profile
if 'message' in profile:
new_entry['reservedByOnename'] = True
else:
new_entry['reservedByOnename'] = False
nmc_state.insert(new_entry)
print counter
def process_nmc_state():
counter = 0
# convert profile to json
for entry in nmc_state.find():
if type(entry['profile']) is not dict:
try:
profile = json.loads(entry['profile'])
nmc_state.save(entry)
except:
pass
# mark if profile is valid
for entry in nmc_state.find():
if type(entry['profile']) is not dict:
entry['profileIsValid'] = False
else:
entry['profileIsValid'] = True
nmc_state.save(entry)
# pull full profiles for entries with next keys
for entry in nmc_state.find():
if entry['profileIsValid']:
if 'next' in entry['profile']:
counter += 1
print counter
profile = namecoind.get_full_profile('u/' + entry['username'])
entry['full_profile'] = profile
nmc_state.save(entry)
# replace profiles with full profiles
for entry in nmc_state.find():
if entry['profileIsValid']:
if 'next' in entry['profile']:
# check if full_profile was fetched properly
USE_FULL_PROFILE = False
if len(json.dumps(entry['full_profile'])) >= len(json.dumps(entry['profile'])):
USE_FULL_PROFILE = True
else:
if 'code' not in entry['full_profile']:
USE_FULL_PROFILE = True
if USE_FULL_PROFILE:
entry['profile'] = entry['full_profile']
del entry['full_profile']
nmc_state.save(entry)
# save profile hash
for entry in nmc_state.find():
entry['profile_hash'] = get_hash(entry['profile'])
nmc_state.save(entry)
counter = 0
# save nmc owner address
for entry in nmc_state.find():
resp = namecoind.name_show('u/' + entry['username'])
if 'address' in resp:
entry['nmc_address'] = resp['address']
nmc_state.save(entry)
counter += 1
print counter
def temp_process_nmc_state():
return
def build_registrar_state():
counter_users = 0
for entry in users.find():
new_entry = {}
new_entry['username'] = entry['username']
new_entry['profile'] = entry['profile']
new_entry['nmc_address'] = entry['namecoin_address']
registrar_state.insert(new_entry)
counter_users += 1
if counter_users % 10 == 0:
print counter_users
counter_old_users = 0
for entry in old_users.find():
check_entry = users.find_one({'username': entry['username']})
if check_entry is None:
new_entry = {}
new_entry['username'] = entry['username']
new_entry['profile'] = entry['profile']
new_entry['nmc_address'] = entry['namecoin_address']
registrar_state.insert(new_entry)
counter_old_users += 1
if counter_old_users % 10 == 0:
print counter_old_users
#print users.count()
#print old_users.count()
print counter_users
print counter_old_users
print registrar_state.count()
def process_registrar_state():
for entry in registrar_state.find():
entry['profile_hash'] = get_hash(entry['profile'])
registrar_state.save(entry)
def compare_states():
counter_not_registered = 0
# check if registrar has pending registrations
for entry in registrar_state.find():
check_entry = nmc_state.find_one({"username": entry['username']})
if check_entry is None:
# special case: remove the junk bitcoin addresses
if len(entry['username']) == 34:
print entry['username']
#registrar_state.remove(entry)
counter_not_registered += 1
print "Not registered on nmc: %s" % counter_not_registered
# check if registrar's view matches nmc
counter_profile_data_mismatch = 0
counter_send_profile_update = 0
for entry in registrar_state.find(timeout=False):
nmc_entry = nmc_state.find_one({"username": entry['username']})
if nmc_entry is None:
continue
if entry['profile_hash'] != nmc_entry['profile_hash']:
#print entry['username']
counter_profile_data_mismatch += 1
if 'needsTransfer' in entry and entry['needsTransfer'] is True:
counter_send_profile_update += 1
if entry['username'] in IGNORE_USERNAMES:
continue
else:
user = users.find_one({"username": entry['username']})
print user['username']
try:
process_user(user['username'], user['profile'], new_address=user['namecoin_address'])
except Exception as e:
print e
print "Profile hash mismatch: %s" % counter_profile_data_mismatch
print "Registrar profiles to update: %s" % counter_send_profile_update
def check_ownership_state():
counter_needs_transfer = 0
counter_transferred = 0
for entry in registrar_state.find():
nmc_entry = nmc_state.find_one({"username": entry['username']})
if nmc_entry is None:
continue
if nmc_entry['nmc_address'] != entry['nmc_address']:
print entry['username']
counter_needs_transfer += 1
else:
counter_transferred += 1
print counter_needs_transfer
print counter_transferred
def check_transfer_state():
from registrar.config import SERVER_FLEET, IGNORE_USERNAMES
servers = SERVER_FLEET
counter = 0
for entry in registrar_state.find(timeout=False):
counter += 1
#print counter
nmc_entry = nmc_state.find_one({"username": entry['username']})
if nmc_entry is None:
continue
if 'needsTransfer' in entry and entry['needsTransfer'] is True:
continue
if nmc_entry['nmc_address'] != entry['nmc_address']:
server_counter = 0
while(server_counter != len(servers)):
server = servers[server_counter]
#print server
namecoind = NamecoindClient(server)
try:
resp = namecoind.validateaddress(nmc_entry['nmc_address'])
except Exception as e:
print e
print server
server_counter += 1
sleep(3)
continue
if 'ismine' in resp and resp['ismine'] is True:
entry['needsTransfer'] = True
entry['server'] = server
#print entry
registrar_state.save(entry)
break
server_counter += 1
if server_counter == 8:
print entry['username']
#print entry['username']
#print '-' * 5
def update_transfer_state():
counter = 0
for entry in registrar_state.find():
if 'needsTransfer' in entry and entry['needsTransfer'] is True:
profile = entry['profile']
#print entry['username']
#print entry['server']
#print '-' * 5
#continue
namecoind = NamecoindClient()
try:
resp = namecoind.name_show('u/' + entry['username'])
except Exception as e:
print e
continue
current_nmc_address = resp['address']
if current_nmc_address == entry['nmc_address']:
print entry['username']
entry['needsTransfer'] = False
registrar_state.save(entry)
counter += 1
print counter
def dump_btc_state():
namespace = []
for entry in btc_state_diff_2.find():
del entry['_id']
namespace.append(entry)
print namespace
fout = open('btc_state_diff_2.txt', 'w')
fout.write(json.dumps(namespace))
fout.close()
if __name__ == '__main__':
dump_btc_state()
#update_transfer_state()
#dump_btc_state()
#check_total_users_in_states()
#create_migration_state()
#check_transfer_state()
#compare_states()
#process_registrar_state()
#process_nmc_state()