def update_erc721_contract():
    infura_client = InfuraClient(INFURA_API_URL)
    current_block = infura_client.getCurrentBlock() - 2

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

    start_time = time.time()
    transaction_list = get_txn_list(EtheremonERC721Contract.ADDRESS,
                                    start_block, end_block, ETHERSCAN_API_KEY)
    if transaction_list is None:
        return

    log.data(
        "start_update_erc721_contract|current_block=%s,start_block=%s,end_block=%s,len_txn=%s",
        current_block, start_block, end_block, len(transaction_list))

    latest_load_block = start_block
    sender_set = set()
    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

        latest_load_block = max(latest_load_block,
                                int(transaction["blockNumber"]))
        if latest_load_block > current_block:
            return
        sender = str(transaction["from"]).lower()
        sender_set.add(sender)
        log.info("update_erc721|txn_hash=%s,sender=%s", transaction["hash"],
                 sender)

    if sender_set:
        log.info("update_erc721|len_sender=%s,latest_load_block=%s",
                 len(sender_set), latest_load_block)
        data_contract = infura_client.getDataContract()
        for player in sender_set:
            result = _sync_player_dex(data_contract, player)
            if result is False:
                log.warn("sync_player_fail|player=%s", player)
                return

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

    ema_settings_manager.set_setting(EmaSetting.SETTING_CONTRACT_ERC721_BLOCK,
                                     record_block)
    elapsed = time.time() - start_time
    if elapsed < 5:
        time.sleep(5 - elapsed)
    log.data(
        "end_update_erc721_contract|record_block=%s,total_txn=%s,total_player=%s,elapsed=%s",
        record_block, len(transaction_list), len(sender_set), elapsed)
def update_transform_contract():
	infura_client = InfuraClient(INFURA_API_URL)
	current_block = infura_client.getCurrentBlock() - 2

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

	start_time = time.time()


	transaction_list = get_txn_list(EtheremonTransformContract.ADDRESS, start_block, end_block, ETHERSCAN_API_KEY)
	
	
	
	if transaction_list is None:
		return

	log.data("start_update_transform_contract|current_block=%s,start_block=%s,end_block=%s,len_txn=%s", current_block, start_block, end_block, len(transaction_list))

	'''
	if len(transaction_list) > 50:
		log.data("update_transform|cut_down_txn|current_block=%s,start_block=%s,end_block=%s", current_block, start_block, end_block)
		transaction_list = transaction_list[:50]
	'''

	latest_load_block = start_block
	sender_set = set()
	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

		log.info("update_transform_contract|txn_hash=%s", transaction["hash"])
		latest_load_block = max(latest_load_block, int(transaction["blockNumber"]))
		if latest_load_block > current_block:
			return
		sender = str(transaction["from"]).lower()
		sender_set.add(sender)

	# update info by trainer
	count_new_egg = 0
	if sender_set:
		time.sleep(5)
		data_contract = infura_client.getDataContract()
		transform_contract = infura_client.getTransformContract()
		transform_data_contract = infura_client.getTransformDataContract()
		for player in sender_set:
			# update info
			result = _sync_player_dex(data_contract, player, transform_contract)
			if result is False:
				log.warn("sync_player_fail|player=%s", player)
				return

			# sync egg data
			egg_records = EtheremonDB.EmaEggDataTab.objects.filter(trainer=player).filter(new_obj_id=0).all()
			for egg_record in egg_records:
				(egg_id, mother_id, class_id, trainer_address, hatch_time, monster_id) = transform_data_contract.call().getEggDataById(egg_record.egg_id)
				if class_id == 0:
					log.warn("invalid_egg_data|egg_id=%s", egg_record.egg_id)
					return
				egg_record.mother_id = mother_id
				egg_record.class_id = class_id
				egg_record.trainer = str(trainer_address).lower()
				egg_record.hatch_time = int(hatch_time)
				egg_record.new_obj_id = monster_id
				egg_record.save()

		# sync new egg
		max_egg_record = EtheremonDB.EmaEggDataTab.objects.all().order_by("-egg_id").first()
		max_id = 0
		if max_egg_record:
			max_id = max_egg_record.egg_id
		current_total = transform_data_contract.call().totalEgg()
		index = max_id + 1
		while index <= current_total:
			(egg_id, mother_id, class_id, trainer_address, hatch_time, monster_id) = transform_data_contract.call().getEggDataById(index)
			if class_id == 0:
				log.warn("invalid_egg_data|egg_id=%s", index)
				return
			EtheremonDB.EmaEggDataTab.objects.create(
				egg_id=index,
				mother_id=mother_id,
				class_id=class_id,
				trainer=str(trainer_address).lower(),
				hatch_time=int(hatch_time),
				new_obj_id=monster_id,
				create_time=start_time
			)
			index += 1
			count_new_egg += 1

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

	ema_settings_manager.set_setting(EmaSetting.SETTING_CONTRACT_TRANSFORM_BLOCK, record_block)
	elapsed = time.time() - start_time
	if elapsed < 5:
		time.sleep(5-elapsed)
	log.data("end_update_transform_contract|record_block=%s,total_txn=%s,total_player=%s,count_new_egg=%s,elapsed=%s",
		record_block, len(transaction_list), len(sender_set), count_new_egg, elapsed)
