Beispiel #1
0
def sync():
    Client(os.environ.get('SENTRY_DSN'))
    public_url = get_my_public_url()
    if public_url:
        click.echo(f"You have a public node url. ({public_url})")
        Node.broadcast(Node.post_node_endpoint, {'url': public_url})
    Node.update()
    engine = db.engine
    if not engine.dialect.has_table(engine.connect(), Block.__tablename__):
        click.echo("You need to initialize. try `nekoyume init`.")
        return False
    while True:
        try:
            prev_id = Block.query.order_by(Block.id.desc()).first().id
        except AttributeError:
            prev_id = 0
        Block.sync(click=click)
        try:
            if prev_id == Block.query.order_by(Block.id.desc()).first().id:
                click.echo("The blockchain is up to date.")
                time.sleep(15)
        except AttributeError:
            click.echo(("There is no well-connected node. "
                        "please check you network."))
            break
Beispiel #2
0
def init(seed):
    click.echo('Creating database...')
    db.create_all()
    click.echo(f'Updating node... (seed: {seed})')
    Node.update(Node(url=seed))
    click.echo('Syncing blocks...')
    Block.sync(click=click)
Beispiel #3
0
def test_hack_and_slash_execute(fx_user, fx_novice_status):
    move = fx_user.create_novice(fx_novice_status)
    Block.create(fx_user, [move])
    avatar = fx_user.avatar()
    avatar.hp = 0
    move = fx_user.move(HackAndSlash())
    Block.create(fx_user, [move])
    with raises(InvalidMoveError):
        move.execute(avatar)
Beispiel #4
0
def post_block():
    new_block = request.get_json()
    last_block = Block.query.order_by(Block.id.desc()).first()

    if not new_block:
        return jsonify(result='failed', message="empty block."), 400

    if not last_block and new_block['id'] != 1:
        Block.sync(Node.query.order_by(Node.last_connected_at.desc()).first())
        return jsonify(result='failed',
                       message="new block isn't our next block."), 403

    if (new_block['id'] > 1
            and (new_block['id'] != last_block.id + 1
                 or new_block['prev_hash'] != last_block.hash)):
        if new_block['id'] > last_block.id + 1:
            Block.sync(
                Node.query.order_by(Node.last_connected_at.desc()).first())
        return jsonify(result='failed',
                       message="new block isn't our next block."), 403

    block = Block.deserialize(new_block)

    for new_move in new_block['moves']:
        move = Move.query.get(new_move['id'])
        if not move:
            move = Move(
                id=new_move['id'],
                user=new_move['user'],
                name=new_move['name'],
                signature=new_move['signature'],
                tax=new_move['tax'],
                details=new_move['details'],
                created_at=datetime.datetime.strptime(new_move['created_at'],
                                                      '%Y-%m-%d %H:%M:%S.%f'),
                block_id=block.id,
            )
        if not move.valid:
            return jsonify(result='failed',
                           message=f"move {move.id} isn't valid."), 400
        block.moves.append(move)
    if not block.valid:
        return jsonify(result='failed', message="new block isn't valid."), 400

    db.session.add(block)
    try:
        db.session.commit()
    except IntegrityError:
        return jsonify(result='failed',
                       message="This node already has this block."), 400
    sent_node = Node()
    if 'sent_node' in new_block:
        sent_node.url = new_block['sent_node']
    block_broadcast.delay(block.id,
                          sent_node_url=sent_node.url,
                          my_node_url=f'{request.scheme}://{request.host}')
    return jsonify(result='success')
Beispiel #5
0
def init(seed, sync):
    click.echo('Creating database...')
    db.create_all()
    click.echo(f'Updating node... (seed: {seed})')
    if seed:
        Node.update(Node.get(url=seed))
    else:
        Node.update()
    if sync:
        click.echo('Syncing blocks...')
        Block.sync(click=click)
Beispiel #6
0
def neko(private_key):
    app.app_context().push()
    while True:
        Block.sync()
        block = User(private_key).create_block(
            Move.query.filter_by(block=None).limit(20).all(),
            click=click,
        )
        if block:
            block.broadcast()
            click.echo(block)
Beispiel #7
0
    def add_block(new_block):
        block = Block()
        block.id = new_block['id']
        block.creator = new_block['creator']
        block.created_at = datetime.datetime.strptime(new_block['created_at'],
                                                      '%Y-%m-%d %H:%M:%S.%f')
        block.prev_hash = new_block['prev_hash']
        block.hash = new_block['hash']
        block.difficulty = new_block['difficulty']
        block.suffix = new_block['suffix']
        block.root_hash = new_block['root_hash']
        fx_session.add(block)

        return block
Beispiel #8
0
def init(seed, sync):
    echo('Creating database...')
    db.create_all()
    echo(f'Updating node... (seed: {seed})')
    if sync:
        Node.update(Node.get(url=seed))
        echo('Syncing blocks...')
        Block.sync(echo=echo)

    echo('Compiling translations...')
    dir_path = os.path.abspath(os.path.dirname(__file__))
    compile_command = compile_catalog()
    compile_command.directory = dir_path + '/translations'
    compile_command.finalize_options()
    compile_command.run()
