Beispiel #1
0
    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")
Beispiel #2
0
def new_block_checker(current_index):
    while 1:
        try:
            current_index.value = BU.get_latest_block().get('index')
        except:
            pass
        time.sleep(1)
Beispiel #3
0
 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]
Beispiel #4
0
    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])
Beispiel #5
0
 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()
Beispiel #6
0
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
Beispiel #7
0
    def dispatch_request(self):
        config = app.config['yada_config']
        mongo = app.config['yada_mongo']
        unspent = BU.get_wallet_unspent_transactions(
            config, mongo, 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(config,
                                     mongo,
                                     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)
Beispiel #8
0
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()
Beispiel #9
0
    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
Beispiel #10
0
def node(nonces=None, config=None):
    Config.from_dict(json.loads(config))
    Peers.init()
    latest_block_index = Value('i', 0)
    my_peer = Config.peer_host + ":" + str(Config.peer_port)
    Config.max_duration = 300000
    Config.block_version = 1
    #p = Process(target=new_block_checker, args=(latest_block_index,))
    status = Array('c', 'asldkjf')
    #p.start()
    Mongo.init()
    # default run state will be to mine some blocks!
    block = BU.get_latest_block()
    if block:
        latest_block_index.value = block.get('index') + 1
    else:
        genesis_block = BlockFactory.get_genesis_block()
        genesis_block.save()
        Mongo.db.consensus.insert({
            'block': genesis_block.to_dict(),
            'peer': 'me',
            'id': genesis_block.signature,
            'index': 0
        })
        block = BU.get_latest_block()
        latest_block_index.value = block.get('index')

    dup_test = Mongo.db.consensus.find({
        'peer':
        'me',
        'index':
        latest_block_index.value,
        'block.version':
        BU.get_version_for_height(latest_block_index.value + 1)
    }).sort([('index', -1)])
    if dup_test.count():
        #print 'returning', latest_block_index.value + 1, BU.get_version_for_height(latest_block_index.value + 1)
        return

    transactions = Mongo.db.miner_transactions.find()
    transaction_objs = []
    unspent_indexed = {}
    for txn in transactions:
        try:
            transaction = Transaction.from_dict(txn)
            transaction.verify()
            #check double spend
            address = str(
                P2PKHBitcoinAddress.from_pubkey(
                    transaction.public_key.decode('hex')))
            if address in unspent_indexed:
                unspent_ids = unspent_indexed[address]
            else:
                needed_value = sum(
                    [float(x.value)
                     for x in transaction.outputs]) + float(transaction.fee)
                res = BU.get_wallet_unspent_transactions(
                    address, needed_value=needed_value)
                unspent_ids = [x['id'] for x in res]
                unspent_indexed[address] = unspent_ids
            failed1 = False
            failed2 = False
            used_ids_in_this_txn = []

            for x in transaction.inputs:
                if x.id not in unspent_ids:
                    failed1 = True
                if x.id in used_ids_in_this_txn:
                    failed2 = True
                used_ids_in_this_txn.append(x.id)
            if failed1:
                Mongo.db.miner_transactions.remove(
                    {'id': transaction.transaction_signature})
                print 'transaction removed: input presumably spent already, not in unspent outputs', transaction.transaction_signature
                Mongo.db.failed_transactions.insert({
                    'reason':
                    'input presumably spent already',
                    'txn':
                    transaction.to_dict()
                })
            elif failed2:
                Mongo.db.miner_transactions.remove(
                    {'id': transaction.transaction_signature})
                print 'transaction removed: using an input used by another transaction in this block', transaction.transaction_signature
                Mongo.db.failed_transactions.insert({
                    'reason':
                    'using an input used by another transaction in this block',
                    'txn':
                    transaction.to_dict()
                })
            else:
                transaction_objs.append(transaction)
        except MissingInputTransactionException as e:
            #print 'missing this input transaction, will try again later'
            pass
        except InvalidTransactionSignatureException as e:
            print 'InvalidTransactionSignatureException: transaction removed'
            Mongo.db.miner_transactions.remove(
                {'id': transaction.transaction_signature})
            Mongo.db.failed_transactions.insert({
                'reason': 'InvalidTransactionSignatureException',
                'txn': transaction.to_dict()
            })
        except InvalidTransactionException as e:
            print 'InvalidTransactionException: transaction removed'
            Mongo.db.miner_transactions.remove(
                {'id': transaction.transaction_signature})
            Mongo.db.failed_transactions.insert({
                'reason': 'InvalidTransactionException',
                'txn': transaction.to_dict()
            })
        except Exception as e:
            #print e
            #print 'rejected transaction', txn['id']
            pass
        except BaseException as e:
            #print e
            #print 'rejected transaction', txn['id']
            pass
    try:
        block = BlockFactory.mine(transaction_objs, Config.public_key,
                                  Config.private_key, Config.max_duration,
                                  output, latest_block_index, status, nonces)
    except Exception as e:
        raise
    if block:
        dup_test = Mongo.db.consensus.find_one({
            'peer':
            'me',
            'index':
            block.index,
            'block.version':
            BU.get_version_for_height(block.index)
        })
        if not dup_test:
            print '\r\nCandidate submitted for index:', block.index
            print '\r\nTransactions:'
            for x in block.transactions:
                print x.transaction_signature
            Mongo.db.consensus.insert({
                'peer': 'me',
                'index': block.index,
                'id': block.signature,
                'block': block.to_dict()
            })
            print '\r\nSent block to:'
            for peer in Peers.peers:
                try:
                    block_dict = block.to_dict()
                    block_dict['peer'] = my_peer
                    requests.post('http://{peer}/newblock'.format(
                        peer=peer.host + ":" + str(peer.port)),
                                  json=block_dict,
                                  timeout=3,
                                  headers={'Connection': 'close'})
                    print peer.host + ":" + str(peer.port)
                except Exception as e:
                    print e
                    try:
                        print 'reporting bad peer'
                        requests.post('https://yadacoin.io/peers',
                                      json={
                                          'host': peer.host,
                                          'port': str(peer.port),
                                          'failed': True
                                      },
                                      timeout=3,
                                      headers={'Connection': 'close'})
                    except:
                        print 'failed to report bad peer'
                        pass
Beispiel #11
0
 def dispatch_request(self):
     return json.dumps({
         'block_height':
         BU.get_latest_block(app.config['yada_config'],
                             app.config['yada_mongo']).get('index')
     })
Beispiel #12
0
    def dispatch_request(self):
        config = app.config['yada_config']
        mongo = app.config['yada_mongo']
        if request.method == 'GET':
            bulletin_secret = request.args.get('bulletin_secret', '')
            username = request.args.get('username', '')
            to = request.args.get('to', '')
        else:
            bulletin_secret = request.json.get('bulletin_secret', '')
            username = request.json.get('username', '')
            to = request.json.get('to', '')

        if not bulletin_secret:
            return 'error: "bulletin_secret" missing', 400

        if not username:
            return 'error: "username" missing', 400

        if not to:
            return 'error: "to" missing', 400
        rid = TU.generate_rid(config, bulletin_secret)
        dup = mongo.db.blocks.find({'transactions.rid': rid})
        if dup.count():
            for txn in dup:
                if txn['public_key'] == config.public_key:
                    return json.dumps({
                        "success": False,
                        "status": "Already added"
                    })

        miner_transactions = mongo.db.miner_transactions.find()
        mtxn_ids = []
        for mtxn in miner_transactions:
            for mtxninput in mtxn['inputs']:
                mtxn_ids.append(mtxninput['id'])

        checked_out_txn_ids = mongo.db.checked_out_txn_ids.find()
        for mtxn in checked_out_txn_ids:
            mtxn_ids.append(mtxn['id'])

        a = os.urandom(32)
        dh_public_key = scalarmult_base(a).encode('hex')
        dh_private_key = a.encode('hex')

        transaction = TransactionFactory(config=config,
                                         mongo=mongo,
                                         block_height=BU.get_latest_block(
                                             config, mongo)['index'],
                                         bulletin_secret=bulletin_secret,
                                         username=username,
                                         fee=0.00,
                                         public_key=config.public_key,
                                         dh_public_key=dh_public_key,
                                         private_key=config.private_key,
                                         dh_private_key=dh_private_key,
                                         outputs=[{
                                             'to': to,
                                             'value': 0
                                         }])

        TU.save(config, mongo, transaction.transaction)

        mongo.db.miner_transactions.insert(transaction.transaction.to_dict())
        job = Process(target=TxnBroadcaster.txn_broadcast_job,
                      args=(transaction.transaction, ))
        job.start()

        my_bulletin_secret = config.bulletin_secret
        bulletin_secrets = sorted(
            [str(my_bulletin_secret),
             str(bulletin_secret)], key=str.lower)
        rid = hashlib.sha256(
            str(bulletin_secrets[0]) +
            str(bulletin_secrets[1])).digest().encode('hex')
        mongo.site_db.friends.insert({
            'rid': rid,
            'relationship': {
                'bulletin_secret': bulletin_secret
            }
        })
        return json.dumps({"success": True})
Beispiel #13
0
 def dispatch_request(self):
     config = app.config['yada_config']
     mongo = app.config['yada_mongo']
     block = BU.get_latest_block(config, mongo)
     return json.dumps(self.changetime(block), indent=4)
Beispiel #14
0

    picked = []
    picked_sum = 0
    for inp in inputs:
        picked.append(inp)
        picked_sum += inp['value']
        if picked_sum >= float(args.value):
            break

    print("picked {:,} inputs totaling {:,} to send for tx"
            .format(len(inputs), spendable))

    # this
    transaction = Transaction(
        block_height=BU.get_latest_block(config, mongo)['index'],
        fee=0.01,
        public_key=config.public_key,
        outputs=[
            {'to': config.address, 'value': float(args.value)}
        ],
        inputs=picked,
    )
    transaction.hash = transaction.generate_hash()
    transaction.transaction_signature = TU.generate_signature(transaction.hash, config.private_key)
    transaction.verify()
    index = BU.get_latest_block(config, mongo)['index'] + 1
    block = BlockFactory([transaction], config.public_key, config.private_key, index=index)
    block.block.special_min = True
    block.block.target = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
    block.block.nonce = 0
Beispiel #15
0
 def app_getblockheight():
     return json.dumps(
         {'block_height': BU.get_latest_block().get('index')})
Beispiel #16
0
def get_latest_block():
    block = BU.get_latest_block()
    return json.dumps(block, indent=4)