Пример #1
0
def get_or_create_burn_request(player_address, mon_id, mon_level=1, mon_exp=1, amount_type=BurnRewardTypes.UNDEFINED, amount_value=0, status=BurnStatus.INIT):
	burn_request = get_burn_request_by_mon(player_address, mon_id)\
		.filter(status__in=[BurnStatus.INIT, BurnStatus.PENDING])\
		.first()

	if burn_request:
		if burn_request.mon_level != mon_level or burn_request.mon_exp != mon_exp:
			burn_request.mon_level = mon_level
			burn_request.mon_exp = mon_exp
			burn_request.save()
		return burn_request

	burn_request = EtheremonDB.BurnMonTab(
		player_address=player_address,
		mon_id=mon_id,
		mon_level=mon_level,
		mon_exp=mon_exp,
		amount_type=amount_type,
		amount_value=amount_value,
		status=status,
		create_time=get_timestamp(),
		update_time=get_timestamp(),
	)
	burn_request.save()
	return burn_request
Пример #2
0
def create_transaction(player_uid,
                       player_address,
                       txn_type,
                       txn_info,
                       amount_type,
                       amount_value,
                       status=TxnStatus.INIT,
                       txn_hash=None,
                       extra=None):
    txn = EtheremonDB.TransactionTab(
        player_uid=player_uid,
        player_address=player_address,
        txn_type=txn_type,
        txn_info=txn_info,
        txn_hash=txn_hash,
        status=status,
        amount_type=amount_type,
        amount_value=round(amount_value, 4),
        extra=extra if extra is None else json.dumps(extra),
        create_time=get_timestamp(),
        update_time=get_timestamp(),
    )

    txn.save()
    return txn
Пример #3
0
def crawl_adventure_presale():
    infura_client = InfuraClient(INFURA_API_URL)
    adventure_presale_contract = infura_client.getAdventurePresaleContract()

    current_ts = get_timestamp()
    site_id_index = 1
    while site_id_index <= 54:
        site_item_index = 0
        while site_item_index < 10:
            try:
                (bidder, bid_id, site_id, amount, bid_time
                 ) = adventure_presale_contract.call().getBidBySiteIndex(
                     site_id_index, site_item_index)
                if bid_id == 0:
                    log.warn(
                        "query_adventure_presale_invalid|site_id=%s,site_index=%s",
                        site_id_index, site_item_index)
                    time.sleep(3)
                    continue
            except Exception as error:
                logging.exception(
                    "query_adventure_presale_exception|site_id=%s,site_index=%s",
                    site_id_index, site_item_index)
                time.sleep(3)
                continue

            bidder = bidder.lower()
            record = EtheremonDB.EmaAdventurePresaleTab.objects.filter(
                bid_id=bid_id).first()
            if record:
                record.site_id = site_id
                record.bid_id = bid_id
                record.site_index = site_item_index
                record.bidder = bidder
                record.bid_amount = amount
                record.bid_time = bid_time

            else:
                record = EtheremonDB.EmaAdventurePresaleTab(
                    site_id=site_id,
                    site_index=site_item_index,
                    bid_id=bid_id,
                    bidder=bidder,
                    bid_amount=amount,
                    bid_time=bid_time,
                    token_id=0,
                    update_time=current_ts)
            log.data(
                "adventure_presale_query|site_id=%s,site_index=%s,bid_id=%s",
                site_id_index, site_item_index, bid_id)
            record.save()

            site_item_index += 1

        site_id_index += 1
Пример #4
0
def initialize_energy_if_not_exist(trainer_address, init_amount=10):
	record = EtheremonDB.EmaPlayerEnergyTab.objects.filter(trainer=trainer_address).first()
	current_ts = get_timestamp()

	if not record:
		record = EtheremonDB.EmaPlayerEnergyTab(
			trainer=trainer_address,
			init_amount=init_amount,
			free_amount=0,
			paid_amount=0,
			invalid_amount=0,
			consumed_amount=0,
			last_claim_time=0,
			create_time=current_ts,
			update_time=current_ts
		)
		record.save()

	return record
