Exemplo n.º 1
0
async def test_update_operation():
    from src.dto import BitSharesOperation as BitSharesOperationDTO

    async with (await get_test_engine()).acquire() as conn:
        operation = BitsharesOperation(
            op_id=666,
            order_type=OrderType.WITHDRAWAL,
            to_account=testnet_gateway_account_mock,
        )

        await add_operation(conn, operation)

        req = await get_operation(conn, 666)
        op_dto = rowproxy_to_dto(req, BitsharesOperation,
                                 BitSharesOperationDTO)

        op_dto.status = TxStatus.RECEIVED_AND_CONFIRMED

        updated_op = BitsharesOperation(**op_dto.__dict__)
        await update_operation(conn, updated_op)
        current_value = (await get_operation(conn, 666)).status
        assert current_value == TxStatus.RECEIVED_AND_CONFIRMED

        await conn.execute(
            delete(BitsharesOperation).where(BitsharesOperation.op_id == 666))
Exemplo n.º 2
0
    async def watch_unconfirmed_operations(self):
        """Grep unconfirmed transactions from base and try to confirm it"""
        log.info(f"Watching unconfirmed operations")
        while True:
            async with self.db.acquire() as conn:

                unconfirmed_ops = await get_unconfirmed_operations(conn)
                for op in unconfirmed_ops:

                    op_dto = rowproxy_to_dto(
                        op, BitsharesOperation, BitSharesOperationDTO
                    )
                    is_changed = await confirm_op(op_dto)
                    if is_changed:
                        updated_op = BitsharesOperation(**op_dto.__dict__)
                        await update_operation(
                            conn, updated_op, BitsharesOperation.op_id, updated_op.op_id
                        )

                        updated_tx = TransactionDTO(
                            coin=op_dto.asset,
                            amount=op_dto.amount,
                            tx_id=f"{op_dto.op_id}:{op_dto.tx_hash}",
                            from_address=op_dto.from_account,
                            to_address=op_dto.to_account,
                            created_at=op_dto.tx_created_at,
                            confirmations=op_dto.confirmations,
                            max_confirmations=BITSHARES_NEED_CONF,
                        )

                        if op_dto.order_type == OrderType.DEPOSIT:
                            order_dto_to_update = OrderDTO(
                                order_id=op_dto.order_id, out_tx=updated_tx
                            )
                        elif op_dto.order_type == OrderType.WITHDRAWAL:
                            order_dto_to_update = OrderDTO(
                                order_id=op_dto.order_id, in_tx=updated_tx
                            )
                        else:
                            raise

                        remote_update = await self.booker_cli.update_order_request(
                            order_dto_to_update
                        )

                        if hasattr(remote_update, "is_updated"):
                            log.info(
                                f"Update order {order_dto_to_update.order_id} "
                                f"on booker side: {remote_update.is_updated}"
                            )

            await asyncio.sleep(BITSHARES_BLOCK_TIME)
Exemplo n.º 3
0
async def watch_unconfirmed_operations():
    """Grep unconfirmed transactions from base and try to confirm it"""
    log.info(f"Watching unconfirmed operations")
    while True:
        async with ctx.db().acquire() as conn:

            unconfirmed_ops = await get_unconfirmed_operations(conn)
            for op in unconfirmed_ops:

                op_dto = rowproxy_to_dto(op, BitsharesOperation, BitSharesOperationDTO)
                is_changed = await confirm_op(op_dto)
                if is_changed:
                    updated_op = BitsharesOperation(**op_dto.__dict__)
                    await update_operation(conn, updated_op)

        await asyncio.sleep(BITSHARES_BLOCK_TIME)
Exemplo n.º 4
0
    async def broadcast_transactions(self):
        """Grep all WAIT-status transaction from database and broatcast it all. If ok, update order on booker"""
        while True:
            async with self.db.acquire() as conn:
                pending_ops = await get_pending_operations(conn)

                for op in pending_ops:

                    op_dto = rowproxy_to_dto(
                        op, BitsharesOperation, BitSharesOperationDTO
                    )

                    _transfer_body = await asset_transfer(
                        account=op_dto.from_account,
                        to=op_dto.to_account,
                        amount=op_dto.amount,
                        asset=op_dto.asset,
                    )

                    transfer = await broadcast_tx(_transfer_body)

                    if transfer:
                        log.info(
                            f"Broadcast {transfer['id']} transaction as part of order {op_dto.order_id} successful"
                        )

                        op_dto.tx_hash = transfer["id"]
                        op_dto.block_num = transfer["block_num"]
                        op_dto.tx_expiration = transfer["expiration"]

                        updated_op = BitsharesOperation(pk=op.pk, **op_dto.__dict__)

                        await update_operation(
                            conn,
                            updated_op,
                            BitsharesOperation.order_id,
                            updated_op.order_id,
                        )

            await asyncio.sleep(1)
Exemplo n.º 5
0
    async def watch_account_history(self):
        """
        BitShares Gateway account monitoring

        All new operations will be validate and insert in database. Booker will be notified about it.
        """

        log.info(
            f"Watching {self.bitshares_instance.config['default_account']} for new operations started"
        )
        async with self.db.acquire() as conn:
            gateway_wallet = await get_gateway_wallet(conn, self.cfg.account)

        last_op = gateway_wallet.last_operation

        while True:
            new_ops = await wait_new_account_ops(last_op=last_op)
            log.info(f"Found new {len(new_ops)} operations")

            for op in new_ops:
                # BitShares have '1.11.1234567890' so need to retrieve integer ID of operation
                op_id = op["id"].split(".")[2]
                last_op = op_id

                op_dto = await validate_op(op, cfg=self.cfg)
                async with self.db.acquire() as conn:
                    async with conn.begin("SERIALIZABLE") as transaction:
                        if op_dto is not None:
                            if op_dto.order_type == OrderType.WITHDRAWAL:
                                # if operation is relevant WITHDRAWAL, add it to database
                                op_to_insert = BitsharesOperation(**op_dto.__dict__)
                                await insert_operation(conn, op_to_insert)
                            else:
                                op_from_db = await get_operation_by_hash(
                                    conn, op_dto.tx_hash
                                )
                                if op_from_db is None:
                                    continue
                                op_from_db_dto = rowproxy_to_dto(
                                    op_from_db,
                                    BitsharesOperation,
                                    BitSharesOperationDTO,
                                )

                                assert not op_from_db_dto.op_id
                                assert op_from_db_dto.block_num == op_dto.block_num

                                op_from_db_dto.op_id = op_dto.op_id
                                op_from_db_dto.status = TxStatus.RECEIVED_NOT_CONFIRMED
                                op_from_db_dto.error = op_dto.error
                                op_from_db_dto.memo = op_dto.memo
                                op_from_db_dto.confirmations = 0
                                op_from_db_dto.tx_created_at = op_dto.tx_created_at

                                op_to_update = BitsharesOperation(
                                    pk=op_from_db["pk"], **op_from_db_dto.__dict__
                                )

                                await update_operation(
                                    conn,
                                    op_to_update,
                                    BitsharesOperation.order_id,
                                    op_to_update.order_id,
                                )

                        # Just refresh last account operations in database
                        await update_last_operation(
                            conn,
                            account_name=self.bitshares_instance.config[
                                "default_account"
                            ],
                            last_operation=op_id,
                        )