Exemple #1
0
    def __init__(self, path, skip_version_check=False):
        super(LevelDBBlockchain, self).__init__()
        self._path = path

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

        self.TXProcessed = 0

        print(TXProcessed)
        print("==========begin===========")
        print(Blockchain.GenesisBlock())

        try:
            self._db = plyvel.DB(self._path, create_if_missing=True)
        #            self._db = plyvel.DB(self._path, create_if_missing=True, bloom_filter_bits=16, compression=None)
            logger.info("Created Blockchain DB at %s " % self._path)
        except Exception as e:
            logger.info("leveldb unavailable, you may already be running this process: %s " % e)
            raise Exception('Leveldb Unavailable')

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

        print(version)

        if skip_version_check:
            self._db.put(DBPrefix.SYS_Version, self._sysversion)
            version = 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))
            self._current_block_height = int.from_bytes(ba[-4:], 'little')

            print("Block height")
            print(self._current_block_height)

            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')

            #            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:
                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:
                logger.info("Could not get stored header hash list: %s " % e)

            print("hashes")
            print(len(hashes))
            print(hashes)

            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)[8:]
                    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())

            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

        elif version is None:
            self.Persist(Blockchain.GenesisBlock())
            self._db.put(DBPrefix.SYS_Version, self._sysversion)
        else:

            logger.error("\n\n")
            logger.warning("Database schema has changed from %s to %s.\n" % (version, self._sysversion))
            logger.warning("You must either resync from scratch, or use the np-bootstrap command to bootstrap the chain.")

            res = prompt("Type 'continue' to erase your current database and sync from new. Otherwise this program will exit:\n> ")
            if res == 'continue':

                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)

            else:
                raise Exception("Database schema changed")
    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)
        #            self._db = plyvel.DB(self._path, create_if_missing=True, bloom_filter_bits=16, compression=None)
        except Exception as e:
            logger.info(
                "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')

            #            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:
                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:
                logger.info("Could not 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)[8:]
                    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())

            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:
                for key, value in self._db.iterator():
                    wb.delete(key)

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