Beispiel #3
0
def update_trade_contract():
	infura_client = InfuraClient(INFURA_API_URL)
	current_block = infura_client.getCurrentBlock() - 2

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

	start_time = time.time()
	transaction_list = get_txn_list(EtheremonTradeContract.ADDRESS, start_block, end_block, ETHERSCAN_API_KEY)
	if transaction_list is None:
		return

	log.data("start_update_trade_contract|current_block=%s,start_block=%s,end_block=%s,len_txn=%s", current_block, start_block, end_block, len(transaction_list))

	latest_load_block = start_block
	current_ts = get_timestamp()
	monster_id_set = set()
	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

		log.info("update_trade_contract|txn_hash=%s", transaction["hash"])
		latest_load_block = max(latest_load_block, int(transaction["blockNumber"]))
		if latest_load_block > current_block:
			return
		method_id = transaction["input"][0:SMART_CONTRACT_METHOD_ID_LENGTH]
		sender = str(transaction["from"]).lower()

		if method_id == TRADING_CONTRACT_PLACE_SELL_METHOD:
			monster_id_hash = "0x" + transaction["input"][SMART_CONTRACT_METHOD_ID_LENGTH:SMART_CONTRACT_METHOD_ID_LENGTH + 64]
			monster_id = Web3.toInt(hexstr=monster_id_hash)

			price_hash = "0x" + transaction["input"][SMART_CONTRACT_METHOD_ID_LENGTH + 64:SMART_CONTRACT_METHOD_ID_LENGTH + 128]
			original_price = Web3.toInt(hexstr=price_hash)
			price = original_price/MARKET_PRICE_DIVISION

			if price > 1000000000:
				log.warn("price_too_high|txn_hash=%s,origin_price=%s,price=%s", transaction["hash"], original_price, price)
				continue


			current_record = EtheremonDB.EmaMarketTab.objects.filter(type=EmaMarketType.SELL).filter(monster_id=monster_id).first()
			if current_record:
				extra_data = json.loads(current_record.extra_data)
				if current_record.price == price and extra_data.get("txn_hash") == transaction["hash"]:
					continue
				extra_data["txn_hash"] = transaction["hash"]
				current_record.player = sender
				current_record.extra_data = json.dumps(extra_data)
				current_record.price = price
				current_record.save()
			else:
				extra_data = {"txn_hash": transaction["hash"]}
				EtheremonDB.EmaMarketTab.objects.create(
					type=EmaMarketType.SELL,
					player=sender,
					monster_id=monster_id,
					price=price,
					status=EmaMarketStatus.NONE,
					extra_data=json.dumps(extra_data),
					create_time=int(transaction["timeStamp"])
				)

			# update market history
			'''
			price = original_price/HISTORY_PRICE_DIVISION
			monster_record = EtheremonDB.EmaMonsterDataTab.objects.filter(monster_id=monster_id).first()
			if monster_record is None:
				log.warn("monster_id_not_exist|monster_id=%s,trade_hash=%s", monster_id, transaction["hash"])
				return
			market_history_item = EtheremonDB.MarketHistoryTab.objects.filter(monster_id=monster_id, sell_time=int(transaction["timeStamp"])).first()
			if market_history_item:
				continue
			base_bp = (monster_record.b0 + monster_record.b1 + monster_record.b2 + monster_record.b3 + monster_record.b4 + monster_record.b5) / 6
			EtheremonDB.MarketHistoryTab.objects.create(
				monster_id=monster_id,
				price=price,
				is_sold=False,
				block_number=int(transaction["blockNumber"]),
				sell_time=int(transaction["timeStamp"]),
				buy_time=0,
				class_id=monster_record.class_id,
				base_bp=base_bp,
				create_index=monster_record.create_index,
				extra_data=json.dumps({}),
				exp=monster_record.exp
			)
			'''
			log.info("mark_list_monster_for_sell|monster_id=%s,sell_time=%s", monster_id, int(transaction["timeStamp"]))

		elif method_id == TRADING_CONTRACT_REMOVE_SELL_METHOD:
			monster_id_hash = "0x" + transaction["input"][SMART_CONTRACT_METHOD_ID_LENGTH:SMART_CONTRACT_METHOD_ID_LENGTH + 64]
			monster_id = Web3.toInt(hexstr=monster_id_hash)
			EtheremonDB.EmaMarketTab.objects.filter(type=EmaMarketType.SELL).filter(monster_id=monster_id).delete()
			log.info("remove_sell|monster_id=%s,txn_hash=%s", monster_id, transaction["hash"])

		elif method_id == TRADING_CONTRACT_BUY_METHOD:
			monster_id_hash = "0x" + transaction["input"][SMART_CONTRACT_METHOD_ID_LENGTH:SMART_CONTRACT_METHOD_ID_LENGTH + 64]
			monster_id = Web3.toInt(hexstr=monster_id_hash)

			# update monster info
			monster_id_set.add(monster_id)

			monster_record = EtheremonDB.EmaMonsterDataTab.objects.filter(monster_id=monster_id).first()
			if monster_record is None:
				log.warn("monster_id_not_exist|monster_id=%s,trade_hash=%s", monster_id, transaction["hash"])
				return

			txn_hash = transaction["hash"].lower()
			market_record = EtheremonDB.EmaMarketTab.objects.filter(type=EmaMarketType.SELL).filter(monster_id=monster_id).first()
			if not market_record:
				log.warn("market_record_not_exist|txn_hash=%s,monster_id=%s", txn_hash, monster_id)
				continue

			market_history_item = EtheremonDB.MarketHistoryTab.objects.filter(txn_hash=txn_hash).first()
			base_bp = (monster_record.b0 + monster_record.b1 + monster_record.b2 + monster_record.b3 + monster_record.b4 + monster_record.b5) / 6
			if not market_history_item:
				EtheremonDB.MarketHistoryTab.objects.create(
					monster_id=monster_id,
					txn_hash=txn_hash,
					seller=market_record.player,
					buyer=sender,
					price=market_record.price,
					is_sold=True,
					block_number=int(transaction["blockNumber"]),
					sell_time=market_record.create_time,
					buy_time=int(transaction["timeStamp"]),
					class_id=monster_record.class_id,
					base_bp=base_bp,
					create_index=monster_record.create_index,
					extra_data=json.dumps({}),
					exp=monster_record.exp
				)
			market_record.delete()

			log.info("buy_item|monster_id=%s,txn_hash=%s", monster_id, transaction["hash"])

			# update market history
			'''
			if market_history_item is None:
				log.warn("item_sold_not_found|monster_id=%s,hash=%s", monster_id, transaction["hash"])
				continue
			if market_history_item.is_sold:
				continue
			if EtheremonDB.MarketHistoryTab.objects.filter(monster_id=monster_id, buy_time=int(transaction["timeStamp"])).first() is not None:
				log.warn("item_duplicate_buy|monster_id=%s,hash=%s", monster_id, transaction["hash"])
				continue
			monster_record = EtheremonDB.EmaMonsterDataTab.objects.filter(monster_id=monster_id).first()
			if monster_record is None:
				log.warn("monster_id_not_exist|monster_id=%s,trade_hash=%s", monster_id, transaction["hash"])
				return
			base_bp = (monster_record.b0 + monster_record.b1 + monster_record.b2 + monster_record.b3 + monster_record.b4 + monster_record.b5) / 6
			market_history_item.is_sold = True
			market_history_item.buy_time = int(transaction["timeStamp"])
			market_history_item.class_id = monster_record.class_id
			market_history_item.base_bp = base_bp
			market_history_item.create_index = monster_record.create_index
			market_history_item.exp = monster_record.exp
			market_history_item.save()
			log.info("mark_buy_monster|monster_id=%s,buy_time=%s", monster_id, int(transaction["timeStamp"]))
			'''

		elif method_id == TRADING_CONTRACT_OFFER_BORROW_METHOD:
			monster_id_hash = "0x" + transaction["input"][SMART_CONTRACT_METHOD_ID_LENGTH:SMART_CONTRACT_METHOD_ID_LENGTH + 64]
			monster_id = Web3.toInt(hexstr=monster_id_hash)

			price_hash = "0x" + transaction["input"][SMART_CONTRACT_METHOD_ID_LENGTH + 64:SMART_CONTRACT_METHOD_ID_LENGTH + 128]
			price = Web3.toInt(hexstr=price_hash)
			price = price/MARKET_PRICE_DIVISION

			release_time_hash = "0x" + transaction["input"][SMART_CONTRACT_METHOD_ID_LENGTH + 128:SMART_CONTRACT_METHOD_ID_LENGTH + 192]
			release_time = Web3.toInt(hexstr=release_time_hash)

			current_record = EtheremonDB.EmaMarketTab.objects.filter(type=EmaMarketType.BORROW).filter(monster_id=monster_id).first()
			if current_record:
				extra_data = json.loads(current_record.extra_data)
				if current_record.price == price and current_record.status == EmaMarketStatus.NONE and extra_data["release_time"] == release_time and extra_data.get("txn_hash") == transaction["hash"]:
					continue
				extra_data["txn_hash"] = transaction["hash"].lower()
				extra_data["release_time"] = release_time
				extra_data["borrower"] = ""
				current_record.player=sender
				current_record.status = EmaMarketStatus.NONE
				current_record.price = price
				current_record.extra_data = json.dumps(extra_data)
				current_record.save()
			else:
				extra_data = {
					"txn_hash": transaction["hash"].lower(),
					"borrower": "",
					"release_time": release_time
				}
				EtheremonDB.EmaMarketTab.objects.create(
					type=EmaMarketType.BORROW,
					player=sender,
					monster_id=monster_id,
					price=price,
					status=EmaMarketStatus.NONE,
					extra_data=json.dumps(extra_data),
					create_time=current_ts
				)
		elif method_id == TRADING_CONTRACT_REMOVE_OFFER_BORROW_METHOD:
			monster_id_hash = "0x" + transaction["input"][SMART_CONTRACT_METHOD_ID_LENGTH:SMART_CONTRACT_METHOD_ID_LENGTH + 64]
			monster_id = Web3.toInt(hexstr=monster_id_hash)
			EtheremonDB.EmaMarketTab.objects.filter(type=EmaMarketType.BORROW).filter(monster_id=monster_id).delete()
			log.info("remove_borrow|monster_id=%s,txn_hash=%s", monster_id, transaction["hash"])

		elif method_id == TRADING_CONTRACT_BORROW_METHOD:
			monster_id_hash = "0x" + transaction["input"][SMART_CONTRACT_METHOD_ID_LENGTH:SMART_CONTRACT_METHOD_ID_LENGTH + 64]
			monster_id = Web3.toInt(hexstr=monster_id_hash)

			# update monster info
			monster_id_set.add(monster_id)

			current_record = EtheremonDB.EmaMarketTab.objects.filter(type=EmaMarketType.BORROW).filter(monster_id=monster_id).first()
			if not current_record:
				log.error("no_monster_borrow_record|monster_id=%s,txn_hash=%s", monster_id, transaction["hash"])
				break

			extra_data = json.loads(current_record.extra_data)
			extra_data["borrower"] = str(transaction["from"]).lower()
			if extra_data["release_time"] < 10000000:
				extra_data["release_time"] += int(transaction["timeStamp"])
			current_record.status = EmaMarketStatus.LENT
			current_record.extra_data = json.dumps(extra_data)
			current_record.save()

		elif method_id == TRADING_CONTRACT_GET_BACK_LENDING_METHOD:
			monster_id_hash = "0x" + transaction["input"][SMART_CONTRACT_METHOD_ID_LENGTH:SMART_CONTRACT_METHOD_ID_LENGTH + 64]
			monster_id = Web3.toInt(hexstr=monster_id_hash)
			monster_id_set.add(monster_id)

			EtheremonDB.EmaMarketTab.objects.filter(type=EmaMarketType.BORROW).filter(monster_id=monster_id).delete()
			log.info("remove_borrow|monster_id=%s,txn_hash=%s", monster_id, transaction["hash"])

	if len(monster_id_set) > 0:
		log.info("update_trade_contract|monster_len=%s,latest_load_block=%s", len(monster_id_set), latest_load_block)
		data_contract = infura_client.getDataContract()
		for monster_id in monster_id_set:
			_sync_monster_id(data_contract, monster_id)
			log.info("trade_contract|update_monster|monster_id=%s", monster_id)

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

	ema_settings_manager.set_setting(EmaSetting.SETTING_CONTRACT_TRADE_BLOCK, record_block)
	elapsed = time.time() - start_time
	if elapsed < 5:
		time.sleep(5-elapsed)
	log.data("end_update_trade_contract|record_block=%s,total_txn=%s,total_monster=%s,elapsed=%s",
		record_block, len(transaction_list), len(monster_id_set), elapsed)
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)
def update_erc20_contract():
	infura_client = InfuraClient(INFURA_API_URL)
	current_block = infura_client.getCurrentBlock() - 2

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

	start_time = time.time()
	transaction_list = get_txn_list(EtheremonEMONTContract.ADDRESS, start_block, end_block, ETHERSCAN_API_KEY)
	if transaction_list is None:
		return

	log.data("start_update_erc20_contract|current_block=%s,start_block=%s,end_block=%s,len_txn=%s", current_block, start_block, end_block, len(transaction_list))

	latest_load_block = start_block
	egg_sender_set = set()
	energy_sender_set = set()
	adventure_explore_contract = infura_client.getAdventureExploreContract()
	adventure_data_contract = infura_client.getAdventureDataContract()
	site_id_set = set()
	current_ts = get_timestamp()
	deck_sender_set = set()
	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
		latest_load_block = max(latest_load_block, int(transaction["blockNumber"]))
		if latest_load_block > current_block:
			return
		method_id = transaction["input"][0:SMART_CONTRACT_METHOD_ID_LENGTH]
		sender = str(transaction["from"]).lower()

		if method_id == PAY_SERVICE_METHOD:
			type_id_hash = "0x" + transaction["input"][SMART_CONTRACT_METHOD_ID_LENGTH + 64:SMART_CONTRACT_METHOD_ID_LENGTH + 128]
			type_id = Web3.toInt(hexstr=type_id_hash)

			if type_id == PayServiceType.FAST_HATCHING or type_id == PayServiceType.RANDOM_EGG:
				egg_sender_set.add(sender)
			elif type_id == PayServiceType.ENERGY_TOPUP:
				energy_sender_set.add(sender)
			elif type_id == PayServiceType.ADVENTURE:
				adventure_sub_id_hash = "0x" + transaction["input"][SMART_CONTRACT_METHOD_ID_LENGTH + 192:SMART_CONTRACT_METHOD_ID_LENGTH + 256]
				adventure_sub_id = Web3.toInt(hexstr=adventure_sub_id_hash)

				if adventure_sub_id == 1:
					# explore using emont
					pending_explore_data = adventure_explore_contract.call().getPendingExploreItem(sender)
					explore_id = pending_explore_data[0]
					if explore_id == 0:
						log.info("no_pending_txn|sender=%s", sender)
						continue
					current_record = EtheremonDB.EmaAdventureExploreTab.objects.filter(explore_id=explore_id).first()
					if not current_record:
						'''
						EtheremonDB.EmaAdventureExploreTab.objects.create(
							explore_id=explore_id,
							fee_type=EmaAdventureExploreFee.EMONT,
							sender=sender,
							monster_type=pending_explore_data[1],
							monster_id=pending_explore_data[2],
							site_id=pending_explore_data[3],
							reward_monster_class=0,
							reward_item_class=0,
							reward_item_value='0',
							start_block=pending_explore_data[4],
							end_block=pending_explore_data[5],
							claim_txn_hash='',
							create_time=current_ts
						)
						log.info("adding_new_explore|explore_id=%s,sender=%s,txn_hash=%s", explore_id, sender, transaction["hash"])
						'''
						return
					else:
						if current_record.fee_type == 0:
							current_record.fee_type = EmaAdventureExploreFee.EMONT
							current_record.save()
					site_id_set.add(pending_explore_data[3])
				else:
					# claim explore
					explore_id_hash = "0x" + transaction["input"][SMART_CONTRACT_METHOD_ID_LENGTH + 256:SMART_CONTRACT_METHOD_ID_LENGTH + 320]
					explore_id = Web3.toInt(hexstr=explore_id_hash)
					current_record = EtheremonDB.EmaAdventureExploreTab.objects.filter(explore_id=explore_id).first()
					explore_data = adventure_explore_contract.call().getExploreItem(explore_id)
					if explore_data[5] == 0 and explore_data[6] == 0 and explore_data[7] == 0:
						log.warn("invalid_explore_data_claim|explore_id=%s,explore_data=%s,txn_hash=%s", explore_id, explore_data, transaction["hash"])
						return
					if not current_record:
						log.warn("unable_to_find_explore|explore_id=%s,txn_hash=%s,adventure_sub_id=%s", explore_id, transaction["hash"], adventure_sub_id)
						'''
						explore_ending_block = explore_data[4] + EXPLORE_MIN_BLOCK_GAP + explore_data[4] % EXPLORE_MIN_BLOCK_GAP
						EtheremonDB.EmaAdventureExploreTab.objects.create(
							explore_id=explore_id,
							fee_type=EmaAdventureExploreFee.ETH,
							sender=explore_data[0].lower(),
							monster_type=explore_data[1],
							monster_id=explore_data[2],
							site_id=explore_data[3],
							reward_monster_class=explore_data[5],
							reward_item_class=explore_data[6],
							reward_item_value=str(explore_data[7]),
							start_block=explore_data[4],
							end_block=explore_ending_block,
							claim_txn_hash=transaction["hash"].lower(),
							create_time=current_ts
						)
						site_id_set.add(explore_data[3])
						'''
						return
					else:
						current_record.claim_txn_hash = transaction["hash"].lower()
						current_record.reward_monster_class = explore_data[5]
						current_record.reward_item_class = explore_data[6]
						current_record.reward_item_value = str(explore_data[7])
						current_record.save()

					site_id_set.add(current_record.site_id)

					if explore_data[5] > 0:
						deck_sender_set.add(current_record.sender)


	if egg_sender_set:
		log.info("update_erc20_egg_info|len_sender=%s,latest_load_block=%s", len(egg_sender_set), latest_load_block)
		transform_data_contract = infura_client.getTransformDataContract()
		for sender in egg_sender_set:
			egg_records = EtheremonDB.EmaEggDataTab.objects.filter(trainer=sender).filter(new_obj_id=0).all()
			for egg_record in egg_records:
				(egg_id, mother_id, class_id, trainer_address, hatch_time, monster_id) = transform_data_contract.call().getEggDataById(egg_record.egg_id)
				egg_record.mother_id = mother_id
				egg_record.class_id = class_id
				egg_record.trainer = str(trainer_address).lower()
				egg_record.hatch_time = int(hatch_time)
				egg_record.new_obj_id = monster_id
				egg_record.save()
				log.info("erc20_update_egg|trainer=%s,egg_id=%s", sender, egg_id)

		# sync new egg
		max_egg_record = EtheremonDB.EmaEggDataTab.objects.all().order_by("-egg_id").first()
		max_id = 0
		if max_egg_record:
			max_id = max_egg_record.egg_id
		current_total = transform_data_contract.call().totalEgg()
		index = max_id + 1
		while index <= current_total:
			(egg_id, mother_id, class_id, trainer_address, hatch_time, monster_id) = transform_data_contract.call().getEggDataById(index)
			if class_id is 0:
				log.warn("invalid_egg_data|egg_id=%s", index)
				return
			EtheremonDB.EmaEggDataTab.objects.create(
				egg_id=index,
				mother_id=mother_id,
				class_id=class_id,
				trainer=str(trainer_address).lower(),
				hatch_time=int(hatch_time),
				new_obj_id=monster_id,
				create_time=start_time
			)
			index += 1
			log.info("erc20_add_egg|egg_id=%s", egg_id)

	if energy_sender_set:
		log.info("update_erc20_energy_info|len_sender=%s,latest_load_block=%s", len(energy_sender_set), latest_load_block)
		energy_contract = infura_client.getEnergyContract()
		current_ts = get_timestamp()
		for sender in energy_sender_set:
			(free_amount, paid_amount, last_claim) = energy_contract.call().getPlayerEnergy(sender)
			record = EtheremonDB.EmaPlayerEnergyTab.objects.filter(trainer=sender).first()
			if record:
				record.free_amount = free_amount
				record.paid_amount = paid_amount
				record.last_claim_time = last_claim
				record.update_time = current_ts
				record.save()
			else:
				EtheremonDB.EmaPlayerEnergyTab.objects.create(
					trainer=sender,
					init_amount=0,
					free_amount=free_amount,
					paid_amount=paid_amount,
					consumed_amount=0,
					last_claim_time=last_claim,
					create_time=current_ts,
					update_time=current_ts
				)

	# check revenue
	if site_id_set:
		for site_id in site_id_set:
			site_revenue = adventure_data_contract.call().getLandRevenue(site_id)
			log.info("update_site_revenue|site_id=%s,revenue=%s", site_id, site_revenue)
			if site_revenue[0] > 0 or site_revenue[1] > 0:
				emont_amount = (1.0 * site_revenue[0]) / 10**8
				eth_amount = (1.0 * site_revenue[1]) / 10**18
				site_revenue_record = EtheremonDB.EmaAdventureRevenueSiteTab.objects.filter(site_id=site_id).first()
				if not site_revenue_record:
					EtheremonDB.EmaAdventureRevenueSiteTab.objects.create(
						site_id=site_id,
						eth_amount=eth_amount,
						emont_amount=emont_amount,
						update_time=current_ts
					)
				else:
					if site_revenue_record.eth_amount < eth_amount:
						site_revenue_record.eth_amount = eth_amount
					if site_revenue_record.emont_amount < emont_amount:
						site_revenue_record.emont_amount = emont_amount
					site_revenue_record.update_time = current_ts
					site_revenue_record.save()

	# reload sender
	if deck_sender_set:
		log.info("update_deck_erc20|len_sender=%s,latest_load_block=%s", len(deck_sender_set), latest_load_block)
		data_contract = infura_client.getDataContract()
		for player in deck_sender_set:
			result = _sync_player_dex(data_contract, player)
			if result is False:
				log.warn("sync_player_fail|player=%s", player)

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

	ema_settings_manager.set_setting(EmaSetting.SETTING_CONTRACT_ERC20_BLOCK, record_block)
	elapsed = time.time() - start_time
	if elapsed < 5:
		time.sleep(5-elapsed)
	log.data("end_update_erc20_contract|record_block=%s,total_txn=%s,total_egg_sender=%s,total_energy_sender=%s,elapsed=%s",
		record_block, len(transaction_list), len(egg_sender_set), len(energy_sender_set), elapsed)
