Esempio n. 1
0
def user_approve_new_token():
    """
	" Add token that approved by user. It's used for ERC20 function.
	"""
    try:
        data = request.json
        if data is None or \
         'token_id' not in data:
            return response_error(MESSAGE.INVALID_DATA, CODE.INVALID_DATA)

        uid = int(request.headers['Uid'])
        token_id = data['token_id']

        token = Token.find_token_by_id(token_id)
        if token is None or \
         token.tid is None or \
         token.status == -1:
            return response_error(MESSAGE.TOKEN_NOT_FOUND,
                                  CODE.TOKEN_NOT_FOUND)

        user = User.find_user_with_id(uid)

        if token not in user.tokens:
            user.tokens.append(token)
        else:
            return response_error(MESSAGE.TOKEN_APPROVED_ALREADY,
                                  CODE.TOKEN_APPROVED_ALREADY)

        db.session.commit()
        return response_ok(user.to_json())

    except Exception, ex:
        db.session.rollback()
        return response_error(ex.message)
Esempio n. 2
0
    def clear_data_before_test(self):
        token1 = Token.find_token_by_id(1)
        token1.tid = None
        token1.status = -1

        token2 = Token.find_token_by_id(2)
        token2.tid = None
        token2.status = -1

        # reset users
        users = db.session.query(User).filter(User.email=='*****@*****.**').all()
        for u in users:
            u.email = None

        # reset referral code
        referral = db.session.query(Referral).filter(Referral.user_id==66).first()
        if referral is not None:
            db.session.delete(referral)

        user = User.find_user_with_id(66)
        user.tokens = []

        db.session.flush()
        db.session.commit()
Esempio n. 3
0
    def test_user_approve_token(self):
        self.clear_data_before_test()

        with self.client:
            Uid = 66
            params = {
                "token_id": 1
            }
            response = self.client.post(
                                    '/approve_token',
                                    data=json.dumps(params), 
                                    content_type='application/json',
                                    headers={
                                        "Uid": "{}".format(Uid),
                                        "Fcm-Token": "{}".format(123),
                                        "Payload": "{}".format(123),
                                    })

            data = json.loads(response.data.decode()) 
            self.assertTrue(data['status'] == 0)

            # approve token first
            token = Token.find_token_by_id(1)
            token.tid = 0
            token.status = 1

            # call appprove token again
            response = self.client.post(
                                    '/approve_token',
                                    data=json.dumps(params), 
                                    content_type='application/json',
                                    headers={
                                        "Uid": "{}".format(Uid),
                                        "Fcm-Token": "{}".format(123),
                                        "Payload": "{}".format(123),
                                    })

            data = json.loads(response.data.decode()) 
            self.assertTrue(data['status'] == 1)
