def block(self, conf): """Query block with given parameter(height or hash) :param conf: block command configuration :return: result of query """ uri, version = uri_parser(conf['uri']) icon_service, response = IconService(HTTPProvider(uri, version)), None hash, number = conf.get('hash'), conf.get('number') if hash is not None and number is not None: raise TBearsCommandException( "Only one of id and number can be passed.") if hash is not None: response = icon_service.get_block(hash, True, BLOCK_0_3_VERSION) if number is not None: response = icon_service.get_block(convert_hex_str_to_int(number), True, BLOCK_0_3_VERSION) if response is None: raise TBearsCommandException( "You have to specify block height or block hash") if "error" in response: print(json.dumps(response, indent=4)) else: print(f"block info : {json.dumps(response, indent=4)}") return response
def test_set_http_provider_with_param(self): # the initializer icon_service = IconService(HTTPProvider(self.FULL_PATH_URL)) self.assertEqual(type(icon_service.get_block("latest")), dict) # the new initializer icon_service = IconService( HTTPProvider(self.BASE_PATH_URL, self.VERSION)) self.assertEqual(type(icon_service.get_block("latest")), dict)
def get_block(self, block_height): icon_service = IconService(HTTPProvider(PrepRPCCalls.USE_NET)) latest_block = icon_service.get_block("latest") if latest_block['height'] < block_height: return None block = icon_service.get_block(block_height) return block
def test_integrate_converter(self): """ Test integrating for the converter which checks that all of the data about the block, transaction, and transaction result have the right format. [Purpose] Check all of the data about the block, transaction, and transaction result. [Scenario] 1. Get the last block data and validate the block data. 2. Get all of the transaction data on that block and validate the transaction data. 3. Get all of the transaction result data on that transaction and validate the transaction result data. 4. Repeatedly, get the other blocks from the last to the first and validate all of three kinds of the data. """ logger = getLogger("TEST CONVERTER") # No need to use logging, remove the line. set_logger(logger, 'DEBUG') logger.debug("TEST CONVERTER START") icon_service = IconService(HTTPProvider(TEST_HTTP_ENDPOINT_URI_V3)) # Scenario 1: Get the last block data and validate the block data. last_block_height = icon_service.get_block("latest")["height"] for height in range( 0, last_block_height if last_block_height < 30 else 30): # Scenario 2: Get all of the transaction data on that block and validate the transaction data. block = icon_service.get_block(height) # pprint.pprint(block) self.assertTrue(validate_block(block)) # Except for the genesis block if height > 0: for transaction_in_block in block[ "confirmed_transaction_list"]: # Scenario 3: Get all of the transaction result data on that transaction # and validate the transaction result data. transaction_result = icon_service.get_transaction_result( transaction_in_block["txHash"]) # logger.debug(transaction_result) # pprint.pprint(transaction_result) self.assertTrue( validate_transaction_result(transaction_result)) # Scenario 4: Repeatedly, get the other blocks from the last to the first # and validate all of three kinds of the data. transaction = icon_service.get_transaction( transaction_in_block["txHash"]) # logger.debug(transaction) # pprint.pprint(transaction) self.assertTrue(validate_transaction(transaction))
def _set_samples(self, domain: str) -> (list, list, list, list): buf_blocks = list() buf_transactions_on_blocks = list( ) # block's transaction list which means confirmed transaction list buf_transactions = list() # return value of 'get_transaction' buf_transaction_results = list( ) # return value of 'get_transaction_result' icon_service = IconService(HTTPProvider(domain, VERSION_FOR_TEST)) target_block_heights = self._set_target_heights() for height in target_block_heights: block = icon_service.get_block(height, full_response=True) block = block['result'] buf_blocks.append(block) for transaction in block[ 'confirmed_transaction_list' if block['version'] == BLOCK_0_1A_VERSION else 'transactions']: buf_transactions_on_blocks.append(transaction) if ('tx_hash' or 'txHash') in transaction: tx_hash = transaction['tx_hash' if 'tx_hash' in transaction else 'txHash'] tx_hash = add_0x_prefix(tx_hash) tx = icon_service.get_transaction(tx_hash, full_response=True) tx = tx['result'] buf_transactions.append(tx) tx_result = icon_service.get_transaction_result( tx_hash, full_response=True) tx_result = tx_result['result'] buf_transaction_results.append(tx_result) return buf_blocks, buf_transactions_on_blocks, buf_transactions, buf_transaction_results
def test_call_api_by_the_initializer_with_valid_url(self): http_provider = HTTPProvider(self.FULL_PATH_URL) self.assertIsNotNone(http_provider._full_path_url) try: http_provider._base_domain_url except AttributeError: self.assertTrue(True) icon_service = IconService(http_provider) self.assertEqual(type(icon_service.get_block("latest")), dict)
def test_set_http_provider_by_new_initializer_with_valid_url(self): valid_url = "http://localhost:9000" version = 3 http_provider = HTTPProvider(valid_url, version) self.assertTrue(http_provider.is_connected()) icon_service = IconService(HTTPProvider(valid_url, version)) self.assertEqual(type(icon_service.get_block("latest")), dict) http_provider = HTTPProvider(valid_url, version, request_kwargs={ 'timeout': 60, 'allow_redirects': False, 'verify': True }) self.assertTrue(http_provider.is_connected()) icon_service = IconService(http_provider) self.assertEqual(type(icon_service.get_block("latest")), dict)
def test_integrate_converter(self): """ Test integrating for the converter which checks that all of the data about the block, transaction, and transaction result have the right format. [Purpose] Check all of the data about the block, transaction, and transaction result. [Scenario] 1. Get the last block data and validate the block data. 2. Get all of the transaction data on that block and validate the transaction data. 3. Get all of the transaction result data on that transaction and validate the transaction result data. 4. Repeatedly, get the other blocks from the last to the first and validate all of three kinds of the data. """ icon_service = IconService(HTTPProvider(BASE_DOMAIN_URL_V3_FOR_TEST, VERSION_FOR_TEST)) # Scenario 1: Get the last block data and validate the block data. last_block_height = icon_service.get_block("latest")["height"] for height in range(0, last_block_height if last_block_height < 30 else 30): # Scenario 2: Get all of the transaction data on that block and validate the transaction data. block = icon_service.get_block(height) # pprint.pprint(block) self.assertTrue(validate_block(block)) # Except for the genesis block if height > 0: for transaction_in_block in block["confirmed_transaction_list"]: # Scenario 3: Get all of the transaction result data on that transaction # and validate the transaction result data. transaction_result = icon_service.get_transaction_result(transaction_in_block["txHash"]) # logger.debug(transaction_result) # pprint.pprint(transaction_result) self.assertTrue(validate_transaction_result(transaction_result)) # Scenario 4: Repeatedly, get the other blocks from the last to the first # and validate all of three kinds of the data. transaction = icon_service.get_transaction(transaction_in_block["txHash"]) # logger.debug(transaction) # pprint.pprint(transaction) self.assertTrue(validate_transaction(transaction))
def lastblock(self, conf): """Query last block :param conf: lastblock command configuration :return: result of query """ uri, version = uri_parser(conf['uri']) icon_service = IconService(HTTPProvider(uri, version)) response = icon_service.get_block("latest", True) if "error" in response: print(json.dumps(response, indent=4)) else: print(f"block info : {json.dumps(response, indent=4)}") return response
def blockbyhash(self, conf): """Query block with given hash :param conf: blockbyhash command configuration :return: result of query """ uri, version = uri_parser(conf['uri']) icon_service = IconService(HTTPProvider(uri, version)) response = icon_service.get_block(conf['hash'], True) if "error" in response: print('Got an error response') print(json.dumps(response, indent=4)) else: print(f"block info : {json.dumps(response, indent=4)}") return response
def test_set_http_provider_with_param(self): icon_service = IconService(HTTPProvider(TEST_HTTP_ENDPOINT_URI_V3)) self.assertEqual(type(icon_service.get_block("latest")), dict)
class ServiceManager: def __init__(self, node_conf_path: str, wallet_path: str, passwd: str): # Node configuration to be connected with open(node_conf_path, "r") as f: node_conf = json.load(f) self._my_chain_name = node_conf["chain_name"] self._nid = int(node_conf["nid"], 16) self.web_protocol = node_conf["web_protocol"] if self.web_protocol == "ssl": self._icon_service = IconService( HTTPProvider("https://" + node_conf["address"], 3)) self._ws_block = f"wss://{node_conf['address']}/api/ws/{node_conf['channel']}" elif self.web_protocol == "http": self._icon_service = IconService( HTTPProvider("http://" + node_conf["address"], 3)) self._ws_block = f"ws://{node_conf['address']}/api/node/{node_conf['channel']}" else: print("[error] Not supported web_protocol") sys.exit() # Set wallet of actor self._wallet = KeyWallet.load(wallet_path, passwd) self._score_info = node_conf["scores"] # TODO 실제로는 없어도 되는 method def get_block(self, value=None) -> dict: block = self._icon_service.get_block(value) return block def get_rep_list(self): resp = self.query("cx0000000000000000000000000000000000000000", "getPRepTerm", {}) preps_info = resp["preps"] preps_list = [] for item in preps_info: preps_list.append(item["address"]) return preps_list def get_rep_list_local(self): node_info = f"http://localhost:9100/api/node" headers = {"content-type": "application/json"} body = {"jsonrpc": "2.0", "method": "node_getChannelInfos", "id": 1234} resp = requests.post(node_info, data=json.dumps(body), headers=headers).json() assert resp["jsonrpc"] assert resp["id"] preps_list = [] for item in resp["result"]["channel_infos"]["icon_dex"]["peers"]: preps_list.append(item["id"]) return preps_list def get_tx_result_by_hash(self, tx_hash: str) -> dict: tx_result = self._icon_service.get_transaction_result(tx_hash) for key, value in tx_result.items(): if isinstance(value, int): tx_result[key] = hex(value) try: tx_result["logsBloom"] = "0x" + tx_result["logsBloom"].hex() except KeyError: pass return tx_result def call_tx(self, score_addr: str, method: str, params: dict) -> dict: transaction = CallTransactionBuilder() \ .from_(self._wallet.get_address()) \ .to(score_addr) \ .step_limit(STEP_LIMIT) \ .nid(self._nid) \ .nonce(NONCE) \ .method(method) \ .params(params) \ .build() return self._send_transaction(transaction) def query(self, score_addr: str, method: str, params: dict): query = CallBuilder() \ .from_(self._wallet.get_address()) \ .to(score_addr) \ .method(method) \ .params(params) \ .build() return self._icon_service.call(query) def dummy_tx_send(self, loop: int): for i in range(loop): transaction = CallTransactionBuilder().\ from_(self._wallet.get_address()).\ to(self._wallet.get_address()).\ step_limit(STEP_LIMIT).\ value(1).\ nid(self.nid).\ nonce(NONCE).\ method("transfer").build() signed_tx = SignedTransaction(transaction, self._wallet) tx_hash = self.icon_service.send_transaction(signed_tx) print(f"[dc_log] dummy tx hash: {tx_hash}") def _send_transaction(self, transaction) -> dict: signed_tx = SignedTransaction(transaction, self._wallet) tx_hash = self._icon_service.send_transaction(signed_tx) sleep(SLEEP_TIMER) return self.get_tx_result_by_hash(tx_hash) @staticmethod def print_result(data: dict): print( "----------------------------------------------------------------------------------" ) print("<Tx_result>") print(f" - txHash: {data['txHash']}") print(f" - height: {data['blockHeight']}") print(f" - blockHash: {data['blockHash']}") try: print(f" - scoreAddr: {data['scoreAddress']}") except KeyError: pass print(f" - stepUsed: {data['stepUsed']}") print(f" - status: {data['status']}") print( "----------------------------------------------------------------------------------\n\n" ) @property def ws_addr(self): return self._ws_block @property def chain_name(self): return self._my_chain_name @property def nid(self): return self._nid @property def from_account(self): return self._wallet.get_address() @property def icon_service(self): return self._icon_service
def test_integrate_converter(self): """ Test integrating for the converter which checks that all of the data about the block, transaction, and transaction result have the right format. [Purpose] Check all of the data about the block, transaction, and transaction result. [Scenario] 1. Get the last block data and validate the block data. 2. Get all of the transaction data on that block and validate the transaction data. 3. Get all of the transaction result data on that transaction and validate the transaction result data. 4. Repeatedly, get the other blocks from the last to the first and validate all of three kinds of the data. """ test_domains = self.domains + [BASE_DOMAIN_URL_V3_FOR_TEST] max_block_height = 100 for domain in test_domains: icon_service = IconService(HTTPProvider(domain, VERSION_FOR_TEST)) last_block_height = icon_service.get_block("latest")["height"] block_versions = [BLOCK_0_1A_VERSION, BLOCK_0_3_VERSION] for block_version in block_versions: if block_version == BLOCK_0_1A_VERSION: block_template = BLOCK_0_1a key_name_of_transactions = 'confirmed_transaction_list' else: # After Mainnet apply for block 0.3, remove this remark right away. continue block_template = BLOCK_0_3 key_name_of_transactions = 'transactions' for height in range(last_block_height if last_block_height < max_block_height else max_block_height): # Check block block = icon_service.get_block(height, full_response=True, block_version=block_version) block = block['result'] converted_block = icon_service.get_block( height, block_version=block_version) block_template = get_block_template_to_convert_transactions_for_genesis( block, block_template) self.assertTrue( validate_block(block_template, block, converted_block)) if block["height"] == 0: continue for transaction_in_block in converted_block[ key_name_of_transactions]: # Check transaction result tx_result = icon_service.get_transaction_result( transaction_in_block["txHash"], True) tx_result = tx_result['result'] converted_transaction_result = icon_service.get_transaction_result( transaction_in_block["txHash"]) self.assertTrue( validate_transaction_result( TRANSACTION_RESULT, tx_result, converted_transaction_result)) # Check transaction transaction = icon_service.get_transaction( transaction_in_block["txHash"], True) transaction = transaction['result'] converted_transaction = icon_service.get_transaction( transaction_in_block["txHash"]) self.assertTrue( validate_transaction(TRANSACTION, transaction, converted_transaction))
from iconsdk.icon_service import IconService from iconsdk.providers.http_provider import HTTPProvider icon_service = IconService( HTTPProvider("https://bicon.net.solidwallet.io/api/v3")) block = icon_service.get_block("latest") print(block)
class Base(IconIntegrateTestBase): def setUp(self): super().setUp(block_confirm_interval=1, network_only=True) # if you want to send request to network, uncomment next line and set self.TEST_HTTP_ENDPOINT_URI_V3 self.icon_service = IconService( HTTPProvider(TEST_HTTP_ENDPOINT_URI_V3)) # ================= Tool ================= def _get_block_height(self) -> int: block_height: int = 0 if self.icon_service: block = self.icon_service.get_block("latest") block_height = block['height'] return block_height def _make_blocks(self, to: int): block_height = self._get_block_height() while to > block_height: self.process_message_tx(self.icon_service, "test message") block_height += 1 def _make_blocks_to_next_calculation(self) -> int: iiss_info = self.get_iiss_info() next_calculation = int(iiss_info.get('nextCalculation', 0), 16) self._make_blocks(to=next_calculation) self.assertEqual(self._get_block_height(), next_calculation) return next_calculation @staticmethod def create_deploy_score_tx( score_path: str, from_: 'KeyWallet', to: str = SCORE_INSTALL_ADDRESS) -> 'SignedTransaction': transaction = DeployTransactionBuilder() \ .from_(from_.get_address()) \ .to(to) \ .step_limit(100_000_000_000) \ .nid(DEFAULT_NID) \ .nonce(0) \ .content_type("application/zip") \ .content(gen_deploy_data_content(score_path)) \ .build() # Returns the signed transaction object having a signature signed_transaction = SignedTransaction(transaction, from_) return signed_transaction @staticmethod def create_set_revision_tx(from_: 'KeyWallet', revision: int) -> 'SignedTransaction': # set revision transaction = CallTransactionBuilder() \ .from_(from_.get_address()) \ .to(GOVERNANCE_ADDRESS) \ .step_limit(10_000_000) \ .nid(3) \ .nonce(100) \ .method("setRevision") \ .params({"code": revision, "name": f"1.4.{revision}"}) \ .build() # Returns the signed transaction object having a signature signed_transaction = SignedTransaction(transaction, from_) return signed_transaction @staticmethod def create_transfer_icx_tx(from_: 'KeyWallet', to_: str, value: int, step_limit: int = DEFAULT_STEP_LIMIT, nid: int = DEFAULT_NID, nonce: int = 0) -> 'SignedTransaction': transaction = TransactionBuilder() \ .from_(from_.get_address()) \ .to(to_) \ .value(value) \ .step_limit(step_limit) \ .nid(nid) \ .nonce(nonce) \ .build() # Returns the signed transaction object having a signature signed_transaction = SignedTransaction(transaction, from_) return signed_transaction @staticmethod def create_register_prep_tx(key_wallet: 'KeyWallet', reg_data: Dict[str, Union[str, bytes]] = None, value: int = 0, step_limit: int = DEFAULT_STEP_LIMIT, nid: int = DEFAULT_NID, nonce: int = 0) -> 'SignedTransaction': if not reg_data: reg_data = Base._create_register_prep_params(key_wallet) transaction = CallTransactionBuilder(). \ from_(key_wallet.get_address()). \ to(SYSTEM_ADDRESS). \ value(value). \ step_limit(step_limit). \ nid(nid). \ nonce(nonce). \ method("registerPRep"). \ params(reg_data). \ build() signed_transaction = SignedTransaction(transaction, key_wallet) return signed_transaction @staticmethod def create_unregister_prep_tx(key_wallet: 'KeyWallet', value: int = 0, step_limit: int = DEFAULT_STEP_LIMIT, nid: int = DEFAULT_NID, nonce: int = 0) -> 'SignedTransaction': transaction = CallTransactionBuilder(). \ from_(key_wallet.get_address()). \ to(SYSTEM_ADDRESS). \ value(value). \ step_limit(step_limit). \ nid(nid). \ nonce(nonce). \ method("unregisterPRep"). \ build() signed_transaction = SignedTransaction(transaction, key_wallet) return signed_transaction @staticmethod def create_set_prep_tx(key_wallet: 'KeyWallet', irep: int = None, set_data: Dict[str, Union[str, bytes]] = None, value: int = 0, step_limit: int = DEFAULT_STEP_LIMIT, nid: int = DEFAULT_NID, nonce: int = 0) -> 'SignedTransaction': if set_data is None: set_data = {} if irep is not None: set_data[ConstantKeys.IREP] = hex(irep) transaction = CallTransactionBuilder(). \ from_(key_wallet.get_address()). \ to(SYSTEM_ADDRESS). \ value(value). \ step_limit(step_limit). \ nid(nid). \ nonce(nonce). \ method("setPRep"). \ params(set_data). \ build() signed_transaction = SignedTransaction(transaction, key_wallet) return signed_transaction @staticmethod def create_set_stake_tx(key_wallet: KeyWallet, stake: int, value: int = 0, step_limit: int = DEFAULT_STEP_LIMIT, nid: int = DEFAULT_NID, nonce: int = 0) -> 'SignedTransaction': transaction = CallTransactionBuilder(). \ from_(key_wallet.get_address()). \ to(SYSTEM_ADDRESS). \ value(value). \ step_limit(step_limit). \ nid(nid). \ nonce(nonce). \ method("setStake"). \ params({"value": hex(stake)}). \ build() signed_transaction = SignedTransaction(transaction, key_wallet) return signed_transaction @staticmethod def create_set_delegation_tx(key_wallet: KeyWallet, delegations: List[Tuple['KeyWallet', int]], value: int = 0, step_limit: int = DEFAULT_STEP_LIMIT, nid: int = DEFAULT_NID, nonce: int = 0) -> 'SignedTransaction': delegations = Base.create_delegation_params(delegations) transaction = CallTransactionBuilder(). \ from_(key_wallet.get_address()). \ to(SYSTEM_ADDRESS). \ value(value). \ step_limit(step_limit). \ nid(nid). \ nonce(nonce). \ method("setDelegation"). \ params({"delegations": delegations}). \ build() signed_transaction = SignedTransaction(transaction, key_wallet) return signed_transaction @staticmethod def create_claim_iscore_tx(key_wallet: 'KeyWallet', value: int = 0, step_limit: int = DEFAULT_STEP_LIMIT, nid: int = DEFAULT_NID, nonce: int = 0) -> 'SignedTransaction': transaction = CallTransactionBuilder(). \ from_(key_wallet.get_address()). \ to(SYSTEM_ADDRESS). \ value(value). \ step_limit(step_limit). \ nid(nid). \ nonce(nonce). \ method("claimIScore"). \ build() signed_transaction = SignedTransaction(transaction, key_wallet) return signed_transaction def get_prep_list(self, start_index: Optional[int] = None, end_index: Optional[int] = None) -> dict: params = {} if start_index is not None: params['startRanking'] = hex(start_index) if end_index is not None: params['endRanking'] = hex(end_index) call = CallBuilder() \ .from_(self._test1.get_address()) \ .to(SYSTEM_ADDRESS) \ .method("getPRepList") \ .params(params) \ .build() response = self.process_call(call, self.icon_service) return response def get_main_prep_list(self) -> dict: call = CallBuilder() \ .from_(self._test1.get_address()) \ .to(SYSTEM_ADDRESS) \ .method("getMainPRepList") \ .build() response = self.process_call(call, self.icon_service) return response def get_sub_prep_list(self) -> dict: call = CallBuilder() \ .from_(self._test1.get_address()) \ .to(SYSTEM_ADDRESS) \ .method("getSubPRepList") \ .build() response = self.process_call(call, self.icon_service) return response def get_prep(self, key_wallet: 'KeyWallet') -> dict: call = CallBuilder() \ .from_(self._test1.get_address()) \ .to(SYSTEM_ADDRESS) \ .method("getPRep") \ .params({"address": key_wallet.get_address()}) \ .build() response = self.process_call(call, self.icon_service) return response def get_stake(self, key_wallet: 'KeyWallet') -> dict: call = CallBuilder() \ .from_(self._test1.get_address()) \ .to(SYSTEM_ADDRESS) \ .method("getStake") \ .params({"address": key_wallet.get_address()}) \ .build() response = self.process_call(call, self.icon_service) return response def get_delegation(self, key_wallet: 'KeyWallet') -> dict: call = CallBuilder() \ .from_(self._test1.get_address()) \ .to(SYSTEM_ADDRESS) \ .method("getDelegation") \ .params({"address": key_wallet.get_address()}) \ .build() response = self.process_call(call, self.icon_service) return response def get_balance(self, key_wallet: 'KeyWallet') -> dict: return self.icon_service.get_balance(key_wallet.get_address()) def query_iscore(self, key_wallet: 'KeyWallet') -> dict: call = CallBuilder() \ .from_(self._test1.get_address()) \ .to(SYSTEM_ADDRESS) \ .method("queryIScore") \ .params({"address": key_wallet.get_address()}) \ .build() response = self.process_call(call, self.icon_service) return response def get_iiss_info(self) -> dict: call = CallBuilder() \ .from_(self._test1.get_address()) \ .to(SYSTEM_ADDRESS) \ .method("getIISSInfo") \ .build() response = self.process_call(call, self.icon_service) return response @staticmethod def _create_register_prep_params( key_wallet: 'KeyWallet') -> Dict[str, Union[str, bytes]]: name = f"node{key_wallet.get_address()[2:7]}" return { ConstantKeys.NAME: name, ConstantKeys.EMAIL: f"node{name}@example.com", ConstantKeys.WEBSITE: f"https://node{name}.example.com", ConstantKeys.DETAILS: f"https://node{name}.example.com/details", ConstantKeys.P2P_END_POINT: f"https://node{name}.example.com:7100", ConstantKeys.PUBLIC_KEY: f"0x{key_wallet.bytes_public_key.hex()}" } @staticmethod def create_delegation_params( params: List[Tuple['KeyWallet', int]]) -> List[Dict[str, str]]: return [{ "address": key_wallet.get_address(), "value": hex(value) } for (key_wallet, value) in params if value > 0]
import json import datetime from iconsdk.icon_service import IconService from iconsdk.providers.http_provider import HTTPProvider icon_service = IconService(HTTPProvider("http://104.196.209.29:9000/api/v3")) #Define latest block, latest block height, and latest block timestamp. latest_block = json.loads(json.dumps(icon_service.get_block("latest"))) latest_block_height = latest_block['height'] latest_block_timestamp_epoch = latest_block['time_stamp'] latest_block_timestamp_utc = datetime.datetime.utcfromtimestamp( latest_block_timestamp_epoch / 1000000.0).strftime('%Y-%m-%d %H:%M:%S.%f') #Print latest block heigh and latest block timestamp. print("Latest Block Height: " + str(latest_block_height)) print("Latest Block Timestamp: " + str(latest_block_timestamp_utc) + " UTC") #Calculate block time of most recent block. #block_time = (latest_block_timestamp - prev_block_timestamp)/1000000 #print("Block Time:",block_time,"seconds") #Calculate average block time from last 10 blocks. icx_block_time_list = [] for x in range(10): icx_block = json.loads( json.dumps(icon_service.get_block(latest_block_height - x))) icx_block_prev = json.loads( json.dumps(icon_service.get_block(latest_block_height - x - 1))) icx_block_timestamp = icx_block['time_stamp'] icx_block_prev_timestamp = icx_block_prev['time_stamp']