Beispiel #6
0
def update_claim_contract():
    infura_client = InfuraClient(INFURA_API_URL)
    current_block = infura_client.getCurrentBlock() - 5

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

    start_time = time.time()
    transaction_list = get_txn_list(EtheremonClaimContract.ADDRESS,
                                    start_block, end_block, ETHERSCAN_API_KEY)
    if transaction_list is None:
        return

    log.data(
        "start_update_claim_contract|current_block=%s,start_block=%s,end_block=%s,len_txn=%s",
        current_block, start_block, end_block, len(transaction_list))

    latest_load_block = start_block
    monster_id_set = set()
    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

        latest_load_block = max(latest_load_block,
                                int(transaction["blockNumber"]))
        if latest_load_block > current_block:
            return

        method_id = transaction["input"][0:SMART_CONTRACT_METHOD_ID_LENGTH]

        if method_id == CLAIM_MONSTER_EXP_METHOD:
            token_bytes = transaction[
                "input"][SMART_CONTRACT_METHOD_ID_LENGTH:
                         SMART_CONTRACT_METHOD_ID_LENGTH + 64]
            token = token_bytes.decode("hex")
            token_data = decode_claim_exp_token(token)
            request_id = token_data["request_id"]
            monster_id = token_data["monster_id"]

            result = proceed_pending_exp_claim(request_id)
            monster_id_set.add(monster_id)
            log.info(
                "process_exp_claim|request_id=%s,result=%s,txn_hash=%s,monster_id=%s",
                request_id, result, transaction["hash"], monster_id)
        elif method_id == CLAIM_WIN_RANK_METHOD:
            token_bytes = transaction[
                "input"][SMART_CONTRACT_METHOD_ID_LENGTH:
                         SMART_CONTRACT_METHOD_ID_LENGTH + 64]
            token = token_bytes.decode("hex")
            token_data = decode_claim_win_token(token)
            request_id = token_data["request_id"]
            try:
                result = proceed_pending_win_claim(request_id)
            except:
                logging.exception(
                    "process_win_claim_invalid|request_id=%s,txn_hash=%s",
                    request_id, transaction["hash"])
                continue
            log.info("process_win_claim|request_id=%s,result=%s,txn_hash=%s",
                     request_id, result, transaction["hash"])
        elif method_id == CLAIM_TOP_RANK_METHOD:
            token_bytes = transaction[
                "input"][SMART_CONTRACT_METHOD_ID_LENGTH:
                         SMART_CONTRACT_METHOD_ID_LENGTH + 64]
            token = token_bytes.decode("hex")
            token_data = decode_claim_top_token(token)
            request_id = token_data["request_id"]

            result = proceed_pending_top_claim(request_id)
            log.info("process_top_claim|request_id=%s,result=%s,txn_hash=%s",
                     request_id, result, transaction["hash"])

    # update monster id
    if monster_id_set:
        log.info(
            "update_claim_contract|monster_len=%s,latest_load_block=%s,current_block=%s",
            len(monster_id_set), latest_load_block, current_block)
        data_contract = infura_client.getDataContract()
        for monster_id in monster_id_set:
            result, add_flag, update_flag = _sync_monster_id(
                data_contract, monster_id)
            if result is False:
                return

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

    ema_settings_manager.set_setting(EmaSetting.SETTING_CONTRACT_CLAIM_BLOCK,
                                     record_block)
    elapsed = time.time() - start_time
    if elapsed < 5:
        time.sleep(5 - elapsed)
    log.data(
        "end_update_claim_contract|record_block=%s,total_txn=%s,total_monster=%s,elapsed=%s",
        record_block, len(transaction_list), len(monster_id_set), elapsed)
