def dispatch_request(self): config = app.config['yada_config'] mongo = app.config['yada_mongo'] address = request.args.get('address') bulletin_secret = request.args.get('bulletin_secret').replace(' ', "+") rid = TU.generate_rid(config, bulletin_secret) unspent_transactions = [ x for x in BU.get_wallet_unspent_transactions( config, mongo, address) ] regular_txns = [] txns_for_fastgraph = [] for txn in unspent_transactions: if 'signatures' in txn and txn['signatures']: fastgraph = FastGraph.from_dict(config, mongo, txn) origin_fasttrack = fastgraph.get_origin_relationship(rid) if origin_fasttrack: txns_for_fastgraph.append(txn) else: if 'rid' in txn and txn[ 'rid'] == rid and 'dh_public_key' in txn and txn[ 'dh_public_key']: txns_for_fastgraph.append(txn) else: regular_txns.append(txn) wallet = { 'balance': BU.get_wallet_balance(config, mongo, address), 'unspent_transactions': regular_txns, 'txns_for_fastgraph': txns_for_fastgraph } return json.dumps(wallet, indent=4)
def dispatch_request(self): config = app.config['yada_config'] mongo = app.config['yada_mongo'] phrase = request.args.get('phrase') requester_rid = request.args.get('requester_rid') if not phrase and not requester_rid: return 'phrase required', 400 bulletin_secret = request.args.get('bulletin_secret').replace(' ', '+') if not bulletin_secret: return 'bulletin_secret required', 400 my_bulletin_secret = config.get_bulletin_secret() if requester_rid: friend = [x for x in BU().search_rid(requester_rid)][0] requester_rid = friend['rid'] rids = sorted([str(my_bulletin_secret), str(bulletin_secret)], key=str.lower) requested_rid = hashlib.sha256(rids[0].encode() + rids[1].encode()).hexdigest() else: rids = sorted([str(my_bulletin_secret), str(bulletin_secret)], key=str.lower) requester_rid = hashlib.sha256(rids[0].encode() + rids[1].encode()).hexdigest() friend = [x for x in BU().search_username(phrase)][0] requested_rid = friend['rid'] if friend: to = [x['to'] for x in friend['outputs'] if x['to'] != config.address][0] else: return '{}', 404 out = json.dumps({ 'bulletin_secret': friend['relationship']['their_bulletin_secret'], 'requested_rid': requested_rid, 'requester_rid': requester_rid, 'to': to, 'username': friend['relationship']['their_username'] }, indent=4) return out
def dispatch_request(self): address = request.args.get('address') wallet = { 'balance': BU.get_wallet_balance(address), 'unspent_transactions': [x for x in BU.get_wallet_unspent_transactions(address)] } return json.dumps(wallet, indent=4)
def dispatch_request(self): config = app.config['yada_config'] mongo = app.config['yada_mongo'] if request.json: data = request.json comment_id = data.get('_id') else: data = request.form comment_id = json.loads(data.get('_id')) res = BU.get_comment_reacts(config, mongo, [comment_id]) out = [] for x in res: try: res1 = BU.get_transaction_by_rid(config, mongo, x['rid'], wif=config.wif, rid=True) if res1: x['username'] = res1['relationship']['their_username'] out.append(x) except: pass return json.dumps(out)
def dispatch_request(self): config = app.config['yada_config'] mongo = app.config['yada_mongo'] unspent = BU().get_wallet_unspent_transactions(request.json.get('address')) unspent_inputs = dict([(x['id'], x) for x in unspent]) input_sum = 0 for x in request.json.get('inputs'): found = False if x['id'] in unspent_inputs: for tx in unspent_inputs[x['id']].get('outputs'): input_sum += float(tx['value']) found = True break if not found: if mongo.db.blocks.find_one({'transactions.id': x['id']}, {'_id': 0}): return json.dumps({'status': 'error', 'msg': 'output already spent'}), 400 else: return json.dumps({'status': 'error', 'msg': 'transaction id not in blockchain'}), 400 output_sum = 0 for x in request.json.get('outputs'): output_sum += float(x['value']) if (output_sum + float(request.json.get('fee'))) > input_sum: return json.dumps({'status': 'error', 'msg': 'not enough inputs to pay for transaction outputs + fee'}) try: txn = TransactionFactory( block_height=BU().get_latest_block(config, mongo)['index'], public_key=request.json.get('public_key'), fee=float(request.json.get('fee')), inputs=request.json.get('inputs'), outputs=request.json.get('outputs') ) except NotEnoughMoneyException as e: return json.dumps({'status': 'error', 'msg': 'not enough coins from referenced inputs to pay for transaction outputs + fee'}), 400 return '{"header": "%s", "hash": "%s"}' % (txn.header, txn.hash)
def dispatch_request(self): config = app.config['yada_config'] mongo = app.config['yada_mongo'] if request.method == 'POST': items = request.json if not isinstance(items, list): items = [ items, ] else: items = [item for item in items] transactions = [] for txn in items: transaction = Transaction.from_dict( config, mongo, BU.get_latest_block(config, mongo)['index'], txn) try: transaction.verify() except InvalidTransactionException: mongo.db.failed_transactions.insert({ 'exception': 'InvalidTransactionException', 'txn': txn }) print 'InvalidTransactionException' return 'InvalidTransactionException', 400 except InvalidTransactionSignatureException: print 'InvalidTransactionSignatureException' mongo.db.failed_transactions.insert({ 'exception': 'InvalidTransactionSignatureException', 'txn': txn }) return 'InvalidTransactionSignatureException', 400 except MissingInputTransactionException: pass except: raise print 'uknown error' return 'uknown error', 400 transactions.append(transaction) for x in transactions: mongo.db.miner_transactions.insert(x.to_dict()) job = Process(target=TxnBroadcaster.txn_broadcast_job, args=(transaction, )) job.start() return json.dumps(request.get_json()) else: rid = request.args.get('rid') if rid: transactions = BU.get_transactions_by_rid( config, mongo, rid, config.bulletin_secret, rid=True, raw=True) else: transactions = [] return json.dumps([x for x in transactions])
def dispatch_request(self): config = app.config['yada_config'] mongo = app.config['yada_mongo'] address = request.args.get('address') wallet = { 'balance': BU().get_wallet_balance(address), 'unspent_transactions': [x for x in BU().get_wallet_unspent_transactions(address)], } return json.dumps(wallet, indent=4)
def home(): session.setdefault('id', str(uuid.uuid4())) if request.method == 'POST': bulletin_secret = request.form.get('bulletin_secret', '') if not bulletin_secret: return redirect('/?error') # generate a transaction which contains a signin message containing the current sessions identifier txn = TransactionFactory(bulletin_secret=bulletin_secret, public_key=Config.public_key, private_key=Config.private_key, signin=session.get('id'), fee=0.01).transaction # send the transaction to our own serve instance, which saves it to miner_transactions # the miner looks in miner_transactions to include in a block when it finds a new block for peer in Peers.peers: print peer.host, peer.port requests.post("http://{host}:{port}/newtransaction".format( host=peer.host, port=peer.port), txn.to_json(), headers={"Content-Type": "application/json"}) return redirect('/?bulletin_secret=%s' % urllib.quote_plus(bulletin_secret)) elif request.method == 'GET': bulletin_secret = request.args.get('bulletin_secret', '') rid = TU.generate_rid(bulletin_secret) txns = BU.get_transactions_by_rid(rid, rid=True) txns2 = BU.get_transactions_by_rid(rid, rid=True, raw=True) half1 = False half2 = False for txn in txns: if txn['public_key'] == Config.public_key: half1 = True for txn in txns2: if txn['public_key'] != Config.public_key: half2 = True registered = half1 and half2 sent, received = BU.verify_message(rid, session['id']) session['loggedin'] = received return render_template('index.html', session_id=str(session.get('id')), registered=str(registered), sent=str(sent), received=str(received), loggedin=str(session['loggedin']), bulletin_secret=str(bulletin_secret), rid=str(rid)) else: return redirect('/')
def dispatch_request(self): config = app.config['yada_config'] mongo = app.config['yada_mongo'] rid = request.args.get('rid') if not rid: return '{"error": "rid not in query params"}', 400 txn_id = request.args.get('id') bulletin_secret = request.args.get('bulletin_secret') if not bulletin_secret: return '{"error": "bulletin_secret not in query params"}', 400 result = GU().verify_message( request.args.get('rid'), session.get('siginin_code'), config.public_key, txn_id.replace(' ', '+')) print(result) if result[1]: session['rid'] = rid username_txns = [x for x in BU().search_rid(rid)] session['username'] = username_txns[0]['relationship']['their_username'] return json.dumps({ 'authenticated': True }) return json.dumps({ 'authenticated': False })
def nonce_generator(): Mongo.init() latest_block_index = BU.get_latest_block()['index'] while 1: next_latest_block_index = BU.get_latest_block()['index'] if latest_block_index < next_latest_block_index: print '\r\nMining block height:', next_latest_block_index latest_block_index = next_latest_block_index start_nonce = 0 else: try: start_nonce += 1000000 except: print '\r\nMining block height:', latest_block_index start_nonce = 0 yield [start_nonce, start_nonce + 1000000]
def on_newtransaction(self, data): #print("new transaction ", data) config = app.config['yada_config'] mongo = app.config['yada_mongo'] try: incoming_txn = Transaction.from_dict( config, mongo, BU.get_latest_block(config, mongo)['index'], data) except Exception as e: print "transaction is bad" print e raise Exception("transaction is bad") except BaseException as e: print "transaction is bad" print e raise Exception("transaction is bad") try: print incoming_txn.transaction_signature dup_check = mongo.db.miner_transactions.find( {'id': incoming_txn.transaction_signature}) if dup_check.count(): print 'found duplicate' raise Exception("duplicate") mongo.db.miner_transactions.update(incoming_txn.to_dict(), incoming_txn.to_dict(), upsert=True) except Exception as e: print e raise Exception("transaction is bad") except BaseException as e: print e raise Exception("transaction is bad")
def new_block_checker(current_index): while 1: try: current_index.value = BU.get_latest_block().get('index') except: pass time.sleep(1)
def dispatch_request(self): config = app.config['yada_config'] mongo = app.config['yada_mongo'] phrase = request.args.get('phrase') if not phrase: return 'phrase required', 400 bulletin_secret = request.args.get('bulletin_secret') if not bulletin_secret: return 'bulletin_secret required', 400 my_bulletin_secret = config.get_bulletin_secret() rids = sorted([str(my_bulletin_secret), str(bulletin_secret)], key=str.lower) rid = hashlib.sha256(str(rids[0]) + str(rids[1])).digest().encode('hex') friend = [x for x in BU.search_username(config, mongo, phrase)][0] if friend: to = [ x['to'] for x in friend['outputs'] if x['to'] != config.address ][0] else: return '{}', 404 out = json.dumps( { 'bulletin_secret': friend['relationship']['their_bulletin_secret'], 'requested_rid': friend['rid'], 'requester_rid': rid, 'to': to }, indent=4) return out
def api_stats(): max_target = 0x0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff blocks = BU.get_blocks() total_nonce = 0 periods = [] last_time = None for block in blocks: difficulty = max_target / int(block.get('target'), 16) if block.get('index') == 0: start_timestamp = block.get('time') if last_time: if int(block.get('time')) > last_time: periods.append({ 'hashrate': (difficulty * 2**32) / (int(block.get('time')) - last_time), 'index': block.get('index'), 'elapsed_time': (int(block.get('time')) - last_time) }) last_time = int(block.get('time')) total_nonce += block.get('nonce') sorted(periods, key=lambda x: x['index']) total_time_elapsed = int(block.get('time')) - int(start_timestamp) network_hash_rate = total_nonce / int(total_time_elapsed) return json.dumps( { 'stats': { 'network_hash_rate': network_hash_rate, 'total_time_elapsed': total_time_elapsed, 'total_nonce': total_nonce, 'periods': periods } }, indent=4)
def get_block_reward(cls, block_index=None): """Returns the reward matching a given block height, next block if None is provided""" if block_index is None: from yadacoin import BU block_index = BU().get_latest_block()['index'] + 1 index = block_index // 2100000 reward = int(50.0 * 1e8 / 2**index) / 1e8 return reward
def get_previous_consensus_block_from_local(self, block, peer): #table cleanup new_block = Mongo.db.consensus.find_one({ 'block.hash': block.prev_hash, 'block.index': (block.index - 1), 'block.version': BU.get_version_for_height((block.index - 1)) }) if new_block: new_block = Block.from_dict(new_block['block']) if int(new_block.version) == BU.get_version_for_height( new_block.index): return new_block else: return None return None
def __init__(self): Mongo.init() latest_block = BU.get_latest_block() if latest_block: self.latest_block = Block.from_dict(latest_block) else: self.insert_genesis() self.verify_existing_blockchain()
def dispatch_request(self): config = app.config['yada_config'] mongo = app.config['yada_mongo'] address = request.args.get('address') bulletin_secret = request.args.get('bulletin_secret').replace(' ', "+") rid = TU.generate_rid(config, bulletin_secret) unspent_transactions = [x for x in BU().get_wallet_unspent_transactions(address)] spent_txn_ids = [] for x in unspent_transactions: spent_txn_ids.extend([y['id'] for y in x['inputs']]) unspent_fastgraph_transactions = [x for x in BU().get_wallet_unspent_fastgraph_transactions(address) if x['id'] not in spent_txn_ids] print('fastgraph uspent txn ids:') print([x['id'] for x in unspent_fastgraph_transactions]) spent_fastgraph_ids = [] for x in unspent_fastgraph_transactions: spent_fastgraph_ids.extend([y['id'] for y in x['inputs']]) print('regular unspent txn ids:') print([x['id'] for x in unspent_transactions]) regular_txns = [] txns_for_fastgraph = [] for txn in unspent_transactions: if 'signatures' in txn and txn['signatures']: fastgraph = FastGraph.from_dict(0, txn) origin_fasttrack = fastgraph.get_origin_relationship(rid) if origin_fasttrack: txns_for_fastgraph.append(txn) else: regular_txns.append(txn) else: if 'rid' in txn and txn['rid'] == rid and 'dh_public_key' in txn and txn['dh_public_key']: txns_for_fastgraph.append(txn) else: regular_txns.append(txn) #print(unspent_fastgraph_transactions) if unspent_fastgraph_transactions: txns_for_fastgraph.extend(unspent_fastgraph_transactions) print('final txn ids:') print([x['id'] for x in txns_for_fastgraph]) wallet = { 'balance': BU().get_wallet_balance(address), 'unspent_transactions': regular_txns, 'txns_for_fastgraph': txns_for_fastgraph } return json.dumps(wallet, indent=4)
def post_block(): block = Block.from_dict(request.json) block.verify() my_latest_block = BU.get_latest_block() if my_latest_block[0].get('index') - block.index == 1: block.save() return '{"status": "ok"}' else: return '{"status": "error"}', 400
def get_consensus_blocks_by_index(self, index): return Mongo.db.consensus.find( { 'index': index, 'block.prevHash': { '$ne': '' }, 'block.version': BU.get_version_for_height(index) }, {'_id': 0})
def dispatch_request(self): config = app.config['yada_config'] mongo = app.config['yada_mongo'] if not request.args.get('rid'): return '{"error": "rid not in query params"}' result = BU.verify_message(config, mongo, request.args.get('rid'), session.get('siginin_code'), config.public_key, request.args.get('id').replace(' ', '+')) return json.dumps({'authenticated': True if result[1] else False})
def dispatch_request(self): if request.method == 'POST': items = request.json if not isinstance(items, list): items = [items, ] else: items = [item for item in items] transactions = [] for txn in items: transaction = Transaction.from_dict(txn) try: transaction.verify() except InvalidTransactionException: Mongo.db.failed_transactions.insert({ 'exception': 'InvalidTransactionException', 'txn': txn }) print 'InvalidTransactionException' return 'InvalidTransactionException', 400 except InvalidTransactionSignatureException: print 'InvalidTransactionSignatureException' Mongo.db.failed_transactions.insert({ 'exception': 'InvalidTransactionSignatureException', 'txn': txn }) return 'InvalidTransactionSignatureException', 400 except MissingInputTransactionException: pass except: raise print 'uknown error' return 'uknown error', 400 transactions.append(transaction) for x in transactions: Mongo.db.miner_transactions.insert(x.to_dict()) job = Process(target=TxnBroadcaster.txn_broadcast_job, args=(transaction,)) job.start() if Config.fcm_key: for txn in transactions: job = Process( target=self.do_push, args=(txn.to_dict(), request.args.get('bulletin_secret')) ) job.start() return json.dumps(request.get_json()) else: rid = request.args.get('rid') if rid: transactions = BU.get_transactions_by_rid(rid, rid=True, raw=True) else: transactions = [] return json.dumps([x for x in transactions])
def generate_some_blocks(keys): for key in keys: transactions = [] existing_input = mongo.db.blocks.find({'transactions.outputs.to': key.get('address')}) if existing_input.count() == 0: config = Wallet(key) index = BU.get_latest_block(config, mongo)['index'] + 1 block = BlockFactory(transactions, key.get('public_key'), key.get('private_key'), index=index) block.block.special_min = True block.block.target = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff block.block.nonce = 0 header = BlockFactory.generate_header(block.block) block.block.hash = BlockFactory.generate_hash_from_header(header, block.block.nonce) block.block.signature = BU.generate_signature(block.block.hash, key['private_key']) mongo.db.consensus.insert({ 'peer': 'me', 'index': block.block.index, 'id': block.block.signature, 'block': block.block.to_dict() }) consensus.sync_bottom_up()
def faucet(): Mongo.init() used_inputs = [] new_inputs = [] for x in Mongo.site_db.faucet.find({'active': True}): balance = BU.get_wallet_balance(x['address']) if balance >= 25: Mongo.site_db.faucet.update({'_id': x['_id']}, { 'active': False, 'address': x['address'] }) continue last_id_in_blockchain = x.get('last_id') if last_id_in_blockchain and not Mongo.db.blocks.find({ 'transactions.id': last_id_in_blockchain }).count(): continue try: transaction = TransactionFactory( fee=0.01, public_key=Config.public_key, private_key=Config.private_key, outputs=[Output(to=x['address'], value=5)]) except NotEnoughMoneyException as e: print "not enough money yet" return except Exception as e: print x try: transaction.transaction.verify() except: Mongo.site_db.failed_faucet_transactions.insert( transaction.transaction.to_dict()) print 'faucet transaction failed' TU.save(transaction.transaction) x['last_id'] = transaction.transaction.transaction_signature Mongo.site_db.faucet.update({'_id': x['_id']}, x) print 'saved. sending...', x['address'] for peer in Peers.peers: try: socketIO = SocketIO(peer.host, peer.port, wait_for_connection=False) chat_namespace = socketIO.define(ChatNamespace, '/chat') chat_namespace.emit('newtransaction', transaction.transaction.to_dict()) socketIO.disconnect() except Exception as e: print e
def dispatch_request(self): config = app.config['yada_config'] mongo = app.config['yada_mongo'] my_bulletin_secret = config.get_bulletin_secret() their_bulletin_secret = request.json.get('bulletin_secret') rids = sorted([str(my_bulletin_secret), str(their_bulletin_secret)], key=str.lower) rid = hashlib.sha256(str(rids[0]) + str(rids[1])).digest().encode('hex') client = app.test_client() response = client.post('/post-fastgraph-transaction', data=request.json.get('txn'), headers=list(request.headers)) fastgraph = FastGraph(**request.json.get('txn')) try: response.get_json() except: return 'error posting react', 400 friend = BU().get_transactions( config, mongo, wif=config.wif, both=False, query={'txn.relationship.their_username': {'$exists': True}, 'txn.relationship.id': {'$in': signatures}}, queryType="searchUsername" ) if friend: username = [x for x in friend][0]['relationship']['their_username'] else: username = '' res = mongo.site_db.fcmtokens.find({"rid": rid}) for token in res: result = push_service.notify_single_device( registration_id=token['token'], message_title='%s commented on your post!' % username, message_body='Go see what they said!', extra_kwargs={'priority': 'high'} ) comments = mongo.site_db.comments.find({ 'rid': {'$ne': rid}, 'txn_id': request.json.get('txn_id') }) for comment in comments: res = mongo.site_db.fcmtokens.find({"rid": comment['rid']}) for token in res: result = push_service.notify_single_device( registration_id=token['token'], message_title='%s commented on a post you commented on!' % username, message_body='Go see what they said!', extra_kwargs={'priority': 'high'} ) return 'ok'
def sync(self): #top down syncing self.latest_block = Block.from_dict(BU.get_latest_block()) self.remove_pending_transactions_now_in_chain() latest_consensus = self.get_latest_consensus_block() if latest_consensus: print latest_consensus.index, "latest consensus_block" # check for difference between blockchain and consensus table heights if self.latest_block.index == latest_consensus.index: self.log('up to date, height: ' + str(latest_consensus.index)) return records = Mongo.db.consensus.find({ 'index': latest_consensus.index, 'block.version': BU.get_version_for_height(latest_consensus.index) }) for record in sorted(records, key=lambda x: int(x['block']['target'], 16)): block = Block.from_dict(record['block']) peer = Peer.from_string(record['peer']) print self.latest_block.hash, block.prev_hash, self.latest_block.index, ( block.index - 1) try: self.integrate_block_with_existing_chain( block, peer, self.existing_blockchain) except AboveTargetException as e: pass except ForkException as e: self.retrace(block, peer) except IndexError as e: self.retrace(block, peer) else: self.log('no consensus data... none.') return
def fcm_token(): try: token = request.json.get('token') print token rid = request.json.get('rid') txn = BU.get_transaction_by_rid(rid, rid=True) Mongo.site_db.fcmtokens.update({'rid': rid}, { 'rid': rid, 'token': token }, upsert=True) return '', 200 except Exception as e: return '', 400
def show_friend_request(): authed_user = get_logged_in_user() transaction = BU.get_transaction_by_rid(request.args.get('rid'), rid=True, raw=True) requested_transaction = BU.get_transaction_by_rid( transaction['requester_rid'], rid=True) dict_data = { 'bulletin_secret': requested_transaction['relationship']['bulletin_secret'], 'requested_rid': transaction['requested_rid'], 'requester_rid': transaction['requester_rid'] } data = json.dumps(dict_data) qr_code = make_qr(data) return render_template( 'accept-friend-request.html', qrcode=qr_code, data=json.dumps(dict_data, indent=4), rid=requested_transaction['rid'], bulletin_secret=requested_transaction['relationship'] ['bulletin_secret'])
def get_logged_in_user(): user = None tests = [] res = Mongo.db.blocks.aggregate([{ "$match": { "transactions.challenge_code": session['challenge_code'] } }, { '$unwind': "$transactions" }, { "$match": { "transactions.challenge_code": session['challenge_code'] } }]) for transaction in res: transaction = transaction['transactions'] tests = BU.get_transactions_by_rid(transaction['rid'], rid=True) for test in tests: if 'relationship' in test and 'shared_secret' in test[ 'relationship']: cipher = Crypt( hashlib.sha256(test['relationship'] ['shared_secret']).digest().encode('hex')) answer = cipher.decrypt(transaction['answer']) if answer == transaction['challenge_code']: for txn_output in transaction['outputs']: if txn_output['to'] != Config.address: to = txn_output['to'] user = { 'balance': BU.get_wallet_balance(to), 'authenticated': True, 'rid': transaction['rid'], 'bulletin_secret': test['relationship']['bulletin_secret'] } return user if user else {'authenticated': False}
def get_previous_consensus_block_from_remote(self, block, peer): try: url = 'http://' + peer.to_string( ) + '/get-block?hash=' + block.prev_hash print 'getting block', url res = requests.get(url, timeout=3) print 'response code: ', res.status_code new_block = Block.from_dict(json.loads(res.content)) if int(new_block.version) == BU.get_version_for_height( new_block.index): return new_block else: return None except: return None