def update_adventure_nft_contract():
	infura_client = InfuraClient(INFURA_API_URL)
	current_block = infura_client.getCurrentBlock() - 2

	start_block = ema_settings_manager.get_setting_value(EmaSetting.SETTING_CONTRACT_ADVENTURE_ITEM)
	end_block = start_block + SMART_CONTRACT_BLOCK_STEP

	start_time = time.time()
	event_list = get_event_list(EtheremonAdventureItemContract.ADDRESS, start_block, end_block, ETHERSCAN_API_KEY, TOPIC_TRANSFER)
	if event_list is None:
		return

	log.data("start_update_adventure_nft_contract|current_block=%s,start_block=%s,end_block=%s,len_event=%s", current_block, start_block, end_block, len(event_list))

	latest_load_block = start_block
	token_id_set = set()
	token_id_address_dict = {}
	from_address_set = set()
	for event in event_list:
		latest_load_block = max(latest_load_block, int(event["blockNumber"], 16))
		if latest_load_block > current_block:
			return
		token_id_hash = event["topics"][3]
		token_id = Web3.toInt(hexstr=token_id_hash)
		token_id_set.add(token_id)
		from_address = '0x' + event["topics"][1][26:].lower()
		token_address = '0x' + event["topics"][2][26:].lower()
		from_address_set.add(from_address)
		if token_id in token_id_address_dict:
			token_id_address_dict[token_id].add(token_address)
		else:
			token_id_address_dict[token_id] = set([token_address])
		log.info("scan_adventure_event|txn_hash=%s,token_id=%s,target_address=%s,from_address=%s", event["transactionHash"], token_id, token_address, from_address)

	current_ts = get_timestamp()
	if token_id_set:
		adventure_item_contract = infura_client.getAdventureItemContract()
		for token_id in token_id_set:
			try:
				owner = adventure_item_contract.call().ownerOf(token_id)
			except Exception as error:
				log.info("error_owner_token|token_id=%s", token_id)
				owner = EMPTY_ADDRESS
			owner = owner.lower()
			if owner not in token_id_address_dict[token_id]:
				# Case current owner is different from the old transaction => ignore
				log.warn("adventure_item_owner_invalid|token_id=%s,owner=%s,owner_set=%s", token_id, owner, token_id_address_dict[token_id])
				continue
			(item_class, item_value) = adventure_item_contract.call().getItemInfo(token_id)
			if item_class == 0:
				log.warn("adventure_item_class_invalid|token_id=%s,item_class=%s,item_value=%s", token_id, item_class, item_value)
				return
			token_record = EtheremonDB.EmaAdventureItemTab.objects.filter(token_id=token_id).first()
			if token_record:
				token_record.owner = owner
				token_record.class_id = item_class
				token_record.value = item_value
				token_record.update_time = current_ts
			else:
				token_record = EtheremonDB.EmaAdventureItemTab(
					token_id=token_id,
					owner=owner,
					class_id=item_class,
					value=item_value,
					update_time=current_ts
				)
			token_record.save()

			# update claim
			if token_id < 1081:
				if token_id % 10 == 0:
					site_id = token_id / 10
					site_index = 9
				else:
					site_id = token_id / 10 + 1
					site_index = token_id % 10 - 1
				EtheremonDB.EmaAdventurePresaleTab.objects.filter(site_id=site_id).filter(site_index=site_index).update(token_id=token_id)

	# sync player data
	if from_address_set:
		log.info("update_adventure_nft_contract|sender_len=%s,latest_load_block=%s", len(from_address_set), latest_load_block)
		data_contract = infura_client.getDataContract()
		for player in from_address_set:
			result = _sync_player_dex(data_contract, player, None, True)
			if result is False:
				log.warn("sync_player_fail|player=%s", player)
				return
			log.info("contract_adventure_nft_sync_player|sync_player=%s,block=%s", player, current_block)

	record_block = latest_load_block
	if len(token_id_set) > 0:
		record_block += 1
		if record_block > current_block:
			record_block = current_block

	ema_settings_manager.set_setting(EmaSetting.SETTING_CONTRACT_ADVENTURE_ITEM, record_block)
	elapsed = time.time() - start_time
	if elapsed < 5:
		time.sleep(5-elapsed)
	log.data("end_update_adventure_item_contract|record_block=%s,total_txn=%s,total_token=%s,elapsed=%s", record_block, len(event_list), len(token_id_set), elapsed)