Beispiel #7
0
def _update_exp_contract(setting_type, app_key):
    infura_client = InfuraClient(INFURA_API_URL)
    current_block = infura_client.getCurrentBlock() - 2

    start_block = ema_settings_manager.get_setting_value(setting_type)
    end_block = start_block + SMART_CONTRACT_BLOCK_STEP

    start_time = time.time()
    contract_address = None
    if setting_type == EmaSetting.SETTING_EXP_GYM_BLOCK:
        contract_address = EtheremonGymContract.ADDRESS

    transaction_list = get_txn_list(contract_address, start_block, end_block,
                                    app_key)
    if transaction_list is None:
        return

    log.data(
        "start_update_exp_contract|setting=%s,start_block=%s,end_block=%s,len_txn=%s",
        setting_type, start_block, end_block, len(transaction_list))

    latest_load_block = start_block
    monster_id_set = set()
    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

        latest_load_block = max(latest_load_block,
                                int(transaction["blockNumber"]))
        if latest_load_block > current_block:
            return
        method_id = transaction["input"][0:SMART_CONTRACT_METHOD_ID_LENGTH]

        if setting_type == EmaSetting.SETTING_EXP_GYM_BLOCK:
            if method_id == GYM_CONTRACT_START_TRAINING_METHOD:
                monster_id_hash = "0x" + transaction[
                    "input"][SMART_CONTRACT_METHOD_ID_LENGTH:
                             SMART_CONTRACT_METHOD_ID_LENGTH + 64]
                monster_id = Web3.toInt(hexstr=monster_id_hash)
                monster_id_set.add(monster_id)
                log.info("update_gym_contract|monster_id=%s,hash=%s",
                         monster_id, transaction["hash"])

    total_add = 0
    total_update = 0
    if monster_id_set:
        log.info(
            "update_exp_contract|setting=%s,len_monster=%s,latest_load_block=%s",
            setting_type, len(monster_id_set), latest_load_block)
        data_contract = infura_client.getDataContract()
        for monster_id in monster_id_set:
            result, add_flag, update_flag = _sync_monster_id(
                data_contract, monster_id)
            if result is False:
                return
            total_add += add_flag
            total_update += update_flag

    block_value = latest_load_block
    if current_block < block_value:
        block_value = current_block

    ema_settings_manager.set_setting(setting_type, block_value)
    elapsed = time.time() - start_time
    if elapsed < 5:
        time.sleep(5 - elapsed)
    log.data(
        "end_update_exp_contract|setting=%s,total_add=%s,total_update=%s,start_block=%s,end_block=%s,block_sync=%s,elapsed=%s",
        setting_type, total_add, total_update, start_block, end_block,
        block_value, elapsed)