Esempio n. 4
0
def add_match():
    try:
        from_request = request.headers.get('Request-From', 'mobile')
        request_size = request.headers.get('Content-length')  # string
        uid = int(request.headers['Uid'])
        token_id = request.args.get('token_id')
        file_name = None
        saved_path = None

        if request.form.get('data') is None:
            return response_error(MESSAGE.INVALID_DATA, CODE.INVALID_DATA)

        item = json.loads(request.form.get('data'))
        if request.files and len(
                request.files) > 0 and request.files['image'] is not None:
            if int(
                    request_size
            ) <= CONST.UPLOAD_MAX_FILE_SIZE and storage_bl.validate_extension(
                    request.files['image'].filename,
                    CONST.UPLOAD_ALLOWED_EXTENSIONS):
                file_name, saved_path = storage_bl.handle_upload_file(
                    request.files['image'])
            else:
                return response_error(MESSAGE.FILE_TOO_LARGE,
                                      CODE.FILE_TOO_LARGE)

        if token_id is None:
            contract = contract_bl.get_active_smart_contract()
            if contract is None:
                return response_error(MESSAGE.CONTRACT_EMPTY_VERSION,
                                      CODE.CONTRACT_EMPTY_VERSION)

        else:
            token = Token.find_token_by_id(token_id)
            if token is None:
                return response_error(MESSAGE.TOKEN_NOT_FOUND,
                                      CODE.TOKEN_NOT_FOUND)

            token_id = token.id
            # refresh erc20 contract
            contract = contract_bl.get_active_smart_contract(
                contract_type=CONST.CONTRACT_TYPE['ERC20'])
            if contract is None:
                return response_error(MESSAGE.CONTRACT_EMPTY_VERSION,
                                      CODE.CONTRACT_EMPTY_VERSION)

        response_json = []
        source = None
        category = None

        if match_bl.is_validate_match_time(item) == False:
            return response_error(MESSAGE.MATCH_INVALID_TIME,
                                  CODE.MATCH_INVALID_TIME)

        if "source_id" in item:
            # TODO: check deleted and approved
            source = db.session.query(Source).filter(
                Source.id == int(item['source_id'])).first()
        elif "source" in item and "name" in item["source"] and "url" in item[
                "source"]:
            source = db.session.query(Source).filter(
                and_(Source.name == item["source"]["name"],
                     Source.url == item["source"]["url"])).first()
            if source is None:
                source = Source(name=item["source"]["name"],
                                url=item["source"]["url"],
                                created_user_id=uid)
                db.session.add(source)
                db.session.flush()
        else:
            if item['public'] == 1:
                return response_error(MESSAGE.MATCH_SOURCE_EMPTY,
                                      CODE.MATCH_SOURCE_EMPTY)

        if "category_id" in item:
            category = db.session.query(Category).filter(
                Category.id == int(item['category_id'])).first()
        else:
            if "category" in item and "name" in item["category"]:
                category = db.session.query(Category).filter(
                    Category.name == item["category"]["name"]).first()
                if category is None:
                    category = Category(name=item["category"]["name"],
                                        created_user_id=uid)
                    db.session.add(category)
                    db.session.flush()

        image_url_default = CONST.SOURCE_GC_DOMAIN.format(
            app.config['GC_STORAGE_BUCKET'],
            '{}/{}'.format(app.config.get('GC_STORAGE_FOLDER'),
                           app.config.get('GC_DEFAULT_FOLDER')),
            CONST.IMAGE_NAME_SOURCE_DEFAULT)

        if source is not None and source.image_url is not None and source.image_url != '':
            image_url_default = source.image_url

        match = Match(
            homeTeamName=item.get('homeTeamName', ''),
            homeTeamCode=item.get('homeTeamCode', ''),
            homeTeamFlag=item.get('homeTeamFlag', ''),
            awayTeamName=item.get('awayTeamName', ''),
            awayTeamCode=item.get('awayTeamCode', ''),
            awayTeamFlag=item.get('awayTeamFlag', ''),
            name=item['name'],
            public=item['public'],
            market_fee=int(item.get('market_fee', 0)),
            date=item['date'],
            reportTime=item['reportTime'],
            disputeTime=item['disputeTime'],
            created_user_id=uid,
            source_id=None if source is None else source.id,
            category_id=None if category is None else category.id,
            grant_permission=int(item.get('grant_permission', 0)),
            creator_wallet_address=item.get('creator_wallet_address'),
            outcome_name=item.get('outcome_name'),
            event_name=item.get('event_name'),
            image_url=image_url_default)
        db.session.add(match)
        db.session.flush()

        # Add default YES outcome
        outcome = Outcome(name=CONST.OUTCOME_DEFAULT_NAME,
                          match_id=match.id,
                          contract_id=contract.id,
                          modified_user_id=uid,
                          created_user_id=uid,
                          token_id=token_id,
                          from_request=from_request,
                          approved=CONST.OUTCOME_STATUS['PENDING'])
        db.session.add(outcome)
        db.session.flush()

        match_json = match.to_json()
        match_json['contract'] = contract.to_json()
        match_json['source_name'] = None if source is None else source.name
        match_json[
            'category_name'] = None if category is None else category.name

        if source is not None:
            source_json = match_bl.handle_source_data(match.source)
            match_json["source"] = source_json

        if category is not None:
            match_json["category"] = category.to_json()

        response_json.append(match_json)

        # Send mail create market
        send_email_create_market.delay(match.id, uid)

        db.session.commit()

        # Handle upload file to Google Storage
        if file_name is not None and saved_path is not None and storage_bl.check_file_exist(
                saved_path):
            upload_file_google_storage.delay(socket.gethostname(), match.id,
                                             file_name, saved_path)
        return response_ok(response_json)
    except Exception, ex:
        db.session.rollback()
        return response_error(ex.message)