Пример #6
0
def cal_txn(contract_address, default_block=START_BLOCK):
    total_count = 0

    start_block = EtheremonDB.RevenueTxnTab.objects.filter(
        contract_address=contract_address).all().aggregate(Max('block_number'))
    if not start_block["block_number__max"]:
        start_block = default_block[contract_address]
    else:
        start_block = start_block["block_number__max"]

    print start_block
    while True:
        end_block = start_block + SMART_CONTRACT_BLOCK_STEP

        time.sleep(3)
        transaction_list = get_txn_list(contract_address, start_block,
                                        end_block,
                                        ETHERSCAN_API_KEYS["cron_3"])
        if transaction_list is None:
            break

        if len(transaction_list) == 0:
            break

        new_row = 0
        for transaction in transaction_list:
            if len(transaction["input"]) < SMART_CONTRACT_METHOD_ID_LENGTH:
                log.warn("invalid_smart_contract_txn|transaction=%s",
                         transaction)
                continue
            if int(transaction.get("isError", 1)) != 0:
                continue
            if int(transaction.get("txreceipt_status")) != 1:
                continue

            block_number = int(transaction["blockNumber"])
            start_block = max(start_block, block_number)

            eth_amount = long(transaction["value"])
            if eth_amount == 0:
                continue

            txn_time = int(transaction["timeStamp"])
            catch_date_str = _getDate(txn_time)
            catch_date_int = _getDateInInteger(txn_time)

            eth_amount = float(eth_amount * 1.0 / (10**18))
            if catch_date_str not in ETH_PRICE_DICT:
                #print "--- missing ETH price:", catch_date_str
                #break
                usd_amount = 0
            else:
                usd_amount = float(eth_amount * ETH_PRICE_DICT[catch_date_str])

            method_id = str(transaction["input"]
                            [0:SMART_CONTRACT_METHOD_ID_LENGTH]).lower()
            sender = str(transaction["from"]).lower()
            txn_hash = str(transaction["hash"]).lower()

            current_record = EtheremonDB.RevenueTxnTab.objects.filter(
                txn_hash=txn_hash).first()
            if not current_record:
                EtheremonDB.RevenueTxnTab(contract_address=contract_address,
                                          method_id=method_id,
                                          txn_hash=txn_hash,
                                          sender=sender,
                                          eth_amount=eth_amount,
                                          usd_amount=usd_amount,
                                          block_number=block_number,
                                          create_date=catch_date_int,
                                          timestamp=txn_time).save()
                new_row += 1
                total_count += 1
        if new_row == 0:
            break

    print "query:contract=%s,total_added=%s,block=%s" % (
        contract_address, total_count, start_block)
