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

501 lines
13 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 os
import json
import requests
from time import sleep
from pymongo import MongoClient
from pybitcoin import hex_hash160, address_to_new_cryptocurrency
from pybitcoin import BitcoinPrivateKey, NamecoinPrivateKey
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, transfer_key
from tools.bip38 import bip38_encrypt
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 FRONTEND_SECRET
from tools.misc import process_manually
from tools.sweep_btc import sweep_btc
from tools.misc import import_update
from tools.crypto_tools import aes_encrypt, aes_decrypt, get_addresses_from_privkey
from tools.namespace_state import get_hash
from tools.namespace_diff import insert_state_diff as insert_btc_diff
from registrar.config import SERVER_FLEET
from pybitcoin.rpc.namecoind_cluster import pending_transactions
namecoind = NamecoindClient(NAMECOIND_SERVER, NAMECOIND_PORT,
NAMECOIND_USER, NAMECOIND_PASSWD,
NAMECOIND_WALLET_PASSPHRASE, NAMECOIND_USE_HTTPS)
SECRET_KEY = os.environ['SECRET_KEY']
# -----------------------------------
remote_db = MongoClient(MONGODB_URI).get_default_database()
users = remote_db.user
registrations = remote_db.user_registration
updates = remote_db.profile_update
transfer = remote_db.name_transfer
old_db = MongoClient(OLD_DB).get_default_database()
old_users = old_db.user
aws_db = MongoClient(AWSDB_URI)['blockdata']
skip_users = aws_db.skip_users
pending_users = aws_db.pending_users
c = MongoClient()
migration_db = c['migration']
migration_users = migration_db.migration_users
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
def update_migration_users():
for user in migration_users.find():
resp = namecoind.name_show('u/' + user['username'])
if 'address' in resp:
nmc_address = resp['address']
if nmc_address != user['nmc_address']:
try:
process_user(user['username'], user['profile'], new_address=user['nmc_address'])
except Exception as e:
print e
def add_migration_user(username, profile):
check_entry = migration_users.find_one({"username": username})
if check_entry is not None:
print "already in migration DB"
return
new_entry = {}
new_entry['username'] = username
new_entry['profile'] = profile
new_entry['profile_hash'] = get_hash(profile)
privkey = BitcoinPrivateKey()
hex_privkey = privkey.to_hex()
new_entry['encrypted_privkey'] = aes_encrypt(hex_privkey, SECRET_KEY)
#hex_privkey_test = aes_decrypt(new_entry['encrypted_privkey'], SECRET_KEY)
#print hex_privkey
#print hex_privkey_test
nmc_address, btc_address = get_addresses_from_privkey(hex_privkey)
new_entry['nmc_address'] = nmc_address
new_entry['btc_address'] = btc_address
print new_entry
migration_users.save(new_entry)
def test_migration_user(check_user):
for entry in migration_users.find():
if entry['username'] != check_user:
continue
hex_privkey = aes_decrypt(entry['encrypted_privkey'], SECRET_KEY)
nmc_privkey = NamecoinPrivateKey(hex_privkey)
btc_privkey = BitcoinPrivateKey(hex_privkey)
print hex_privkey
print nmc_privkey.to_wif()
print get_addresses_from_privkey(hex_privkey)
#encrypted_privkey = aes_encrypt(entry['hex_privkey'], SECRET_KEY)
def add_users_from_db(list_of_users_to_add):
for username in list_of_users_to_add:
print username
user = users.find_one({"username": username})
if user is None:
user = old_users.find_one({"username": username})
add_migration_user(user['username'], user['profile'])
def sleep_while_pending_tx():
while(1):
total_pending_tx = check_pending_tx()
if total_pending_tx > 200:
print "pending tx, sleeping"
sleep(60)
else:
print "resuming"
break
def transfer_registrar_users():
counter = 0
for user in users.find(timeout=False):
registrar_entry = registrar_state.find_one({"username": user['username']})
if registrar_entry is None:
#print "not in registrar state %s" % user['username']
continue
if 'needsTransfer' in registrar_entry and registrar_entry['needsTransfer'] is True:
profile = user['profile']
try:
transfer_key(user['username'], user['namecoin_address'], live=True, server=registrar_entry['server'])
#transfer_key(user['username'], user['namecoin_address'], live=True)
except Exception as e:
print e
print user['username']
counter += 1
if counter % 100 == 0:
sleep_while_pending_tx()
print counter
def check_pending_tx():
counter_total = 0
for server in SERVER_FLEET:
print server
try:
count = int(pending_transactions(server))
print count
counter_total += count
except Exception as e:
print e
return counter_total
def test_btc_migration(blockstore_db_file, check_username, namespace):
btc_migration = open(blockstore_db_file, 'r').read()
btc_migration = json.loads(btc_migration)
btc_registrations = btc_migration['registrations']
for entry in btc_registrations:
username = entry
if username != (check_username + "." + namespace):
continue
profile_hash = btc_registrations[username]['value_hash']
owner_address = btc_registrations[username]['address']
print username
print owner_address
print '-' * 5
entry = migration_users.find_one({"username": check_username})
print entry['btc_address']
hex_privkey = aes_decrypt(entry['encrypted_privkey'], SECRET_KEY)
nmc_address, btc_address = get_addresses_from_privkey(hex_privkey)
print btc_address
print nmc_address
def clean_registration(username):
check_user = users.find_one({"username": username})
print check_user['namecoin_address']
return
check_register = registrations.find_one({"user_id": check_user['_id']})
if check_register is not None:
registrations.remove(check_register)
print "cleaning: %s" % username
def calculate_diff():
ban_users = []
counter = 0
for check_user in old_users.find():
username = check_user["username"]
check_new_user = users.find_one({"username": username})
check_btc = btc_state.find_one({"username": username})
check_btc_diff = btc_state_diff.find_one({"username": username})
if check_btc is None and check_btc_diff is None and check_new_user is None:
if len(username) == 34 or len(username) == 33:
continue
if 'stormtrooper' in username or 'clone' in username:
continue
if username in ban_users:
continue
namecoind = NamecoindClient()
try:
resp = namecoind.name_show('u/' + username)
except Exception as e:
print username
print e
continue
if 'code' in resp:
print "not registered: %s" % username
continue
try:
resp_value = resp['value']
if 'message' in resp_value:
print "reserved: %s" % username
continue
except Exception as e:
print e
try:
current_nmc_address = resp['address']
except Exception as e:
print resp
continue
if current_nmc_address == check_user['namecoin_address']:
print "transferred new user: %s" % username
insert_btc_diff(username, check_user['profile'], str(check_user['namecoin_address']))
else:
namecoind = get_namecoind('u/' + username)
try:
resp = namecoind.validateaddress(current_nmc_address)
except Exception as e:
print e
continue
if 'ismine' in resp and resp['ismine'] is True:
profile = check_user['profile']
if type(profile) is not dict:
profile = json.loads(profile)
insert_btc_diff(username, profile, str(check_user['namecoin_address']))
else:
print "problem: %s" % username
print check_user['namecoin_address']
print '-' * 5
counter += 1
print counter
def calculate_old_users_bug():
counter = 0
for old_user in old_users.find():
username = old_user['username']
new_user = users.find_one({"username": username})
if new_user is not None:
btc_address = address_to_new_cryptocurrency(str(old_user['namecoin_address']), 0)
btc_user = btc_state.find_one({"username": username})
if btc_user is not None:
if btc_address == btc_user['btc_address']:
print username
insert_btc_diff(username, new_user['profile'], str(new_user['namecoin_address']))
counter += 1
print counter
def reprocess_user(username):
user = users.find_one({"username": username})
process_user(user['username'], user['profile'], new_address=user['namecoin_address'])
def find_user_by_email(email):
user = users.find_one({"email": email})
print user['username']
print user['namecoin_address']
def print_owner_addresses(username):
old_user = old_users.find_one({"username": username})
new_user = users.find_one({"username": username})
btc_user = btc_state.find_one({"username": username})
if old_user is not None:
print old_user['namecoin_address']
print new_user['namecoin_address']
print btc_user['btc_address']
def test_namespace(btc_state_file):
fin = open(btc_state_file, 'r')
namespace_file = json.loads(fin.read())
namespace = []
counter = 0
counter_double = 0
for entry in namespace_file:
check_entry = btc_state.find_one({"username": entry['username']})
if check_entry is not None:
counter_double += 1
counter += 1
print counter
print counter_double
def prepare_diff_2(btc_state_file, btc_state_diff_file):
fin = open(btc_state_file, 'r')
first_import = json.loads(fin.read())
fin.close()
fin = open(btc_state_diff_file, 'r')
diff_1 = json.loads(fin.read())
fin.close()
btc_namespace = first_import + diff_1
counter = 0
user_found = False
for user in users.find():
username = user['username']
user_found = False
if len(username) == 34 or len(username) == 33:
continue
if 'stormtrooper' in username or 'clone' in username:
continue
for check_user in btc_namespace:
if username == check_user['username']:
user_found = True
break
if user_found is True:
continue
namecoind = NamecoindClient()
try:
resp = namecoind.name_show('u/' + username)
except Exception as e:
print username
print e
continue
if 'code' in resp:
pass
#print "not registered: %s" % username
#print username
#insert_btc_diff(username, user['profile'], str(user['namecoin_address']))
#counter += 1
else:
print username
print counter
def get_reserved_profile(name):
profile = {}
profile['status'] = 'reserved'
profile['message'] = "This blockchain ID is reserved for %s. If this is \
you, please email support@onename.com to claim it \
for free." % name
return profile
def insert_users(list_of_users):
for username in list_of_users:
check_user = migration_users.find_one({"username": username})
print check_user
insert_btc_diff(username, check_user['profile'], str(check_user['nmc_address']))
def check_user_state(username):
check_user = btc_state_diff_2.find_one({"username": username})
if check_user is None:
check_user = btc_state_diff.find_one({"username": username})
if check_user is None:
check_user = btc_state.find_one({"username": username})
return check_user
if __name__ == '__main__':
print_reserved_users()