Esempio n. 5
0
def create_market():
	"""
	" Admin create new markets
	"	- Based on fixtures.json
	"	- image file should be stored at /files/temp
	"""
	try:
		fixtures_path = os.path.abspath(os.path.dirname(__file__)) + '/fixtures.json'
		data = {}
		with open(fixtures_path, 'r') as f:
			data = json.load(f)

		if 'fixtures' in data:
			fixtures = data['fixtures']
			for item in fixtures:

				contract = contract_bl.get_active_smart_contract()
				if contract is None:
					return response_error(MESSAGE.CONTRACT_EMPTY_VERSION, CODE.CONTRACT_EMPTY_VERSION)

				# check token id
				token_id = item['token_id']
				if token_id is not None:
					token = Token.find_token_by_id(token_id)
					if token is None:
						return response_error(MESSAGE.TOKEN_NOT_FOUND, CODE.TOKEN_NOT_FOUND)
					token_id = token.id

					# refresh erc20 contract
					contract = contract_bl.get_active_smart_contract(contract_type=CONST.CONTRACT_TYPE['ERC20'])
					if contract is None:
						return response_error(MESSAGE.CONTRACT_EMPTY_VERSION, CODE.CONTRACT_EMPTY_VERSION)

				match = Match(
							homeTeamName=item['homeTeamName'],
							awayTeamName=item['awayTeamName'],
							name=item['name'],
							market_fee=int(item.get('market_fee', 0)),
							source_id=int(item['source_id']),
							category_id=int(item['category_id']),
							public=int(item['public']),
							date=item['date'],
							reportTime=item['reportTime'],
							disputeTime=item['disputeTime']
						)
				db.session.add(match)
				db.session.flush()

				for o in item['outcomes']:
					outcome = Outcome(
						name=o.get('name', ''),
						match_id=match.id,
						contract_id=contract.id,
						token_id=token_id,
						approved=CONST.OUTCOME_STATUS['APPROVED']
					)
					db.session.add(outcome)
					db.session.flush()

				# add Task
				task = Task(
					task_type=CONST.TASK_TYPE['REAL_BET'],
					data=json.dumps(match.to_json()),
					action=CONST.TASK_ACTION['CREATE_MARKET'],
					status=-1,
					contract_address=contract.contract_address,
					contract_json=contract.json_name
				)
				db.session.add(task)
				db.session.flush()

				# Handle upload file to Google Storage
				if item['image'] is not None and len(item['image']) > 0:
					upload_file_google_storage.delay(match.id, storage_bl.formalize_filename(os.path.basename(item['image'])), item['image'])

		db.session.commit()
		return response_ok()
	except Exception, ex:
		db.session.rollback()
		return response_error(ex.message)