Пример #7
0
def _sync_monster_id(data_contract, monster_id, transform_contract=None, base_stats_refresh=False):
	add_count = 0
	update_count = 0

	# check monster is existed or not
	monster_record = EtheremonDB.EmaMonsterDataTab.objects.filter(monster_id=monster_id).first()
	if monster_record and monster_record.class_id == 21:
		# skip non important monster
		return True, 0, 0

	(monster_return_id, class_id, owner_address, exp, create_index, last_claim_index, monster_create_time) = data_contract.call().getMonsterObj(monster_id)
	if int(class_id) == 0:  # Bug, break
		log.error('update_ema_monster_error|monster_id=%s', monster_id)
		return False, 0, 0

	log.info("sync_monster_id|contract_data|monster_id=%s,owner_address=%s,exp=%s", monster_id, owner_address, owner_address)

	owner_address = owner_address.lower()
	name = data_contract.call().getMonsterName(monster_id)
	name = name.encode("latin1").decode("utf8").strip()
	name = (name[:100] + '..') if len(name) > 100 else name

	egg_bonus = None
	if transform_contract and class_id <= 24:
		egg_bonus = transform_contract.call().getBonusEgg(monster_id)

	current_ts = get_timestamp()
	exp_flag = False
	trainer_flag = None

	# update information
	if monster_record:
		if egg_bonus is None:
			egg_bonus = monster_record.egg_bonus

		if base_stats_refresh:
			base_stats = []
			for index in xrange(0, 6):
				stat_value = data_contract.call().getElementInArrayType(DataArrayType.STAT_BASE, monster_id, index)
				base_stats.append(stat_value)
			# if 0 in base_stats:
			# 	log.error('update_ema_monster_error|monster_id=%s,base_stats=%s', monster_id, base_stats)
			# 	return False, 0, 0
			monster_record.b0 = base_stats[0]
			monster_record.b1 = base_stats[1]
			monster_record.b2 = base_stats[2]
			monster_record.b3 = base_stats[3]
			monster_record.b4 = base_stats[4]
			monster_record.b5 = base_stats[5]
			monster_record.save()

		# Nothing to update
		if monster_record.trainer == owner_address \
				and monster_record.exp == exp \
				and monster_record.name == name \
				and monster_record.last_claim_index == last_claim_index \
				and monster_record.egg_bonus == egg_bonus:
			return True, 0, 0

		# update exp
		if monster_record.exp != exp:
			exp_flag = True
			monster_record.exp = exp

			# get bp
			stats, bp, level = get_stats(
				monster_record.class_id,
				monster_record.exp,
				[monster_record.b0, monster_record.b1, monster_record.b2, monster_record.b3, monster_record.b4, monster_record.b5]
			)
			monster_record.bp = bp

		# Update rank team if necessary
		if monster_record.trainer != owner_address:
			trainer_flag = monster_record.trainer

		monster_record.egg_bonus = egg_bonus
		monster_record.trainer = owner_address
		monster_record.name = name
		monster_record.last_claim_index = last_claim_index
		monster_record.update_time = current_ts
		monster_record.save()
		log.info("update_ema_monster_info|monster_id=%s", monster_id)
		update_count += 1
		dcl_manager.dcl_update_transferred_mon(monster_id, owner_address)
	else:
		# Case new mon
		exp_flag = True
		base_stats = []
		for index in xrange(0, 6):
			stat_value = data_contract.call().getElementInArrayType(DataArrayType.STAT_BASE, monster_id, index)
			base_stats.append(stat_value)

		if 0 in base_stats:
			log.error('update_ema_monster_error|monster_id=%s,base_stats=%s', monster_id, base_stats)
			return False, 0, 0

		# get bp
		stats, bp, level = get_stats(
			class_id,
			exp,
			[base_stats[0], base_stats[1], base_stats[2], base_stats[3], base_stats[4], base_stats[5]]
		)

		if egg_bonus is None:
			egg_bonus = 0

		monster_record = EtheremonDB.EmaMonsterDataTab(
			monster_id=monster_id,
			class_id=class_id,
			trainer=owner_address,
			name=name,
			exp=exp,
			b0=base_stats[0],
			b1=base_stats[1],
			b2=base_stats[2],
			b3=base_stats[3],
			b4=base_stats[4],
			b5=base_stats[5],
			bp=bp,
			egg_bonus=egg_bonus,
			create_index=create_index,
			last_claim_index=last_claim_index,
			create_time=monster_create_time,
			update_time=current_ts
		)
		monster_record.save()
		log.info("add_ema_monster_info|monster_id=%s", monster_id)
		add_count += 1

	# update exp
	if exp_flag:
		monster_stats = [monster_record.b0, monster_record.b1, monster_record.b2, monster_record.b3, monster_record.b4, monster_record.b5]
		status = EmaMonsterStatus.Normal
		if monster_record.trainer == EMPTY_ADDRESS:
			status = EmaMonsterStatus.Deleted
		update_ema_monster_bp(monster_id, class_id, monster_stats, monster_record.exp, status)

	# Update old_player_rank
	if trainer_flag:
		ema_player_manager.try_disband_team(trainer_flag)

	log.info("sync_monster_id|monster_id=%s,exp=%s,class_id=%s", monster_id, exp, class_id)

	return True, add_count, update_count