Beispiel #9
0
def neko(private_key):
    app.app_context().push()
    Client(os.environ.get('SENTRY_DSN'))

    while True:
        Block.sync()
        block = User(private_key).create_block(
            [
                m for m in Move.query.filter_by(block=None).limit(20).all()
                if m.valid
            ],
            click=click,
        )
        if block:
            block.broadcast()
            click.echo(block)
Beispiel #10
0
def test_get_blocks(fx_test_client, fx_user):
    move = fx_user.sleep()

    rv = fx_test_client.get(f'/moves/{move.id}')
    assert rv.status == '200 OK'
    assert move.id.encode() in rv.data

    block = Block.create(fx_user, [move])

    rv = fx_test_client.get(f'/blocks')
    assert rv.status == '200 OK'
    assert block.hash.encode() in rv.data
    assert move.id.encode() in rv.data

    rv = fx_test_client.get(f'/blocks/{block.id}')
    assert rv.status == '200 OK'
    assert block.hash.encode() in rv.data
    assert move.id.encode() in rv.data

    rv = fx_test_client.get(f'/blocks/{block.hash}')
    assert rv.status == '200 OK'
    assert block.hash.encode() in rv.data

    rv = fx_test_client.get(f'/blocks/last')
    assert rv.status == '200 OK'
    assert block.hash.encode() in rv.data
Beispiel #11
0
def test_block_validation(fx_user, fx_novice_status):
    move = fx_user.create_novice(fx_novice_status)
    block = Block.create(fx_user, [move])
    assert block.valid
    move.id = ('00000000000000000000000000000000'
               '00000000000000000000000000000000')
    assert not block.valid
Beispiel #12
0
def sync():
    public_url = get_my_public_url()
    if public_url:
        click.echo(f"You have a public node url. ({public_url})")
        Node.broadcast(Node.post_node_endpoint, {'url': public_url})
    while True:
        try:
            prev_id = Block.query.order_by(Block.id.desc()).first().id
        except AttributeError:
            click.echo("You need to initialize. try `nekoyume init`.")
            break
        if not prev_id:
            click.echo("You need to initialize. try `nekoyume init`.")
            break
        Block.sync(click=click)
        if prev_id == Block.query.order_by(Block.id.desc()).first().id:
            click.echo("The blockchain is up to date.")
            time.sleep(15)
Beispiel #13
0
def test_prevent_hack_and_slash_when_dead(
    fx_test_client: FlaskClient,
    fx_session: Session,
    fx_user: User,
    fx_private_key: PrivateKey,
    fx_novice_status: typing.Dict[str, str],
):
    move = fx_user.create_novice(fx_novice_status)
    Block.create(fx_user, [move])

    assert fx_user.avatar().dead is False
    while fx_user.avatar().hp > 0:
        move = fx_user.hack_and_slash()
        Block.create(fx_user, [move])
    assert fx_user.avatar().dead is True

    response = fx_test_client.post('/session_moves',
                                   data={'name': 'hack_and_slash'})
    assert response.status_code == 302
Beispiel #14
0
def test_sync(fx_user, fx_session, fx_other_user, fx_other_session, fx_server,
              fx_novice_status):
    assert fx_other_session.query(Block).count() == 0
    assert fx_session.query(Block).count() == 0

    Block.sync(Node(url=fx_server.url), fx_other_session)
    assert fx_other_session.query(Block).count() == 0
    assert fx_session.query(Block).count() == 0

    fx_other_user.create_block([])
    Block.sync(Node(url=fx_server.url), fx_other_session)
    assert fx_other_session.query(Block).count() == 1
    assert fx_session.query(Block).count() == 0

    move = fx_user.create_novice(fx_novice_status)
    fx_user.create_block([move])
    fx_user.create_block([])
    fx_user.create_block([])

    assert fx_other_session.query(Block).count() == 1
    assert fx_other_session.query(Move).count() == 0
    assert fx_session.query(Block).count() == 3
    assert fx_session.query(Move).count() == 1

    Block.sync(Node(url=fx_server.url), fx_other_session)
    assert fx_other_session.query(Block).count() == 3
    assert fx_other_session.query(Move).count() == 1
    assert fx_session.query(Block).count() == 3
    assert fx_session.query(Move).count() == 1
Beispiel #15
0
def test_block_broadcast(fx_user, fx_session, fx_other_user, fx_other_session,
                         fx_server):
    assert fx_other_session.query(Block).count() == 0
    assert fx_session.query(Block).count() == 0

    fx_other_session.add(
        Node(url=fx_server.url, last_connected_at=datetime.datetime.utcnow()))
    fx_other_session.commit()

    block = Block.create(fx_other_user, [])
    block.broadcast(session=fx_other_session)
    assert fx_other_session.query(Block).count() == 1
    assert fx_session.query(Block).count() == 1
