def update_claim_reward_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_REWARD_BLOCK) end_block = start_block + SMART_CONTRACT_BLOCK_STEP start_time = time.time() transaction_list = get_txn_list(EtheremonClaimRewardContract.ADDRESS, start_block, end_block, ETHERSCAN_API_KEY) latest_load_block = None log.data( "start_update_claim_reward_contract|current_block=%s,start_block=%s,end_block=%s,len_txn=%s", current_block, start_block, end_block, len(transaction_list)) 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 if int(transaction["blockNumber"]) > current_block: continue latest_load_block = int( transaction["blockNumber"]) if latest_load_block is None else max( latest_load_block, int(transaction["blockNumber"])) method_id = transaction["input"][0:SMART_CONTRACT_METHOD_ID_LENGTH] if method_id == CLAIM_REWARD_METHOD: token_bytes = transaction[ "input"][SMART_CONTRACT_METHOD_ID_LENGTH: SMART_CONTRACT_METHOD_ID_LENGTH + 256] token = token_bytes.decode("hex") token_data = decode_claim_reward_token(token) reward_txn_id = token_data["reward_id"] try: txn = transaction_manager.get_transaction_by_id(reward_txn_id) txn.txn_hash = transaction["hash"] txn.status = TxnStatus.FINISHED txn.save() except: logging.exception( "process_claim_reward_failed|reward_txn_id=%s,txn_hash=%s", reward_txn_id, transaction["hash"]) continue record_block = latest_load_block + 1 if latest_load_block is not None else end_block + 1 record_block = min(record_block, current_block) ema_settings_manager.set_or_create_setting( setting_id=EmaSetting.SETTING_CONTRACT_CLAIM_REWARD_BLOCK, name="claim reward contract", value=record_block) elapsed = time.time() - start_time if elapsed < 5: time.sleep(5 - elapsed) log.data( "end_update_claim_reward_contract|record_block=%s,total_txn=%s,total_monster=%s,elapsed=%s", record_block, len(transaction_list), len(monster_id_set), elapsed)
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_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_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 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)
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)
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
def update_burn_mon_contract(): infura_client = InfuraClient(INFURA_API_URL) current_block = infura_client.getCurrentBlock() - 5 start_block = ema_settings_manager.get_setting_value( EmaSetting.SETTING_CONTRACT_BURN_MON) end_block = start_block + SMART_CONTRACT_BLOCK_STEP start_time = time.time() transaction_list = get_txn_list(EtheremonBurnMonContract.ADDRESS, start_block, end_block, ETHERSCAN_API_KEY) latest_load_block = None log.data( "start_update_burn_mon_contract|current_block=%s,start_block=%s,end_block=%s,len_txn=%s", current_block, start_block, end_block, len(transaction_list)) 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 if int(transaction["blockNumber"]) > current_block: continue latest_load_block = int( transaction["blockNumber"]) if latest_load_block is None else max( latest_load_block, int(transaction["blockNumber"])) method_id = transaction["input"][0:SMART_CONTRACT_METHOD_ID_LENGTH] if method_id == BURN_MON_METHOD: contract_mon_id_hash = "0x" + transaction[ "input"][SMART_CONTRACT_METHOD_ID_LENGTH: SMART_CONTRACT_METHOD_ID_LENGTH + 64] contract_mon_id = Web3.toInt(hexstr=contract_mon_id_hash) contract_burn_id_hash = "0x" + transaction[ "input"][SMART_CONTRACT_METHOD_ID_LENGTH + 64:SMART_CONTRACT_METHOD_ID_LENGTH + 128] contract_burn_id = Web3.toInt(hexstr=contract_burn_id_hash) mon_id, burn_id = burn_manager.get_mon_id_from_contract_burn_id( contract_burn_id) burn_request = burn_manager.get_burn_request_by_id(burn_id) if not burn_request or burn_request.mon_id != contract_mon_id: logging.exception( "burn_mon_failed|contract_burn_id=%s,txn_hash=%s", contract_burn_id, transaction["hash"]) continue if burn_request.status in [BurnStatus.FINISHED, BurnStatus.FAILED]: logging.exception( "burn_already_finished|contract_burn_id=%s,txn_hash=%s", contract_burn_id, transaction["hash"]) continue try: with transaction.atomic(): player_uid = user_manager.get_uid_by_address_default_0( burn_request.player_address) if burn_request.reward_value > 0: # Only if there is reward if burn_request.reward_type == BurnRewardTypes.ENERGY: ema_energy_manager.add_energy( burn_request.player_address, burn_request.reward_value) elif burn_request.reward_type == BurnRewardTypes.IN_GAME_EMONT: emont_bonus_manager.add_bonus( player_uid, { EmontBonusType.EVENT_BONUS: burn_request.reward_value }) transaction_manager.create_transaction( player_uid=player_uid, player_address=burn_request.player_address, txn_type=TxnTypes.BURN_MON_REWARD, txn_info="mon %s" % burn_request.mon_id, amount_type=TxnAmountTypes.IN_GAME_EMONT if burn_request.reward_type == BurnRewardTypes.IN_GAME_EMONT else TxnAmountTypes.ENERGY, amount_value=burn_request.reward_value, status=TxnStatus.FINISHED, txn_hash=transaction["hash"]) # 300 EMONT BONUS # if burn_request.mon_level >= 30 and randint(1, 100) <= 3: if randint(1, 100) <= 3: additional_bonus = 500 emont_bonus_manager.add_bonus( player_uid, {EmontBonusType.EVENT_BONUS: additional_bonus}) transaction_manager.create_transaction( player_uid=player_uid, player_address=burn_request.player_address, txn_type=TxnTypes.BURN_MON_REWARD_BONUS, txn_info="mon %s" % burn_request.mon_id, amount_type=TxnAmountTypes.IN_GAME_EMONT, amount_value=additional_bonus, status=TxnStatus.FINISHED, txn_hash=transaction["hash"]) burn_request.status = BurnStatus.FINISHED burn_request.save() except: logging.exception( "burn_mon_failed|contract_burn_id=%s,txn_hash=%s", contract_burn_id, transaction["hash"]) continue record_block = latest_load_block + 1 if latest_load_block is not None else end_block + 1 record_block = min(record_block, current_block) ema_settings_manager.set_or_create_setting( setting_id=EmaSetting.SETTING_CONTRACT_BURN_MON, name="burn mon contract", value=record_block) elapsed = time.time() - start_time if elapsed < 5: time.sleep(5 - elapsed) log.data( "end_update_burn_mon_contract|record_block=%s,total_txn=%s,total_monster=%s,elapsed=%s", record_block, len(transaction_list), len(monster_id_set), elapsed)