def update_worldnft_contract():
	infura_client = InfuraClient(INFURA_API_URL)
	current_block = infura_client.getCurrentBlock() - 2

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

	start_time = time.time()
	transaction_list = get_txn_list(EtheremonWorldNFTContract.ADDRESS, start_block, end_block, ETHERSCAN_API_KEY)
	if transaction_list is None:
		return

	log.data("start_update_worldnft_contract|current_block=%s,start_block=%s,end_block=%s,len_txn=%s", current_block, start_block, end_block, len(transaction_list))

	latest_load_block = start_block
	sender_set = set()
	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

		latest_load_block = max(latest_load_block, int(transaction["blockNumber"]))
		if latest_load_block > current_block:
			return
		sender = str(transaction["from"]).lower()
		sender_set.add(sender)
		log.info("update_worldnft|txn_hash=%s,sender=%s", transaction["hash"], sender)
		method_id = transaction["input"][0:SMART_CONTRACT_METHOD_ID_LENGTH]

		if method_id == CATCH_MONSTER_NFT_METHOD_ID:

			monster_class_id_hash = "0x" + transaction["input"][SMART_CONTRACT_METHOD_ID_LENGTH:SMART_CONTRACT_METHOD_ID_LENGTH + 64]
			monster_class_id = Web3.toInt(hexstr=monster_class_id_hash)

			current_ts = get_timestamp()
			trainer_address = str(transaction["from"]).lower()
			trainer_record = EtheremonDB.WorldTrainerTab.objects.filter(trainer=trainer_address).first()
			monster_create_time = int(transaction["timeStamp"])
			if not trainer_record:
				extra_data = [(monster_class_id, monster_create_time)]
				flag = WorldTrainerFlag.NONE
				if monster_class_id not in FREE_MONSTER_CLASS_IDS:
					flag = WorldTrainerFlag.SPEND_ETH
				EtheremonDB.WorldTrainerTab.objects.create(
					trainer=trainer_address,
					flag=flag,
					extra_data=json.dumps(extra_data),
					create_time=current_ts,
					update_time=current_ts
				)
			else:
				extra_data = json.loads(trainer_record.extra_data)
				existed = False
				for pair in extra_data:
					if pair[0] == monster_class_id and pair[1] == monster_create_time:
						existed = True
						break
				if existed:
					continue
				extra_data.append((monster_class_id, monster_create_time))
				if monster_class_id not in FREE_MONSTER_CLASS_IDS:
					trainer_record.flag = WorldTrainerFlag.SPEND_ETH
				trainer_record.extra_data = json.dumps(extra_data)
				trainer_record.update_time = current_ts
				trainer_record.save()
			log.data("player_catch_monster|address=%s,class_id=%s", trainer_address, monster_class_id)

	if sender_set:
		log.info("update_worldnft|len_sender=%s,latest_load_block=%s", len(sender_set), latest_load_block)
		data_contract = infura_client.getDataContract()
		for player in sender_set:
			result = _sync_player_dex(data_contract, player)
			if result is False:
				log.warn("sync_player_fail|player=%s", player)
				return

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

	ema_settings_manager.set_setting(EmaSetting.SETTING_CONTRACT_WORLD_NFT_BLOCK, record_block)
	elapsed = time.time() - start_time
	if elapsed < 5:
		time.sleep(5-elapsed)
	log.data("end_update_worldnft_contract|record_block=%s,total_txn=%s,total_player=%s,elapsed=%s",
		record_block, len(transaction_list), len(sender_set), elapsed)
