예제 #1
0
    def get_highest_block(self):
        """
        Return the highest known block in the main chain
        """
        if self._highest_block is not None:
            return self._highest_block

        highest_in_cache = None
        if self.block_cache:
            main_chain = [
                block for block in self.block_cache.values()
                if block.chain == MAIN_CHAIN
            ]
            if main_chain:
                highest_in_cache = max(main_chain, key=lambda b: b.height)

        highest_in_db = self.blocks.find_one({"chain": MAIN_CHAIN},
                                             sort=[("height", -1)])
        if highest_in_db:
            mongo_block_transactions = self.transactions.find(
                {"blockhash": highest_in_db['hash']})
            highest_in_db = MongoBlockFactory.from_mongo(
                highest_in_db, mongo_block_transactions)

        highest_block = max([highest_in_cache, highest_in_db])
        self.set_highest_block(highest_block)
        return self._highest_block
예제 #2
0
    def get_blocks_higher_than(self, height):
        """
        Returns blocks in the MAIN_CHAIN with block.height > height
        """
        cache_blocks = sorted([
            block for (key, block) in self.block_cache.iteritems()
            if block['chain'] == MAIN_CHAIN
        ],
                              key=lambda b: b['height'])

        if cache_blocks[0]['height'] < height:
            result = [
                block for block in cache_blocks if block['height'] > height
            ]
        else:
            result = list(
                self.blocks.find({
                    "height": {
                        "$gt": height
                    },
                    "chain": MAIN_CHAIN
                }))
            result += cache_blocks

        return [MongoBlockFactory.from_mongo(block) for block in result]
예제 #3
0
    def get_blocks_higher_than(self, height):
        """
        Returns blocks in the MAIN_CHAIN with block.height > height
        """
        cache_blocks = sorted([
            block
            for block in self.block_cache.values() if block.chain == MAIN_CHAIN
        ],
                              key=lambda b: b.height)

        if cache_blocks and cache_blocks[0].height < height:
            result = [block for block in cache_blocks if block.height > height]
        else:
            mongo_blocks = self.blocks.find({
                "height": {
                    "$gt": height
                },
                "chain": MAIN_CHAIN
            })
            result = [
                MongoBlockFactory.from_mongo(
                    block, self.transactions.find({"blockhash":
                                                   block['hash']}))
                for block in mongo_blocks
            ]

            result += cache_blocks

        return result
예제 #4
0
    def get_highest_block(self):
        """
        Return the highest known block in the DB
        """
        mongo_block = self.blocks.find_one(sort=[("height", -1)])

        if mongo_block:
            return MongoBlockFactory.from_mongo(mongo_block)
        else:
            return None
예제 #5
0
    def get_blocks_by_chain(self, chain):
        in_cache = [block for block in self.block_cache.values() if block.chain == chain]

        in_db = []
        mongo_blocks = self.blocks.find({"chain": chain})
        for mongo_block in mongo_blocks:
            mongo_block_transactions = self.transactions.find({"blockhash": mongo_block['hash']})
            in_db.append(MongoBlockFactory.from_mongo(mongo_block, mongo_block_transactions))

        return in_cache + in_db
예제 #6
0
    def get_blocks_by_chain(self, chain):
        in_cache = [
            block for (key, block) in self.block_cache.iteritems()
            if block['chain'] == chain
        ]
        in_db = self.blocks.find({"chain": chain})

        return [
            MongoBlockFactory.from_mongo(block)
            for block in (in_cache + list(in_db))
        ]
예제 #7
0
    def get_block_by_hash(self, block_hash):
        """
        Tries to find it in cache and if it misses finds it in the DB
        """
        if block_hash in self.block_cache:
            return self.block_cache[block_hash]

        mongo_block = self.blocks.find_one({"hash": block_hash})

        if not mongo_block:
            raise KeyError("[get_block_by_hash] Block with hash %s not found." % block_hash)

        mongo_block_transactions = self.transactions.find({"blockhash": mongo_block['hash']})
        return MongoBlockFactory.from_mongo(mongo_block, mongo_block_transactions)
예제 #8
0
    def get_block_by_height(self, block_height):
        found = [block for block in self.block_cache.values() if block.height == block_height]
        if found:
            return found[0]

        mongo_block = self.blocks.find_one({"height": block_height})

        if mongo_block:
            mongo_block_transactions = self.transactions.find({"blockhash": mongo_block['hash']})
            found = MongoBlockFactory.from_mongo(mongo_block, mongo_block_transactions)

        if not found:
            raise KeyError("[get_block_by_height] Block with height %s not found." % block_height)

        return found
예제 #9
0
    def get_block_by_height(self, block_height):
        found = None
        if self.cache:
            for (blockhash, block) in self.block_cache.iteritems():
                if block['height'] == block_height:
                    found = block

        if not self.cache or not found:
            found = self.blocks.find_one({"height": block_height})

        if not found:
            raise KeyError(
                "[get_block_by_height] Block with height %s not found." %
                block_height)

        return MongoBlockFactory.from_mongo(found)
예제 #10
0
    def get_block_by_hash(self, block_hash):
        """
        Tries to find it in cache and if it misses finds it in the DB
        """
        found = None
        if self.cache and block_hash in self.block_cache:
            found = self.block_cache[block_hash]

        if not self.cache or not found:
            found = self.blocks.find_one({"hash": block_hash})

        if not found:
            raise KeyError(
                "[get_block_by_hash] Block with hash %s not found." %
                block_hash)

        return MongoBlockFactory.from_mongo(found)
예제 #11
0
 def get_latest_blocks(self, limit=10, offset=0):
     return [
         MongoBlockFactory.from_mongo(block) for block in self.blocks.find(
             sort=[("height", -1)]).skip(offset).limit(limit)
     ]
예제 #12
0
 def setUp(self):
     self.db = MagicMock()
     self.chain = Blockchain(self.db)
     self.example_block = MongoBlockFactory.from_mongo(EXAMPLE_MONGO_BLOCK)