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 crawl_monster_egg_data(): infura_client = InfuraClient(INFURA_API_URL) current_block_number = infura_client.getCurrentBlock() transform_data_contract = infura_client.getTransformDataContract() start_time = time.time() total_egg_no = transform_data_contract.call().totalEgg() log.data("start_crawl_egg_data|total_egg=%s,block=%s", total_egg_no, current_block_number) index = 1 while index <= total_egg_no: try: (egg_id, mother_id, class_id, trainer_address, hatch_time, monster_id) = transform_data_contract.call().getEggDataById(index) except Exception as error: log.warn("query_borrow_data_error|index=%s,error=%s", index, error.message) time.sleep(5) infura_client = InfuraClient(INFURA_API_URL) transform_data_contract = infura_client.getTransformDataContract() continue egg_record = EtheremonDB.EmaEggDataTab.objects.filter( egg_id=index).first() if egg_record: 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.create_time = start_time else: 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.data("end_crawl_egg_data|total_egg=%s,block=%s,elapsed=%s", total_egg_no, current_block_number, time.time() - start_time)
def crawl_adventure_presale(): infura_client = InfuraClient(INFURA_API_URL) adventure_presale_contract = infura_client.getAdventurePresaleContract() current_ts = get_timestamp() site_id_index = 1 while site_id_index <= 54: site_item_index = 0 while site_item_index < 10: try: (bidder, bid_id, site_id, amount, bid_time ) = adventure_presale_contract.call().getBidBySiteIndex( site_id_index, site_item_index) if bid_id == 0: log.warn( "query_adventure_presale_invalid|site_id=%s,site_index=%s", site_id_index, site_item_index) time.sleep(3) continue except Exception as error: logging.exception( "query_adventure_presale_exception|site_id=%s,site_index=%s", site_id_index, site_item_index) time.sleep(3) continue bidder = bidder.lower() record = EtheremonDB.EmaAdventurePresaleTab.objects.filter( bid_id=bid_id).first() if record: record.site_id = site_id record.bid_id = bid_id record.site_index = site_item_index record.bidder = bidder record.bid_amount = amount record.bid_time = bid_time else: record = EtheremonDB.EmaAdventurePresaleTab( site_id=site_id, site_index=site_item_index, bid_id=bid_id, bidder=bidder, bid_amount=amount, bid_time=bid_time, token_id=0, update_time=current_ts) log.data( "adventure_presale_query|site_id=%s,site_index=%s,bid_id=%s", site_id_index, site_item_index, bid_id) record.save() site_item_index += 1 site_id_index += 1
def sign_claim_reward(token, address): unlock_account() address = address[2:] infura_client = InfuraClient(INFURA_API_URLS["static_methods"]) claim_reward_contract = infura_client.getClaimRewardContract() hashed_message = claim_reward_contract.call().getVerifySignature( "0x" + address, Web3.toBytes(hexstr="0x" + token)) try: hashed_message = hashed_message.encode("latin1") return sign_message(hashed_message) except: logging.exception("decode_hex_value_fail|token=%s,address=%s,value=%s", token, address, hashed_message) return None
def crawl_trade_txn(from_id): trade_buy_records = EtheremonDB.RevenueTxnTab.objects.filter( contract_address=CONTRACT_ADDRESS).filter( method_id=BUY_METHOD_ID).filter( id__gt=from_id).order_by("id").all() infura_client = InfuraClient(INFURA_API_URL) for trade_buy_record in trade_buy_records: txn_hash = trade_buy_record.txn_hash.lower() if EtheremonDB.MarketHistoryTab.objects.filter( txn_hash=txn_hash).exists(): continue txn_data = infura_client.web3_client.eth.getTransaction(txn_hash) input_data = txn_data.input method_id = input_data[0:SMART_CONTRACT_METHOD_ID_LENGTH] monster_id_hash = "0x" + input_data[ SMART_CONTRACT_METHOD_ID_LENGTH:SMART_CONTRACT_METHOD_ID_LENGTH + 64] monster_id = Web3.toInt(hexstr=monster_id_hash) market_history_price = int(trade_buy_record.eth_amount * (10**6)) market_history_records = list( EtheremonDB.MarketHistoryTab.objects.filter( monster_id=monster_id).filter( txn_hash="").order_by("id").all()) if len(market_history_records) > 0: first_record = market_history_records[0] if abs(first_record.price - market_history_price) > 1000: print "ERROR|price_mismatch|txn_hash=%s,monster_id=%s,record_price=%s,revenue_price=%s" % ( txn_hash, monster_id, first_record.price, market_history_price) return first_record.price = market_history_price first_record.txn_hash = txn_hash first_record.buyer = trade_buy_record.sender first_record.save() print "MAP|txn_hash=%s,history_id=%s,revenue_id=%s" % ( txn_hash, first_record.id, trade_buy_record.id) else: print "ERROR|not_match|txn_hash=%s,monster_id=%s,price=%s,record_len=%s" % ( txn_hash, monster_id, market_history_price, len(market_history_records)) break
def fix_borrow_problem(): infura_client = InfuraClient(INFURA_API_URL) trade_contract = infura_client.getTradeContract() borrow_records = EtheremonDB.EmaMarketTab.objects.filter( type=EmaMarketType.BORROW).all() for borrow_record in borrow_records: extra_data = json.loads(borrow_record.extra_data) release_time = extra_data.get("release_time", 0) if release_time > 2061775712: (sell_price, lending_price, lent, release_time) = trade_contract.call().getTradingInfo( borrow_record.monster_id) extra_data["release_time"] = int(release_time) borrow_record.extra_data = json.dumps(extra_data) borrow_record.save() log.info("fix_borrow|monster_id=%s", borrow_record.monster_id)
def _verify_signature(message, signature, sender): infura_client = InfuraClient(INFURA_API_URLS["verify_signature"]) util_contract = infura_client.getUtilContract() try: if len(signature) < 132: return False elif len(signature) == 132: # Case metamask r = signature[0:66] s = "0x" + signature[66:130] v = int("0x" + signature[130:132], 16) # Specific case if using ecrecover, according to https://github.com/ethereum/wiki/wiki/JavaScript-API#web3ethsign if v in [0, 1]: v += 27 # print(r, s, v) string_message = u'\u0019Ethereum Signed Message:\n%s%s' % (len(message), message) hash_message = Web3.sha3(hexstr=Web3.toHex(string_message)) bytes_hash_message = Web3.toBytes(hexstr=hash_message.encode("latin1")) bytes_r = Web3.toBytes(hexstr=r) bytes_s = Web3.toBytes(hexstr=s) verify_address = util_contract.call().verifySignature(bytes_hash_message, v, bytes_r, bytes_s) return verify_address.lower() == sender else: # string_message = u'\u0019Ethereum Signed Message:\n%s%s' % (len(message), message) hash_message = Web3.sha3(hexstr=Web3.toHex(message)).encode("latin1") bytes_hash_message = Web3.toBytes(hexstr=hash_message.encode("latin1")) # Case Dapper erc1271_core_contract = infura_client.getDapperUserContract(sender) magic_value = erc1271_core_contract.call().isValidSignature(bytes_hash_message, Web3.toBytes(hexstr=signature)) return "0x" + magic_value.encode("latin1").encode("hex") == ERC1271_MAGIC_VALUE except: print("verify_signature_fail|message=%s,signature=%s,sender=%s", message, signature, sender) return False
def crawl_explore_info(explore_id): infura_client = InfuraClient(INFURA_API_URL) adventure_explore_contract = infura_client.getAdventureExploreContract() explore_data = adventure_explore_contract.call().getExploreItem(explore_id) if explore_data[2] == 0: log.warn("explore_data_invalid|explore_id=%s", explore_id) return explore_ending_block = explore_data[4] + EXPLORE_MIN_BLOCK_GAP + explore_data[4] % EXPLORE_MIN_BLOCK_GAP current_record = EtheremonDB.EmaAdventureExploreTab.objects.filter(explore_id=explore_id).first() sm_sender = explore_data[0].lower() if not current_record: current_ts = get_timestamp() EtheremonDB.EmaAdventureExploreTab.objects.create( explore_id=explore_id, fee_type=EmaAdventureExploreFee.NONE, sender=sm_sender, 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='', create_time=current_ts ) log.info("add_explore_info|explore_id=%s", explore_id) else: if current_record.sender != sm_sender or current_record.start_block != explore_data[4] or current_record.monster_id != explore_data[2]: log.warn("mismatch_db_explore|explore_id=%s,sender=%s,sm_sender=%s,start_block=%s,sm_start_block=%s,monster_id=%s,sm_monster_id=%s", explore_id, current_record.sender, sm_sender, current_record.start_block, explore_data[4], current_record.monster_id, explore_data[2]) current_record.sender = sm_sender current_record.monster_type = explore_data[1] current_record.monster_id = explore_data[2] current_record.site_id = explore_data[3] 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.start_block = explore_data[4] current_record.save()
def fix_bonus_egg(): infura_client = InfuraClient(INFURA_API_URL) current_block_number = infura_client.getCurrentBlock() mother_egg_records = EtheremonDB.EmaEggDataTab.objects.filter( mother_id__gt=0).filter( class_id__lt=25).values('mother_id').distinct() mother_id = [] for mother_egg_record in mother_egg_records: mother_id.append(mother_egg_record["mother_id"]) # monster transform_contract = infura_client.getTransformContract() monster_records = list( EtheremonDB.EmaMonsterDataTab.objects.filter( monster_id__in=mother_id).filter(egg_bonus__gt=0).all()) count = 0 while count < len(monster_records): monster_record = monster_records[count] try: egg_bonus = transform_contract.call().getBonusEgg( monster_record.monster_id) except Exception as error: log.warn("get_egg_bonus_error|monster_id=%s,error=%s", monster_record.monster_id, error) time.sleep(4) continue if monster_record.egg_bonus != egg_bonus: log.info( "fix_egg_bonus|monster_id=%s,before_bonus=%s,after_bonus=%s,block=%s", monster_record.monster_id, monster_record.egg_bonus, egg_bonus, current_block_number) EtheremonDB.EmaMonsterDataTab.objects.filter( monster_id=monster_record.monster_id).update( egg_bonus=egg_bonus) else: log.info("correct_egg_bonus|monster_id=%s", monster_record.monster_id) count += 1
def fix_egg_info(): infura_client = InfuraClient(INFURA_API_URL) transform_data_contract = infura_client.getTransformDataContract() egg_records = list( EtheremonDB.EmaEggDataTab.objects.filter(class_id=0).all()) index = 0 while index < len(egg_records): egg_record = egg_records[index] (egg_id, mother_id, class_id, trainer_address, hatch_time, monster_id) = transform_data_contract.call().getEggDataById( egg_record.egg_id) if class_id is 0: log.warn("invalid_egg_data|egg_id=%s", index) continue 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() index += 1
def crawl_token_claim(token_id): infura_client = InfuraClient(INFURA_API_URL) adventure_data_contract = infura_client.getAdventureDataContract() current_ts = get_timestamp() 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()
def get_adventure_pending_explore(request, data): trainer_address = data["trainer_address"].lower() response_data = { "explore_id": 0, "monster_type": 0, "monster_id": 0, "monster_class": 0, "site_id": 0, "start_block": 0, "end_block": 0, "current_block": 0, "estimated_time_back": 0, "can_fasten": False, } pending_explore = get_pending_explore(trainer_address) if pending_explore: if pending_explore.monster_type == EmaAdventureMonsterType.ETHEREMON: monster_data = get_monster_data(pending_explore.monster_id) if monster_data.class_id == 21: log.warn("sending_invalid_monster|explore_id=%s", pending_explore.explore_id) return api_response_result(request, ResultCode.SUCCESS, response_data) response_data["monster_class"] = monster_data.class_id response_data["explore_id"] = pending_explore.explore_id response_data["monster_type"] = pending_explore.monster_type response_data["monster_id"] = pending_explore.monster_id response_data["site_id"] = pending_explore.site_id response_data["start_block"] = pending_explore.start_block response_data["end_block"] = pending_explore.end_block infura_client = InfuraClient(INFURA_API_URLS["adventure_task"]) response_data["current_block"] = infura_client.getCurrentBlock() if response_data["end_block"] > response_data["current_block"]: response_data["estimated_time_back"] = (response_data["end_block"] - response_data["current_block"]) * 15 if response_data["current_block"] >= response_data["start_block"] + 2: response_data["can_fasten"] = True return api_response_result(request, ResultCode.SUCCESS, response_data)
def crawl_site_revenue(site_id): infura_client = InfuraClient(INFURA_API_URL) adventure_data_contract = infura_client.getAdventureDataContract() site_revenue = adventure_data_contract.call().getLandRevenue(site_id) current_ts = get_timestamp() 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()
def crawl_monster_bonus_egg(): infura_client = InfuraClient(INFURA_API_URL) current_block_number = infura_client.getCurrentBlock() transform_contract = infura_client.getTransformDataContract() start_time = time.time() monster_records = list( EtheremonDB.EmaMonsterDataTab.objects.filter(class_id__lte=24).all()) log.data("start_crawl_monster_bonus_egg|total_monster=%s,block=%s", len(monster_records), current_block_number) count = 0 for monster_record in monster_records: count += 1 egg_bonus = int(transform_contract.call().getBonusEgg( monster_record.monster_id)) monster_record.egg_bonus = egg_bonus monster_record.save() log.info("ema_crawl_monster_egg|monster_id=%s,egg_bonus=%s", monster_record.monster_id, egg_bonus) log.data("end_crawl_monster_bonus_egg|count=%s,block=%s,elapsed=%s", count, current_block_number, time.time() - start_time)
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)
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 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_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_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_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_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 crawl_market(): infura_client = InfuraClient(INFURA_API_URL) trade_contract = infura_client.getTradeContract() total_sell = trade_contract.call().getTotalSellingMonsters() total_borrow = trade_contract.call().getTotalBorrowingMonsters() current_block_number = infura_client.getCurrentBlock() log.data( "start_crawl_market|total_sell=%s,total_borrow=%s,block_number=%s", total_sell, total_borrow, current_block_number) # clear all table EtheremonDB.EmaMarketTab.objects.filter(id__gte=0).delete() # clone sell current_ts = get_timestamp() index = 0 while index < total_sell: try: (obj_id, class_id, exp, bp, trainer, create_index, price, create_time) = trade_contract.call().getSellingItem(index) except Exception as error: log.warn("query_sell_data_error|index=%s,error=%s", index, error.message) time.sleep(5) infura_client = InfuraClient(INFURA_API_URL) trade_contract = infura_client.getTradeContract() continue price = price / MARKET_PRICE_DIVISION extra_data = {} EtheremonDB.EmaMarketTab.objects.create( type=EmaMarketType.SELL, player=trainer, monster_id=obj_id, price=price, status=EmaMarketStatus.NONE, extra_data=json.dumps(extra_data), create_time=create_time) index += 1 # clone borrow index = 0 while index < total_borrow: try: (obj_id, owner, borrower, price, lent, create_time, release_time) = trade_contract.call().getBorrowingItem(index) except Exception as error: log.warn("query_borrow_data_error|index=%s,error=%s", index, error.message) time.sleep(5) infura_client = InfuraClient(INFURA_API_URL) trade_contract = infura_client.getTradeContract() continue owner = owner.lower() price = price / MARKET_PRICE_DIVISION extra_data = { "borrower": borrower, "create_time": create_time, "release_time": release_time } status = EmaMarketStatus.NONE if lent: status = EmaMarketStatus.LENT EtheremonDB.EmaMarketTab.objects.create( type=EmaMarketType.BORROW, player=owner, monster_id=obj_id, price=price, status=status, extra_data=json.dumps(extra_data), create_time=create_time) index += 1 log.data("end_crawl_market|block=%s,elapsed=%s", current_block_number, time.time() - current_ts)
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_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_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 crawl_rank_data(): start_time = time.time() infura_client = InfuraClient(INFURA_API_URL) rank_data_contract = infura_client.getRankDataContract() rank_reward_contract = infura_client.getRankRewardContract() ladder_contract = infura_client.getLadderContract() current_block = infura_client.getCurrentBlock() total_player = rank_data_contract.call().totalPlayer() log.data("start_crawl_rank_data|total=%s,block_number=%s", total_player, current_block) for index in range(total_player): player_id = index + 1 player_contract_data = rank_data_contract.call().getPlayerData( player_id) if not player_contract_data[4]: log.warn("invalid_contract_data|player_contract_data=%s", player_contract_data) continue player_record = get_rank_data(player_id) if not player_record: player_record = EtheremonDB.UserLadderTab(player_id=player_id) trainer_address = player_contract_data[0] trainer_address = trainer_address.lower() player_record.trainer = trainer_address player_record.point = player_contract_data[3] player_record.total_win = player_contract_data[1] player_record.total_lose = player_contract_data[2] player_record.a0 = player_contract_data[4] player_record.a1 = player_contract_data[5] player_record.a2 = player_contract_data[6] player_record.s0 = player_contract_data[7] if player_contract_data[ 7] else 0 player_record.s1 = player_contract_data[8] if player_contract_data[ 8] else 0 player_record.s2 = player_contract_data[9] if player_contract_data[ 9] else 0 # total claim match total_win_claim = rank_reward_contract.call().getWinClaim(player_id) player_record.total_match = player_record.total_win + player_record.total_lose + total_win_claim # calculate avg bp total_bp = ladder_contract.call().getMonsterCP(player_record.a0) total_bp += ladder_contract.call().getMonsterCP(player_record.a1) total_bp += ladder_contract.call().getMonsterCP(player_record.a2) # calculate avg level total_level = 0 level_info = ladder_contract.call().getMonsterLevel(player_record.a0) total_level += level_info[1] level_info = ladder_contract.call().getMonsterLevel(player_record.a1) total_level += level_info[1] level_info = ladder_contract.call().getMonsterLevel(player_record.a2) total_level += level_info[1] player_record.avg_bp = total_bp / 3 player_record.avg_level = total_level / 3 player_record.energy = player_contract_data[10] player_record.last_claim = player_contract_data[11] player_record.update_time = get_timestamp() player_record.save() elapsed = time.time() - start_time log.data("end_crawl_rank_data|elapsed=%s,total_player=%s,start_block=%s", elapsed, total_player, current_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)