def update_adventure_revenue_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_REVENUE_BLOCK)
    end_block = start_block + SMART_CONTRACT_BLOCK_STEP

    start_time = time.time()
    transaction_list = get_txn_list(EtheremonAdventureRevenueContract.ADDRESS,
                                    start_block, end_block, ETHERSCAN_API_KEY)
    if transaction_list is None:
        return

    log.data(
        "start_update_adventure_revenue_contract|current_block=%s,start_block=%s,end_block=%s,len_txn=%s",
        current_block, start_block, end_block, len(transaction_list))

    latest_load_block = start_block
    current_ts = get_timestamp()
    adventure_data_contract = infura_client.getAdventureDataContract()
    token_id_set = set()
    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

        log.info("update_adventure_revenue_contract|txn_hash=%s",
                 transaction["hash"])

        latest_load_block = max(latest_load_block,
                                int(transaction["blockNumber"]))
        if latest_load_block > current_block:
            return
        method_id = transaction["input"][0:SMART_CONTRACT_METHOD_ID_LENGTH]

        sender = str(transaction["from"]).lower()

        if method_id == ADVENTURE_CLAIM_EARNING_METHOD:
            token_id_hash = "0x" + transaction[
                "input"][SMART_CONTRACT_METHOD_ID_LENGTH:
                         SMART_CONTRACT_METHOD_ID_LENGTH + 64]
            token_id = Web3.toInt(hexstr=token_id_hash)
            token_id_set.add(token_id)
            log.info("claim_earning|sender=%s,token_id=%s,txn_hash=%s", sender,
                     token_id, transaction["hash"])

    if token_id_set:
        for token_id in token_id_set:
            claim_data = adventure_data_contract.call().getTokenClaim(token_id)
            eth_amount = 1.0 * claim_data[1] / 10**18
            emont_amount = 1.0 * claim_data[0] / 10**8
            claim_record = EtheremonDB.EmaAdventureClaimTokenTab.objects.filter(
                token_id=token_id).first()
            if not claim_record:
                EtheremonDB.EmaAdventureClaimTokenTab.objects.create(
                    token_id=token_id,
                    claimed_eth_amount=eth_amount,
                    claimed_emont_amount=emont_amount,
                    update_time=current_ts)
            else:
                if claim_record.claimed_eth_amount < eth_amount:
                    claim_record.claimed_eth_amount = eth_amount
                if claim_record.claimed_emont_amount < emont_amount:
                    claim_record.claimed_emont_amount = emont_amount
                claim_record.update_time = current_ts
                claim_record.save()

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

    ema_settings_manager.set_setting(
        EmaSetting.SETTING_CONTRACT_ADVENTURE_REVENUE_BLOCK, record_block)
    elapsed = time.time() - start_time
    if elapsed < 5:
        time.sleep(5 - elapsed)
    log.data(
        "end_update_adventure_contract|record_block=%s,total_txn=%s,elapsed=%s",
        record_block, len(transaction_list), elapsed)
