Ejemplo n.º 1
0
    def __init__(self, path):
        super(LevelDBBlockchain,self).__init__()
        self._path = path

        self._header_index = []
        self._header_index.append(Blockchain.GenesisBlock().Header.Hash.ToBytes())

        try:
            self._db = plyvel.DB(self._path, create_if_missing=True)
        except Exception as e:
            self.__log.debug("leveldb unavailable, you may already be running this process: %s " % e)
            raise Exception('Leveldb Unavailable')


        version = self._db.get(DBPrefix.SYS_Version)


        if version == self._sysversion: #or in the future, if version doesn't equal the current version...


            ba=bytearray(self._db.get(DBPrefix.SYS_CurrentBlock, 0))
            self._current_block_height = int.from_bytes( ba[-4:], 'little')


            ba = bytearray(self._db.get(DBPrefix.SYS_CurrentHeader, 0))
            current_header_height = int.from_bytes(ba[-4:], 'little')
            current_header_hash = bytes(ba[:64].decode('utf-8'), encoding='utf-8')

            self.__log.debug("current header hash!! %s " % current_header_hash)
            self.__log.debug("current header height, hashes %s %s %s" %(self._current_block_height, self._header_index, current_header_height) )


            hashes = []
            try:
                for key, value in self._db.iterator(prefix=DBPrefix.IX_HeaderHashList):
                    ms = StreamManager.GetStream(value)
                    reader = BinaryReader(ms)
                    hlist = reader.Read2000256List()
                    key =int.from_bytes(key[-4:], 'little')
                    hashes.append({'k':key, 'v':hlist})
                    StreamManager.ReleaseStream(ms)
    #                hashes.append({'index':int.from_bytes(key, 'little'), 'hash':value})

            except Exception as e:
                self.__log.debug("Coludnt get stored header hash list: %s " % e)

            if len(hashes):
                hashes.sort(key=lambda x:x['k'])
                genstr = Blockchain.GenesisBlock().Hash.ToBytes()
                for hlist in hashes:

                    for hash in hlist['v']:
                        if hash != genstr:
                            self._header_index.append(hash)
                        self._stored_header_count += 1

            if self._stored_header_count == 0:
                headers = []
                for key, value in self._db.iterator(prefix=DBPrefix.DATA_Block):
                    dbhash = bytearray(value)[4:]
                    headers.append(  Header.FromTrimmedData(binascii.unhexlify(dbhash), 0))

                headers.sort(key=lambda h: h.Index)
                for h in headers:
                    if h.Index > 0:
                        self._header_index.append(h.Hash.ToBytes())


        else:
            with self._db.write_batch() as wb:
                for key,value in self._db.iterator():
                    wb.delete(key)


            self.Persist(Blockchain.GenesisBlock())
            self._db.put(DBPrefix.SYS_Version, self._sysversion )