def collect_free_bet():
	"""
	"	Collect free-bet in ETH
	"""
	try:
		uid = int(request.headers['Uid'])
		chain_id = int(request.headers.get('ChainId', CONST.BLOCKCHAIN_NETWORK['RINKEBY']))
		user = User.find_user_with_id(uid)

		data = request.json
		if data is None:
			return response_error(MESSAGE.INVALID_DATA, CODE.INVALID_DATA)

		offchain = data.get('offchain', '')
		if len(offchain) == 0:
			return response_error(MESSAGE.MISSING_OFFCHAIN, CODE.MISSING_OFFCHAIN)

		h = []
		s = []
		offchain = offchain.replace(CONST.CRYPTOSIGN_OFFCHAIN_PREFIX, '')
		if 's' in offchain:
			offchain = int(offchain.replace('s', ''))
			shaker = db.session.query(Shaker).filter(and_(Shaker.id==offchain, Shaker.shaker_id==user.id)).first()
			msg = handshake_bl.can_withdraw(handshake=None, shaker=shaker)
			if len(msg) != 0:
				return response_error(msg, CODE.CANNOT_WITHDRAW)
			
			hs = Handshake.find_handshake_by_id(shaker.handshake_id)
			outcome = Outcome.find_outcome_by_id(hs.outcome_id)

			# check erc20 token or not
			token = Token.find_token_by_id(outcome.token_id)
			if token is not None:
				return response_error(MESSAGE.HANDSHAKE_CANNOT_WITHDRAW_FREEBET_IN_ERC20, CODE.HANDSHAKE_CANNOT_WITHDRAW_FREEBET_IN_ERC20)

			h = db.session.query(Handshake).filter(and_(Handshake.user_id==user.id, Handshake.outcome_id==hs.outcome_id, Handshake.side==shaker.side, Handshake.status==HandshakeStatus['STATUS_INITED'])).all()
			s = db.session.query(Shaker).filter(and_(Shaker.shaker_id==user.id, Shaker.side==shaker.side, Shaker.status==HandshakeStatus['STATUS_SHAKER_SHAKED'], Shaker.handshake_id.in_(db.session.query(Handshake.id).filter(Handshake.outcome_id==hs.outcome_id)))).all()

			data['hid'] = outcome.hid
			data['winner'] = shaker.from_address

		else:
			offchain = int(offchain.replace('m', ''))
			handshake = db.session.query(Handshake).filter(and_(Handshake.id==offchain, Handshake.user_id==user.id)).first()
			msg = handshake_bl.can_withdraw(handshake)
			if len(msg) != 0:
				return response_error(msg, CODE.CANNOT_WITHDRAW)

			outcome = Outcome.find_outcome_by_id(handshake.outcome_id)

			# check erc20 token or not
			token = Token.find_token_by_id(outcome.token_id)
			if token is not None:
				return response_error(MESSAGE.HANDSHAKE_CANNOT_WITHDRAW_FREEBET_IN_ERC20, CODE.HANDSHAKE_CANNOT_WITHDRAW_FREEBET_IN_ERC20)

			h = db.session.query(Handshake).filter(and_(Handshake.user_id==user.id, Handshake.outcome_id==handshake.outcome_id, Handshake.side==handshake.side, Handshake.status==HandshakeStatus['STATUS_INITED'])).all()
			s = db.session.query(Shaker).filter(and_(Shaker.shaker_id==user.id, Shaker.side==handshake.side, Shaker.status==HandshakeStatus['STATUS_SHAKER_SHAKED'], Shaker.handshake_id.in_(db.session.query(Handshake.id).filter(Handshake.outcome_id==handshake.outcome_id)))).all()

			data['hid'] = outcome.hid
			data['winner'] = handshake.from_address


		handshakes = []
		shakers = []
		response = {}
		# update status
		for hs in h:
			hs.status = HandshakeStatus['STATUS_COLLECT_PENDING']
			db.session.flush()
			handshakes.append(hs)

			if hs.id == offchain:
				response = hs.to_json()
			
		for sk in s:
			sk.status = HandshakeStatus['STATUS_COLLECT_PENDING']
			db.session.flush()
			shakers.append(sk)

			if sk.id == offchain:
				response = sk.to_json()

		data['uid'] = uid
		data['payload'] = user.payload
		data['free_bet'] = 1

		contract = Contract.find_contract_by_id(outcome.contract_id)
		if contract is None:
			return response_error(MESSAGE.CONTRACT_INVALID, CODE.CONTRACT_INVALID)

		# add task
		task = Task(
			task_type=CONST.TASK_TYPE['FREE_BET'],
			data=json.dumps(data),
			action=CONST.TASK_ACTION['COLLECT'],
			status=-1,
			contract_address=contract.contract_address,
			contract_json=contract.json_name
		)
		db.session.add(task)
		db.session.commit()

		handshake_bl.update_handshakes_feed(handshakes, shakers)
		return response_ok(response)

	except Exception, ex:
		db.session.rollback()
		return response_error(ex.message)