def update_energy_contract():
    infura_client = InfuraClient(INFURA_API_URL)
    current_block = infura_client.getCurrentBlock() - 2

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

    start_time = time.time()
    transaction_list = get_txn_list(EtheremonEnergyContract.ADDRESS,
                                    start_block, end_block, ETHERSCAN_API_KEY)
    if transaction_list is None:
        return

    log.data(
        "start_update_energy_contract|current_block=%s,start_block=%s,end_block=%s,len_txn=%s",
        current_block, start_block, end_block, len(transaction_list))
    '''
	if len(transaction_list) > 50:
		log.data("update_energy|cut_down_txn|current_block=%s,start_block=%s,end_block=%s", current_block, start_block, end_block)
		transaction_list = transaction_list[:50]
	'''

    latest_load_block = start_block
    sender_set = set()
    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

        latest_load_block = max(latest_load_block,
                                int(transaction["blockNumber"]))
        if latest_load_block > current_block:
            return
        sender = str(transaction["from"]).lower()
        sender_set.add(sender)
        log.info("update_energy_contract|txn_hash=%s,sender=%s",
                 transaction["hash"], sender)

    if sender_set:
        time.sleep(5)
        log.info("update_energy_contract|len_sender=%s,latest_load_block=%s",
                 len(sender_set), latest_load_block)
        energy_contract = infura_client.getEnergyContract()
        current_ts = get_timestamp()
        for sender in sender_set:
            (free_amount, paid_amount,
             last_claim) = energy_contract.call().getPlayerEnergy(sender)
            log.info(
                "player_energy_update|sender=%s,current_block=%s,free_amount=%s,paid_amount=%s,last_claim=%s",
                sender, current_block, free_amount, paid_amount, last_claim)
            record = EtheremonDB.EmaPlayerEnergyTab.objects.filter(
                trainer=sender).first()
            if record:
                if free_amount > record.free_amount:
                    latest_gap = free_amount - record.free_amount
                    new_available_energy = record.init_amount + free_amount + record.paid_amount - record.consumed_amount - record.invalid_amount
                    if new_available_energy > 50:
                        deducted_amount = new_available_energy - 50
                        if deducted_amount > latest_gap:
                            record.invalid_amount += latest_gap
                        else:
                            record.invalid_amount += deducted_amount
                record.free_amount = free_amount
                record.paid_amount = paid_amount
                record.last_claim_time = last_claim
                record.update_time = current_ts
                record.save()
            else:
                EtheremonDB.EmaPlayerEnergyTab.objects.create(
                    trainer=sender,
                    init_amount=0,
                    free_amount=free_amount,
                    paid_amount=paid_amount,
                    invalid_amount=0,
                    consumed_amount=0,
                    last_claim_time=last_claim,
                    create_time=current_ts,
                    update_time=current_ts)

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

    ema_settings_manager.set_setting(EmaSetting.SETTING_CONTRACT_ENERGY_BLOCK,
                                     record_block)
    elapsed = time.time() - start_time
    if elapsed < 5:
        time.sleep(5 - elapsed)
    log.data(
        "end_update_energy_contract|record_block=%s,total_txn=%s,total_player=%s,elapsed=%s",
        record_block, len(transaction_list), len(sender_set), elapsed)