Ejemplo n.º 1
0
 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
Ejemplo n.º 2
0
 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})
Ejemplo n.º 3
0
 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
Ejemplo n.º 4
0
    def on_newblock(self, data):
        #print("new block ", data)
        config = app.config['yada_config']
        mongo = app.config['yada_mongo']
        try:
            peer = Peer.from_string(config, mongo, request.json.get('peer'))
            block = Block.from_dict(config, mongo, data)
            if block.index == 0:
                return
            if int(block.version) != BU.get_version_for_height(block.index):
                print 'rejected old version %s from %s' % (block.version, peer)
                return
            mongo.db.consensus.update(
                {
                    'index': block.to_dict().get('index'),
                    'id': block.to_dict().get('id'),
                    'peer': peer.to_string()
                }, {
                    'block': block.to_dict(),
                    'index': block.to_dict().get('index'),
                    'id': block.to_dict().get('id'),
                    'peer': peer.to_string()
                },
                upsert=True)

        except Exception as e:
            print "block is bad"
            raise e
        except BaseException as e:
            print "block is bad"
            raise e
        try:
            if 'regnet' not in config.network:
                requests.post('https://yadacoin.io/peers',
                              json.dumps({
                                  'host': config.peer_host,
                                  'port': config.peer_port
                              }),
                              headers={"Content-Type": "application/json"})
        except:
            print 'ERROR: failed to get peers, exiting...'
Ejemplo n.º 5
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
Ejemplo n.º 6
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
Ejemplo n.º 7
0
        def newblock(data):
            #print("new block ", data)
            try:
                peer = request.json.get('peer')
                incoming_block = Block.from_dict(data)
                if incoming_block.index == 0:
                    return
                if int(incoming_block.version) != BU.get_version_for_height(
                        incoming_block.index):
                    print 'rejected old version %s from %s' % (
                        incoming_block.version, peer)
                    return
            except Exception as e:
                print "block is bad"
                print e
            except BaseException as e:
                print "block is bad"
                print e

            try:
                dup_check = Mongo.db.consensus.find({
                    'id':
                    incoming_block.signature,
                    'peer':
                    peer,
                    'block.version':
                    BU.get_version_for_height(incoming_block.index)
                })
                if dup_check.count():
                    return "dup"
                Mongo.db.consensus.update(
                    {
                        'block': incoming_block.to_dict(),
                        'index': incoming_block.to_dict().get('index'),
                        'id': incoming_block.to_dict().get('id'),
                        'peer': peer
                    }, {
                        'block': incoming_block.to_dict(),
                        'index': incoming_block.to_dict().get('index'),
                        'id': incoming_block.to_dict().get('id'),
                        'peer': peer
                    },
                    upsert=True)
                # before inserting, we need to check it's chain
                # search consensus for prevHash of incoming block.
                #prev_blocks_check = Mongo.db.blocks.find({'hash': incoming_block.prev_hash})
                #if prev_blocks_check.count():
                # 1. if we have it, then insert it.
                #    Mongo.db.consensus.insert({
                #        'block': incoming_block.to_dict(),
                #        'index': incoming_block.to_dict().get('index'),
                #        'id': incoming_block.to_dict().get('id'),
                #        'peer': peer})
                #else:
                # 2 scenarios
                # 1. the 3 is late to the game
                # 2. 1 and 2 do not find prev_hash from 3 and
                # we have a fork
                # the consensus has the previous block to the incoming block but it's not in the block chain
                # we need to do the chain compare routine here and decide if we're going with the blockchain
                # belongs to the incoming block, or stay with our existing one

                #retrace(incoming_block, db, peer)
                # return
            except Exception as e:
                print e
            except BaseException as e:
                print e
Ejemplo n.º 8
0
 def get_latest_consensus_block(self):
     latests = self.get_latest_consensus_blocks()
     for latest in latests:
         if int(latest['block']['version']) == BU.get_version_for_height(
                 latest['block']['index']):
             return Block.from_dict(latest['block'])
Ejemplo n.º 9
0
 def get_latest_consensus_blocks(self):
     for x in Mongo.db.consensus.find({}, {'_id': 0}).sort([('index', -1)]):
         if BU.get_version_for_height(x['block']['index']) == int(
                 x['block']['version']):
             yield x