Beispiel #1
0
    def create_block(self, moves, commit=True, click=None):
        """ Create a block. """
        for move in moves:
            if not move.valid:
                raise InvalidMoveError(move)
        block = Block(version=PROTOCOL_VERSION)
        block.root_hash = h(''.join(sorted(
            (m.id for m in moves))).encode('utf-8')).hexdigest()
        block.creator = self.address
        block.created_at = datetime.datetime.utcnow()

        prev_block = self.session.query(Block).order_by(
            Block.id.desc()).first()
        if prev_block:
            block.id = prev_block.id + 1
            block.prev_hash = prev_block.hash
            block.difficulty = prev_block.difficulty
            difficulty_check_block = self.session.query(Block).get(
                max(1, block.id - 10))
            avg_timedelta = (
                (block.created_at - difficulty_check_block.created_at) /
                (block.id - difficulty_check_block.id))
            if click:
                click.echo(
                    f'avg: {avg_timedelta}, difficulty: {block.difficulty}')
            if avg_timedelta <= datetime.timedelta(0, 5):
                block.difficulty = max(0, block.difficulty + 1)
            elif avg_timedelta > datetime.timedelta(0, 15):
                block.difficulty = max(0, block.difficulty - 1)
        else:
            #: Genesis block
            block.id = 1
            block.prev_hash = None
            block.difficulty = 0

        block.suffix = hashcash._mint(block.serialize(), bits=block.difficulty)
        if self.session.query(Block).get(block.id):
            return None
        block.hash = h(block.serialize() + block.suffix).hexdigest()

        for move in moves:
            move.block = block

        if not block.valid:
            raise InvalidBlockError

        if commit:
            try:
                self.session.add(block)
                self.session.commit()
            except IntegrityError:
                return None

        return block
Beispiel #2
0
def test_mint(challenge, bits):
    answer = _mint(challenge, bits)
    stamp = challenge + answer
    digest = hashlib.sha256(stamp)
    assert has_leading_zero_bits(digest.digest(), bits)
    assert check(stamp)