Ejemplo n.º 2
0
    def __init__(self, path):
        super(RocksDBBlockchain, self).__init__()
        self._path = path

        self._header_index = []
        self._header_index.append(
            Blockchain.GenesisBlock().Header.Hash.ToBytes())

        logger.info("start to create database")
        logger.info("db path is: ", self._path)
        try:
            opts = rocksdb.Options()
            opts.create_if_missing = True
            opts.prefix_extractor = StaticPrefix()
            #           self._db = plyvel.DB(self._path, create_if_missing=True)
            self._db = rocksdb.DB(self._path, opts)
            #           self._db = plyvel.DB(self._path, create_if_missing=True, bloom_filter_bits=16, compression=None)
            logger.info("rocksdb is created successfully")
        except Exception as e:
            logger.info(
                "RocksDB unavailable, you may already be running this process: %s "
                % e)
            raise Exception('RocksDB Unavailable')

        version = self._db.get(DBPrefix.SYS_Version)

        logger.info("database is created successfully, version is: ", version)
        logger.info("database is created successfully, self_sysversion is: ",
                    self._sysversion)

        if version == self._sysversion:  # or in the future, if version doesn't equal the current version...

            ba = bytearray(self._db.get(DBPrefix.SYS_CurrentBlock, 0))
            logger.debug("current block", ba)
            logger.debug("current block", ba[-4:])
            self._current_block_height = int.from_bytes(ba[-4:], 'little')
            logger.debug("current block height: ", self._current_block_height)

            ba = bytearray(self._db.get(DBPrefix.SYS_CurrentHeader, 0))
            logger.debug("current header", ba)
            current_header_height = int.from_bytes(ba[-4:], 'little')
            current_header_hash = bytes(ba[:64].decode('utf-8'),
                                        encoding='utf-8')

            #            logger.info("current header hash!! %s " % current_header_hash)
            #            logger.info("current header height, hashes %s %s %s" %(self._current_block_height, self._header_index, current_header_height) )

            hashes = []
            try:
                it = self._db.iteritems()
                it.seek(DBPrefix.IX_HeaderHashList)
                #                print ( dict(itertools.takewhile(lambda item: item[0].startswith(DBPrefix.IX_HeaderHashList), it)))
                #                for key in self._db.iterkeys().seek(prefix=DBPrefix.IX_HeaderHashList):
                for key, value in dict(
                        itertools.takewhile(
                            lambda item: item[0].startswith(
                                DBPrefix.IX_HeaderHashList), it)).items():
                    ms = StreamManager.GetStream(value)
                    reader = BinaryReader(ms)
                    hlist = reader.Read2000256List()
                    key = int.from_bytes(key[-4:], 'little')
                    hashes.append({'k': key, 'v': hlist})
                    StreamManager.ReleaseStream(ms)

    #                hashes.append({'index':int.from_bytes(key, 'little'), 'hash':value})

            except Exception as e:
                logger.info("Couldnt get stored header hash list: %s " % e)

            if len(hashes):
                hashes.sort(key=lambda x: x['k'])
                genstr = Blockchain.GenesisBlock().Hash.ToBytes()
                for hlist in hashes:

                    for hash in hlist['v']:
                        if hash != genstr:
                            self._header_index.append(hash)
                        self._stored_header_count += 1

            if self._stored_header_count == 0:
                headers = []
                # for key, value in self._db.iterator(prefix=DBPrefix.DATA_Block):
                it = self._db.iteritems()
                # print ("it before seek ", it)
                logger.debug("seek key prefix: ", DBPrefix.DATA_Block)
                it.seek(DBPrefix.DATA_Block)
                # print ("it after seek ", it)
                # print ( dict(itertools.takewhile(lambda item: item[0].startswith(DBPrefix.DATA_Block), it)))
                for key, value in dict(
                        itertools.takewhile(
                            lambda item: item[0].startswith(DBPrefix.DATA_Block
                                                            ), it)).items():
                    # print("key is ", key)
                    # print("value is ", value)
                    dbhash = bytearray(value)[8:]
                    # print (bytearray(value))
                    # print ("dbhash is ", dbhash)
                    headers.append(
                        Header.FromTrimmedData(binascii.unhexlify(dbhash), 0))
                    # print ("header is ", headers)

                headers.sort(key=lambda h: h.Index)
                for h in headers:
                    if h.Index > 0:
                        self._header_index.append(h.Hash.ToBytes())

            elif current_header_height > self._stored_header_count:

                try:
                    hash = current_header_hash
                    targethash = self._header_index[-1]

                    newhashes = []
                    while hash != targethash:
                        header = self.GetHeader(hash)
                        newhashes.insert(0, header)
                        hash = header.PrevHash.ToBytes()

                    self.AddHeaders(newhashes)
                except Exception as e:
                    pass
        else:
            #  with self._db.write_batch() as wb:
            wb = rocksdb.WriteBatch()
            for key in self._db.iterkeys():
                wb.delete(key)
            self._db.write(wb)

            self.Persist(Blockchain.GenesisBlock())
            self._db.put(DBPrefix.SYS_Version, self._sysversion)