def uninit_free_bet(handshake_id):
	"""
	"	Uninit free-bet in ETH
	"""
	try:
		uid = int(request.headers['Uid'])
		chain_id = int(request.headers.get('ChainId', CONST.BLOCKCHAIN_NETWORK['RINKEBY']))
		user = User.find_user_with_id(uid)

		handshake = db.session.query(Handshake).filter(and_(Handshake.id==handshake_id, Handshake.chain_id==chain_id, Handshake.user_id==uid, Handshake.free_bet==1)).first()
		if handshake is not None and \
			(handshake.status == CONST.Handshake['STATUS_INITED'] or \
			handshake.status == CONST.Handshake['STATUS_MAKER_SHOULD_UNINIT']):

			if handshake_bl.can_uninit(handshake) == False:
				return response_error(MESSAGE.HANDSHAKE_CANNOT_UNINIT, CODE.HANDSHAKE_CANNOT_UNINIT)
			else:

				outcome = Outcome.find_outcome_by_id(handshake.outcome_id)
				if outcome is None:
					return response_error(MESSAGE.OUTCOME_INVALID, CODE.OUTCOME_INVALID)
				else:
					# check erc20 token or not
					token = Token.find_token_by_id(outcome.token_id)
					if token is not None:
						return response_error(MESSAGE.HANDSHAKE_CANNOT_UNINIT_FREE_BET_IN_ERC20, CODE.HANDSHAKE_CANNOT_UNINIT_FREE_BET_IN_ERC20)

					contract = Contract.find_contract_by_id(outcome.contract_id)
					if contract is None:
						return response_error(MESSAGE.CONTRACT_INVALID, CODE.CONTRACT_INVALID)

					handshake.status = CONST.Handshake['STATUS_MAKER_UNINIT_PENDING']
					db.session.flush()
					
					data = {
						'hid': outcome.hid,
						'side': handshake.side,
						'odds': handshake.odds,
						'maker': handshake.from_address,
						'value': handshake.amount,
						'offchain': CONST.CRYPTOSIGN_OFFCHAIN_PREFIX + 'm{}'.format(handshake.id),
						'uid': uid,
						'payload': user.payload,
						'free_bet': 1
					}

					task = Task(
						task_type=CONST.TASK_TYPE['FREE_BET'],
						data=json.dumps(data, use_decimal=True),
						action=CONST.TASK_ACTION['UNINIT'],
						status=-1,
						contract_address=contract.contract_address,
						contract_json=contract.json_name
					)
					db.session.add(task)
					db.session.commit()

					update_feed.delay(handshake.id)
					return response_ok(handshake.to_json())
					
		else:
			return response_error(MESSAGE.HANDSHAKE_NOT_FOUND, CODE.HANDSHAKE_NOT_FOUND)	


	except Exception, ex:
		db.session.rollback()
		return response_error(ex.message)
def create_free_bet():
	"""
	"	Create a free-bet in ETH
	"""
	try:
		setting = Setting.find_setting_by_name(CONST.SETTING_TYPE['FREE_BET'])
		if setting is not None and setting.status == 0:
			return response_error(MESSAGE.FREE_BET_UNABLE, CODE.FREE_BET_UNABLE)

		uid = int(request.headers['Uid'])
		chain_id = int(request.headers.get('ChainId', CONST.BLOCKCHAIN_NETWORK['RINKEBY']))
		user = User.find_user_with_id(uid)

		data = request.json
		if data is None:
			return response_error(MESSAGE.INVALID_DATA, CODE.INVALID_DATA)

		redeem = data.get('redeem', '')
		match_id = data.get('match_id', -1)
		odds = Decimal(data.get('odds', Decimal('2')))
		amount = Decimal(CONST.CRYPTOSIGN_FREE_BET_AMOUNT)
		side = int(data.get('side', CONST.SIDE_TYPE['SUPPORT']))
		from_address = data.get('from_address', '')

		# check valid address
		if len(from_address) < 40:
			return response_error(MESSAGE.INVALID_ADDRESS, CODE.INVALID_ADDRESS)

		# check valid redeem or not
		r = Redeem.find_redeem_by_code_and_user(redeem, uid)
		if r is None:
			return response_error(MESSAGE.REDEEM_NOT_FOUND, CODE.REDEEM_NOT_FOUND)
		else:
			if r.used_user > 0:
				return response_error(MESSAGE.REDEEM_INVALID, CODE.REDEEM_INVALID)
			r.used_user = uid
			db.session.flush()

		outcome_id = data.get('outcome_id')
		outcome = None
		if match_id == -1:
			outcome = Outcome.find_outcome_by_id(outcome_id)
			if outcome is None:
				return response_error(MESSAGE.OUTCOME_INVALID, CODE.OUTCOME_INVALID)
			elif outcome.result != -1:
				return response_error(MESSAGE.OUTCOME_HAS_RESULT, CODE.OUTCOME_HAS_RESULT)

		else:
			match = Match.find_match_by_id(match_id)
			if match is not None and len(match.outcomes.all()) > 0:
				outcome = match.outcomes[0]
			else:
				return response_error(MESSAGE.MATCH_NOT_FOUND, CODE.MATCH_NOT_FOUND)

		# check erc20 token or not
		token = Token.find_token_by_id(outcome.token_id)
		if token is not None:
			return response_error(MESSAGE.HANDSHAKE_CANNOT_CREATE_FREEBET_IN_ERC20, CODE.HANDSHAKE_CANNOT_CREATE_FREEBET_IN_ERC20)

		contract = Contract.find_contract_by_id(outcome.contract_id)
		if contract is None:
			return response_error(MESSAGE.CONTRACT_INVALID, CODE.CONTRACT_INVALID)

		match = Match.find_match_by_id(outcome.match_id)
		data['hid'] = outcome.hid
		data['outcome_name'] = outcome.name
		data['match_date'] = match.date
		data['match_name'] = match.name
		data['uid'] = uid
		data['payload'] = user.payload
		data['free_bet'] = 1
		data['amount'] = CONST.CRYPTOSIGN_FREE_BET_AMOUNT

		user.free_bet += 1
		task = Task(
			task_type=CONST.TASK_TYPE['FREE_BET'],
			data=json.dumps(data),
			action=CONST.TASK_ACTION['INIT'],
			status=-1,
			contract_address=contract.contract_address,
			contract_json=contract.json_name
		)
		db.session.add(task)
		db.session.commit()

		# this is for frontend
		handshakes = handshake_bl.find_all_matched_handshakes(side, odds, outcome.id, amount, uid)
		response = {}
		if len(handshakes) == 0:
			response['match'] = 0
		else:
			response['match'] = 1
		return response_ok(response)

	except Exception, ex:
		db.session.rollback()
		return response_error(ex.message)