Beispiel #16
0
def test_avatar_basic_moves(fx_user, fx_novice_status):
    moves = [
        CreateNovice(details=fx_novice_status),
        HackAndSlash(),
        Sleep(),
        Say(details={'content': 'hi'}),
        LevelUp(details={'new_status': 'strength'}),
    ]
    for move in moves:
        move = fx_user.move(move)
        block = Block.create(fx_user, [move])
        assert move.valid
        assert move.confirmed
        assert block.valid
        assert fx_user.avatar(block.id)
Beispiel #17
0
def test_move_confirmed_and_validation(fx_user, fx_novice_status):
    move = Move()
    assert not move.confirmed
    assert not move.valid

    move = fx_user.create_novice(fx_novice_status)

    assert not move.confirmed
    assert move.valid

    block = Block.create(fx_user, [move])

    assert move.block_id
    assert move.confirmed
    assert move.valid

    move.tax = 1
    assert not move.valid
    assert not block.valid
Beispiel #18
0
def test_level_up(fx_user, fx_novice_status):
    move = fx_user.create_novice(fx_novice_status)
    Block.create(fx_user, [move])

    while True:
        if fx_user.avatar().exp >= 8:
            break
        move = fx_user.hack_and_slash()
        Block.create(fx_user, [move])

        if fx_user.avatar().hp <= 0:
            move = fx_user.sleep()
            Block.create(fx_user, [move])

    assert fx_user.avatar().level >= 2
Beispiel #19
0
def test_move(fx_test_client, fx_session, fx_user, fx_private_key):
    rv = fx_test_client.post('/login',
                             data={
                                 'private_key': fx_private_key.to_hex(),
                             },
                             follow_redirects=True)
    rv = fx_test_client.post('/new')
    Block.create(fx_user,
                 fx_session.query(Move).filter_by(block_id=None).all())

    rv = fx_test_client.get('/')
    assert rv.status == '200 OK'
    assert fx_user.address.encode() in rv.data

    rv = fx_test_client.post('/session_moves',
                             data={'name': 'hack_and_slash'},
                             follow_redirects=True)
    assert rv.status == '200 OK'
    Block.create(fx_user,
                 fx_session.query(Move).filter_by(block_id=None).all())

    rv = fx_test_client.post('/session_moves',
                             data={'name': 'sleep'},
                             follow_redirects=True)
    assert rv.status == '200 OK'
    Block.create(fx_user,
                 fx_session.query(Move).filter_by(block_id=None).all())

    rv = fx_test_client.post('/session_moves',
                             data={
                                 'name': 'say',
                                 'content': 'hi!',
                             },
                             follow_redirects=True)
    assert rv.status == '200 OK'
    Block.create(fx_user,
                 fx_session.query(Move).filter_by(block_id=None).all())
Beispiel #20
0
 def add_block(new_block):
     block = Block.deserialize(new_block)
     fx_session.add(block)
     return block
Beispiel #21
0
def test_flush_session_while_syncing(fx_user, fx_session, fx_other_session,
                                     fx_novice_status):
    # 1. block validation failure scenario
    # syncing without flushing can cause block validation failure
    move = fx_user.create_novice(fx_novice_status)
    invalid_block = Block.create(fx_user, [move])
    fx_session.delete(invalid_block)

    # syncing valid blocks from another node
    new_blocks = [
        {
            "created_at": "2018-04-13 11:36:17.920869",
            "creator": "ET8ngv45qwhkDiJS1ZrUxndcGTzHxjPZDs",
            "difficulty": 0,
            "hash":
            "da0182c494660af0d9dd288839ceb86498708f38c800363cd46ed1730013a4d8",  # noqa
            "id": 1,
            "version": 2,
            "moves": [],
            "prev_hash": None,
            "root_hash":
            "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",  # noqa
            "suffix": "00"
        },
        {
            "created_at": "2018-04-13 11:36:17.935392",
            "creator": "ET8ngv45qwhkDiJS1ZrUxndcGTzHxjPZDs",
            "difficulty": 1,
            "hash":
            "014c44b9382a45c2a70d817c090e6b78af22b8f34b57fd7edb474344f25c439c",  # noqa
            "id": 2,
            "version": 2,
            "moves": [],
            "prev_hash":
            "da0182c494660af0d9dd288839ceb86498708f38c800363cd46ed1730013a4d8",  # noqa
            "root_hash":
            "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",  # noqa
            "suffix": "0b"
        }
    ]

    def add_block(new_block):
        block = Block.deserialize(new_block)
        fx_session.add(block)
        return block

    valid_block1 = add_block(new_blocks[0])
    valid_block2 = add_block(new_blocks[1])

    assert invalid_block.hash == \
        fx_session.query(Block).get(valid_block2.id - 1).hash
    assert valid_block2.valid is False

    fx_session.query(Block).delete()

    # 2. valid scenario
    # flush session after deleting the invalid block
    move = fx_user.create_novice(fx_novice_status)
    invalid_block = Block.create(fx_user, [move])
    fx_session.delete(invalid_block)
    fx_session.flush()

    valid_block1 = add_block(new_blocks[0])
    valid_block2 = add_block(new_blocks[1])

    assert valid_block1.hash == \
        fx_session.query(Block).get(valid_block2.id - 1).hash
    assert valid_block2.valid