Пример #8
0
def create_or_update_quest(player_uid, player_address, quest_id, quest):
    current_ts = get_timestamp()
    today_start_time = get_start_time_of_the_day(current_ts)
    today_end_time = get_end_time_of_the_day(current_ts)

    # Get quest info
    quest_info = quest_config.QUEST_LIST[quest_id]
    quest_start_time = quest_info.get("start_time", 0)
    quest_end_time = quest_info.get("end_time", INFINITY_FUTURE)
    is_daily_quest = quest_info[
        'quest_type'] == QuestTypes.DAILY or quest_info.get('is_daily', False)

    # Case daily quest reset
    if quest and is_daily_quest:
        if current_ts > quest.end_time:
            quest.start_time = max(quest_start_time, today_start_time)
            quest.end_time = min(quest_end_time, today_end_time)
            quest.status = QuestStatus.TO_DO
            quest.quest_level = 0
            quest.quest_target = quest_info['quest_target'][0]
            quest.reward_type = quest_info['reward_type'][0]
            quest.reward_value = quest_info['reward_value'][0]

    # Case claimed / finished quest
    if quest and quest.status != QuestStatus.TO_DO:
        return quest

    # Case new quest
    if quest is None:
        quest = EtheremonDB.QuestTab(
            player_uid=player_uid,
            player_address=player_address,
            quest_id=quest_id,
            quest_type=quest_info['quest_type'],
            quest_level=0,
            quest_name=quest_info['quest_name'],
            quest_target=quest_info['quest_target'][0],
            quest_progress=0,
            reward_type=quest_info['reward_type'][0],
            reward_value=quest_info['reward_value'][0],
            status=QuestStatus.TO_DO,
            start_time=quest_start_time if not is_daily_quest else max(
                quest_start_time, today_start_time),
            end_time=quest_end_time if not is_daily_quest else min(
                quest_end_time, today_end_time),
            last_check=0,
            create_time=current_ts,
            extra="{}",
        )

    # Update progress
    temp = quest_info['update_progress_func'](quest, current_ts)
    quest_progress = temp if not isinstance(temp, tuple) else temp[0]
    quest.quest_progress = min(quest.quest_target, quest_progress)

    # Ready to claim
    if quest.quest_progress == quest.quest_target:
        quest.status = QuestStatus.TO_CLAIM

    quest_extra_data = None if not isinstance(temp, tuple) else temp[1]
    extra_data = json.loads(quest.extra or "{}")
    extra_data["info"] = quest_extra_data
    quest.extra = json.dumps(extra_data)

    quest.last_check = current_ts
    quest.update_time = current_ts
    quest.save()

    return quest
Пример #9
0
def crawl_txn():

    start_block = EtheremonDB.PartnerMchPresaleTab.objects.all().aggregate(
        Max('latest_block_number'))
    if not start_block["latest_block_number__max"]:
        start_block = START_BLOCK
    else:
        start_block = start_block["latest_block_number__max"]

    old_block = 0
    while True:
        end_block = start_block + SMART_CONTRACT_BLOCK_STEP

        time.sleep(3)
        transaction_list = get_txn_list(SMART_CONTRACT_ADDRESS, start_block,
                                        end_block,
                                        ETHERSCAN_API_KEYS["cron_3"])
        if transaction_list is None:
            break

        if len(transaction_list) == 0:
            break

        for transaction in transaction_list:
            if len(transaction["input"]) < SMART_CONTRACT_METHOD_ID_LENGTH:
                log.warn("invalid_smart_contract_txn|transaction=%s",
                         transaction)
                continue
            if int(transaction.get("isError", 1)) != 0:
                continue
            if int(transaction.get("txreceipt_status")) != 1:
                continue

            block_number = int(transaction["blockNumber"])
            start_block = max(start_block, block_number)

            eth_amount = long(transaction["value"])
            if eth_amount == 0:
                continue

            txn_time = int(transaction["timeStamp"])
            eth_amount = float(eth_amount * 1.0 / (10**18))
            sender = str(transaction["from"]).lower()
            txn_hash = str(transaction["hash"]).lower()

            current_record = EtheremonDB.PartnerMchPresaleTab.objects.filter(
                player=sender).first()
            if not current_record:
                # check etheremon player
                mch_flag = MCHFlag.FLAG_NONE
                country = ""
                etheremon_user = EtheremonDB.UserTab.objects.filter(
                    address=sender).first()
                if etheremon_user:
                    mch_flag = MCHFlag.FLAG_ETHEREMON_PLAYER
                    country = etheremon_user.country
                else:
                    if EtheremonDB.EmaMonsterDataTab.objects.filter(
                            trainer=sender).count() > 0:
                        mch_flag = MCHFlag.FLAG_ETHEREMON_PLAYER

                EtheremonDB.PartnerMchPresaleTab(
                    player=sender,
                    amount=eth_amount,
                    flag=mch_flag,
                    country=country,
                    txn_count=1,
                    latest_block_number=block_number).save()
            else:
                if current_record.latest_block_number >= block_number:
                    continue
                current_record.amount += eth_amount
                current_record.txn_count += 1
                current_record.latest_block_number = block_number
                current_record.save()

        if start_block == old_block:
            break
        old_block = start_block