def init():
	"""
	" User plays bet in binary event.
	"""
	try:
		from_request = request.headers.get('Request-From', 'mobile')
		uid = int(request.headers['Uid'])
		chain_id = int(request.headers.get('ChainId', CONST.BLOCKCHAIN_NETWORK['RINKEBY']))
		user = User.find_user_with_id(uid)		

		data = request.json
		if data is None:
			return response_error(MESSAGE.INVALID_DATA, CODE.INVALID_DATA)

		hs_type = data.get('type', -1)
		extra_data = data.get('extra_data', '')
		description = data.get('description', '')
		outcome_id = data.get('outcome_id', -1)
		match_id = data.get('match_id', -1)
		odds = Decimal(data.get('odds', '2')).quantize(Decimal('.1'), rounding=ROUND_HALF_DOWN)
		amount = Decimal(data.get('amount'))
		currency = data.get('currency', 'ETH')
		side = int(data.get('side', CONST.SIDE_TYPE['SUPPORT']))
		chain_id = int(data.get('chain_id', CONST.BLOCKCHAIN_NETWORK['RINKEBY']))
		from_address = data.get('from_address', '')
		free_bet = data.get('free_bet', 0)

		print '-------- DEBUG INIT -------'
		print '-------- amount = {}, type = {}, request = {} -------'.format(amount, type(amount), data.get('amount'))

		if hs_type != CONST.Handshake['INDUSTRIES_BETTING']:
			return response_error(MESSAGE.HANDSHAKE_INVALID_BETTING_TYPE, CODE.HANDSHAKE_INVALID_BETTING_TYPE)

		if len(from_address) < 40:
			return response_error(MESSAGE.INVALID_ADDRESS, CODE.INVALID_ADDRESS)

		# check valid outcome or not
		outcome = None
		if match_id == -1:
			outcome = Outcome.find_outcome_by_id(outcome_id)
		else:
			match = Match.find_match_by_id(match_id)
			if match is not None and len(match.outcomes.all()) > 0:
				outcome = match.outcomes[0]

		if outcome is None:
			return response_error(MESSAGE.OUTCOME_INVALID, CODE.OUTCOME_INVALID)

		if outcome.result != CONST.RESULT_TYPE['PENDING']:
			return response_error(MESSAGE.OUTCOME_HAS_RESULT, CODE.OUTCOME_HAS_RESULT)

		outcome_id = outcome.id

		# make sure user cannot call free-bet in ERC20
		if free_bet == 1:
			token = Token.find_token_by_id(outcome.token_id)
			if token is not None:
				return response_error(MESSAGE.HANDSHAKE_CANNOT_CREATE_FREEBET_IN_ERC20, CODE.HANDSHAKE_CANNOT_CREATE_FREEBET_IN_ERC20)

		if odds <= 1:
			return response_error(MESSAGE.INVALID_ODDS, CODE.INVALID_ODDS)

		contract = Contract.find_contract_by_id(outcome.contract_id)
		if contract is None:
			return response_error(MESSAGE.CONTRACT_INVALID, CODE.CONTRACT_INVALID)

		# add to history
		history = History(			
			chain_id=chain_id,
			description=description,
			free_bet=free_bet,
			from_address=from_address,
			contract_address=contract.contract_address,
			contract_json=contract.json_name,
			odds=odds,
			amount=amount,
			currency=currency,
			from_request=from_request,
			side=side,
			user_id=uid,
			outcome_id=outcome_id
		)
		db.session.add(history)
		db.session.flush()

		# filter all handshakes which able be to match first
		handshakes = handshake_bl.find_all_matched_handshakes(side, odds, outcome_id, amount, uid)
		arr_hs = []
		if len(handshakes) == 0:
			handshake = Handshake(
				hs_type=hs_type,
				extra_data=extra_data,
				description=description,
				chain_id=chain_id,
				user_id=user.id,
				outcome_id=outcome_id,
				odds=odds,
				amount=amount,
				currency=currency,
				side=side,
				remaining_amount=amount,
				from_address=from_address,
				free_bet=free_bet,
				contract_address=contract.contract_address,
				contract_json=contract.json_name,
				from_request=from_request,
				history_id=history.id
			)

			db.session.add(handshake)
			db.session.commit()

			update_feed.delay(handshake.id)

			# response data
			hs_json = handshake.to_json()
			hs_json['maker_address'] = handshake.from_address
			hs_json['maker_odds'] = handshake.odds
			hs_json['hid'] = outcome.hid
			hs_json['type'] = 'init'
			hs_json['offchain'] = CONST.CRYPTOSIGN_OFFCHAIN_PREFIX + 'm' + str(handshake.id)
			arr_hs.append(hs_json)

			logfile.debug("Uid -> {}, json --> {}".format(uid, arr_hs))
		else:
			shaker_amount = amount

			hs_feed = []
			sk_feed = []
			for handshake in handshakes:
				if shaker_amount.quantize(Decimal('.00000000000000001'), rounding=ROUND_DOWN) <= 0:
					break

				handshake.shake_count += 1
				handshake_win_value = handshake.remaining_amount*handshake.odds
				shaker_win_value = shaker_amount*odds
				subtracted_amount_for_shaker = 0
				subtracted_amount_for_handshake = 0


				if is_equal(handshake_win_value, shaker_win_value):
					subtracted_amount_for_shaker = shaker_amount
					subtracted_amount_for_handshake = handshake.remaining_amount

				elif handshake_win_value >= shaker_win_value:
					subtracted_amount_for_shaker = shaker_amount
					subtracted_amount_for_handshake = shaker_win_value - subtracted_amount_for_shaker

				else:
					subtracted_amount_for_handshake = handshake.remaining_amount
					subtracted_amount_for_shaker = handshake_win_value - subtracted_amount_for_handshake

				handshake.remaining_amount -= subtracted_amount_for_handshake
				shaker_amount -= subtracted_amount_for_shaker
				db.session.merge(handshake)

				o = Outcome.find_outcome_by_id(handshake.outcome_id)

				if o is None:
					return response_error(MESSAGE.OUTCOME_INVALID, CODE.OUTCOME_INVALID)

				c = Contract.find_contract_by_id(o.contract_id)
				if c is None:
					return response_error(MESSAGE.CONTRACT_INVALID, CODE.CONTRACT_INVALID)

				# create shaker
				shaker = Shaker(
					shaker_id=user.id,
					amount=subtracted_amount_for_shaker,
					currency=currency,
					odds=odds,
					side=side,
					handshake_id=handshake.id,
					from_address=from_address,
					chain_id=chain_id,
					free_bet=free_bet,
					contract_address=c.contract_address,
					contract_json=c.json_name,
					from_request=from_request,
					history_id=history.id
				)

				db.session.add(shaker)
				db.session.flush()
				sk_feed.append(shaker)
				
				shaker_json = shaker.to_json()
				shaker_json['maker_address'] = handshake.from_address
				shaker_json['maker_odds'] = handshake.odds
				shaker_json['hid'] = outcome.hid
				shaker_json['type'] = 'shake'
				shaker_json['offchain'] = CONST.CRYPTOSIGN_OFFCHAIN_PREFIX + 's' + str(shaker.id)
				arr_hs.append(shaker_json)

			if shaker_amount.quantize(Decimal('.00000000000000001'), rounding=ROUND_DOWN) > Decimal(CONST.CRYPTOSIGN_MINIMUM_MONEY):
				handshake = Handshake(
					hs_type=hs_type,
					extra_data=extra_data,
					description=description,
					chain_id=chain_id,
					user_id=user.id,
					outcome_id=outcome_id,
					odds=odds,
					amount=shaker_amount,
					currency=currency,
					side=side,
					remaining_amount=shaker_amount,
					from_address=from_address,
					free_bet=free_bet,
					contract_address=contract.contract_address,
					contract_json=contract.json_name,
					from_request=from_request,
					history_id=history.id
				)
				db.session.add(handshake)
				db.session.flush()
				hs_feed.append(handshake)			

				hs_json = handshake.to_json()
				hs_json['maker_address'] = handshake.from_address
				hs_json['maker_odds'] = handshake.odds
				hs_json['hid'] = outcome.hid
				hs_json['type'] = 'init'
				hs_json['offchain'] = CONST.CRYPTOSIGN_OFFCHAIN_PREFIX + 'm' + str(handshake.id)
				arr_hs.append(hs_json)
			
			db.session.commit()
			logfile.debug("Uid -> {}, json --> {}".format(uid, arr_hs))

			handshake_bl.update_handshakes_feed(hs_feed, sk_feed)

		# make response
		response = {
			"handshakes": arr_hs,
			"total_bets": handshake_bl.get_total_real_bets()
		}
		return response_ok(response)

	except Exception, ex:
		db.session.rollback()
		return response_error(ex.message)
