コード例 #1
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()
コード例 #2
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
コード例 #3
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
コード例 #4
0
    def rank_consenesus_blocks(self):
        # rank is based on target, total chain difficulty, and chain validity
        records = self.get_consensus_blocks_by_index(self.latest_block.index +
                                                     1)
        lowest = self.lowest

        ranks = []
        for record in records:
            peer = Peer.from_string(record['peer'])
            block = Block.from_dict(record['block'])
            target = int(record['block']['hash'], 16)
            if target < lowest:
                ranks.append({'target': target, 'block': block, 'peer': peer})
        return sorted(ranks, key=lambda x: x['target'])
コード例 #5
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
コード例 #6
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
コード例 #7
0
ファイル: endpoints_old.py プロジェクト: EggPool/yadacoin
 def on_newblock(self, data):
     #print("new block ", data)
     config = app.config['yada_config']
     mongo = app.config['yada_mongo']
     try:
         peer = Peer.from_string(request.json.get('peer'))
         block = Block.from_dict(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 Exception 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...')
コード例 #8
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
コード例 #9
0
    def retrace(self, block, peer):
        self.log("retracing...")
        blocks = []
        blocks.append(block)
        while 1:
            self.log(block.hash)
            self.log(block.index)
            # get the previous block from either the consensus collection in mongo
            # or attempt to get the block from the remote peer
            previous_consensus_block = self.get_previous_consensus_block_from_local(
                block, peer)
            if previous_consensus_block:
                block = previous_consensus_block
                blocks.append(block)
            else:
                previous_consensus_block = self.get_previous_consensus_block_from_remote(
                    block, peer)
                if previous_consensus_block and previous_consensus_block.index + 1 == block.index:
                    block = previous_consensus_block
                    blocks.append(block)
                    self.insert_consensus_block(block, peer)
                else:
                    # identify missing and prune
                    # if the pruned chain is still longer, we'll take it
                    if previous_consensus_block:
                        block = previous_consensus_block
                        blocks = [block]
                    else:
                        return

            print 'attempting sync at', block.prev_hash
            # if they do have it, query our consensus collection for prevHash of that block, repeat 1 and 2 until index 1
            prev_blocks_check = Mongo.db.blocks.find_one({
                'hash':
                block.prev_hash,
                'index':
                block.index - 1
            })

            if prev_blocks_check:
                prev_blocks_check = Block.from_dict(prev_blocks_check)
                print prev_blocks_check.hash, prev_blocks_check.index
                missing_blocks = Mongo.db.blocks.find(
                    {'index': {
                        '$lte': prev_blocks_check.index
                    }})
                for missing_block in missing_blocks:
                    blocks.append(Block.from_dict(missing_block))
                # if we have it in our blockchain, then we've hit the fork point
                # now we have to loop through the current block array and build a blockchain
                # then we compare the block height and difficulty of the two chains
                # replace our current chain if necessary by removing them from the database
                # then looping though our new chain, inserting the new blocks
                self.existing_blockchain = Blockchain(
                    [x for x in Mongo.db.blocks.find({})])
                blockchain = Blockchain([x for x in blocks])

                # If the block height is equal, we throw out the inbound chain, it muse be greater
                # If the block height is lower, we throw it out
                # if the block height is heigher, we compare the difficulty of the entire chain

                inbound_difficulty_average = (
                    blockchain.get_difficulty() /
                    blockchain.get_highest_block_height())

                if self.existing_blockchain.get_highest_block_height() == 0:
                    existing_difficulty_average = inbound_difficulty_average + 1
                else:
                    existing_difficulty_average = (
                        self.existing_blockchain.get_difficulty() /
                        self.existing_blockchain.get_highest_block_height())

                if blockchain.get_highest_block_height() > self.existing_blockchain.get_highest_block_height() \
                    and inbound_difficulty_average < existing_difficulty_average:
                    for block in sorted(blockchain.blocks,
                                        key=lambda x: x.index):
                        try:
                            if block.index == 0:
                                continue
                            self.integrate_block_with_existing_chain(
                                block, peer, blockchain)
                        except ForkException as e:
                            return
                        except AboveTargetException as e:
                            return
                    print "Replaced chain with incoming"
                    return
                else:
                    print "Incoming chain lost", blockchain.get_difficulty(
                    ), self.existing_blockchain.get_difficulty(
                    ), blockchain.get_highest_block_height(
                    ), self.existing_blockchain.get_highest_block_height()
                    return
            # lets go down the hash path to see where prevHash is in our blockchain, hopefully before the genesis block
            # we need some way of making sure we have all previous blocks until we hit a block with prevHash in our main blockchain
            #there is no else, we just loop again
            # if we get to index 1 and prev hash doesn't match the genesis, throw out the chain and black list the peer
            # if we get a fork point, prevHash is found in our consensus or genesis, then we compare the current
            # blockchain against the proposed chain.
            if block.index == 0:
                print "zero index reached"
                return
        print "doesn't follow any known chain"  # throwing out the block for now
        return
コード例 #10
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'])