def crawl_monster(): infura_client = InfuraClient(INFURA_API_URL) data_contract = infura_client.getDataContract() start_time = time.time() update_count = 0 add_count = 0 total_monster = data_contract.call().totalMonster() current_block_number = infura_client.getCurrentBlock() log.data("start_crawl_monster|total=%s,block_number=%s", total_monster, current_block_number) monster_id = 1 while monster_id <= total_monster: try: result, add_flag, update_flag = _sync_monster_id( data_contract, monster_id) if result is False: break add_count += add_flag update_count += update_flag except: logging.exception("update_ema_monster_fail|monster_id=%s", monster_id) break monster_id += 1 elapsed = time.time() - start_time log.data( "end_crawl_monster|elapsed=%s,total_monster=%s,ending_monster=%s,update_count=%s,adding_count=%s,start_at_block=%s", elapsed, total_monster, monster_id, update_count, add_count, current_block_number)
def fix_stats_monster(): infura_client = InfuraClient(INFURA_API_URL) data_contract = infura_client.getDataContract() monster_records = EtheremonDB.EmaMonsterDataTab.objects.filter( Q(b0=0) | Q(b1=0) | Q(b2=0) | Q(b3=0) | Q(b4=0) | Q(b5=0)).all() for monster in monster_records: if monster.monster_id < 32599: continue base_stats = [] for index in xrange(0, 6): stat_value = data_contract.call().getElementInArrayType( DataArrayType.STAT_BASE, monster.monster_id, index) base_stats.append(stat_value) if 0 in base_stats: log.error("fix_monster_invalid_stat|monster_id=%s,base_stats=%s", monster.monster_id, base_stats) continue monster.b0 = base_stats[0] monster.b1 = base_stats[1] monster.b2 = base_stats[2] monster.b3 = base_stats[3] monster.b4 = base_stats[4] monster.b5 = base_stats[5] monster.exp = 0 monster.save() _sync_monster_id(data_contract, monster.monster_id) time.sleep(0.05) log.info("fix_monster_stats|monster_id=%s", monster.monster_id)
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)
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_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)
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_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)
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)