Esempio n. 10
0
    def init_data_before_test(self):
        # create token
        token = Token.find_token_by_id(1)
        if token is None:
            token = Token(id=1, name="SHURIKEN", symbol="SHURI", decimal=18)
            db.session.add(token)
            db.session.commit()

        # create contract
        contract = Contract.find_contract_by_id(1)
        if contract is None:
            contract = Contract(id=1,
                                contract_name="contract1",
                                contract_address="0x123",
                                json_name="name1")
            db.session.add(contract)
            db.session.commit()

        # create match
        match = Match.find_match_by_id(1)
        if match is None:
            match = Match(id=1)
            db.session.add(match)
            db.session.commit()

        # create user
        user = User.find_user_with_id(88)
        if user is None:
            user = User(id=88)
            db.session.add(user)
            db.session.commit()

        user = User.find_user_with_id(99)
        if user is None:
            user = User(id=99)
            db.session.add(user)
            db.session.commit()

        user = User.find_user_with_id(100)
        if user is None:
            user = User(id=100)
            db.session.add(user)
            db.session.commit()

        user = User.find_user_with_id(109)
        if user is None:
            user = User(id=109)
            db.session.add(user)
            db.session.commit()

        user = User.find_user_with_id(66)
        if user is None:
            user = User(id=66)
            db.session.add(user)
            db.session.commit()

        # create outcome
        outcome = Outcome.find_outcome_by_id(88)
        if outcome is None:
            outcome = Outcome(id=88,
                              match_id=1,
                              hid=88,
                              contract_id=contract.id)
            db.session.add(outcome)
            db.session.commit()
        else:
            outcome.result = -1
            outcome.contract_id = contract.id
            db.session.commit()

        # add redeem
        try:
            for i in range(1, 3):
                chars = string.ascii_uppercase + string.ascii_lowercase
                code = ''.join(random.choice(chars) for _ in range(i))
                if Redeem.find_redeem_by_code(code) is None:
                    r = Redeem(code=code)
                    db.session.add(r)
                    db.session.commit()
        except Exception as ex:
            db.session.rollback()