async def icx_sendTransaction(**kwargs): url = kwargs['context']['url'] path = urlparse(url).path del kwargs['context'] request = make_request("icx_sendTransaction", kwargs, RequestParamType.send_tx) channel = StubCollection().conf[ConfigKey.CHANNEL] icon_stub = StubCollection().icon_score_stubs[channel] response = await icon_stub.async_task().validate_transaction(request) # Error Check response_to_json_query(response) channel_name = StubCollection().conf[ConfigKey.CHANNEL] channel_tx_creator_stub = StubCollection( ).channel_tx_creator_stubs[channel_name] response_code, tx_hash, relay_target = \ await channel_tx_creator_stub.async_task().create_icx_tx(kwargs) if response_code == message_code.Response.fail_no_permission: return await Version2Dispatcher.__relay_icx_transaction( url, path, kwargs, channel, relay_target) response_data = {'response_code': response_code} if response_code != message_code.Response.success: response_data['message'] = message_code.responseCodeMap[ response_code][1] else: response_data['tx_hash'] = tx_hash return response_data
async def icx_getTransactionByAddress(**kwargs): channel_name = StubCollection().conf[ConfigKey.CHANNEL] address = kwargs.get("address", None) index = kwargs.get("index", None) if address is None or index is None: return { 'response_code': message_code.Response.fail_illegal_params, 'message': message_code.get_response_msg( message_code.Response.fail_illegal_params) } channel_stub = StubCollection().channel_stubs[channel_name] tx_list, next_index = await channel_stub.async_task( ).get_tx_by_address(address=address, index=index) response = { 'next_index': next_index, 'response': tx_list[:-1], 'response_code': message_code.Response.success } return response
async def icx_getBalance(**kwargs): channel_name = StubCollection().conf[ConfigKey.CHANNEL] method = 'icx_getBalance' request = make_request(method, kwargs, RequestParamType.get_balance) stub = StubCollection().icon_score_stubs[channel_name] response = await stub.async_task().query(request) return response_to_json_query(response, True)
async def icx_getTotalSupply(context: Dict[str, str], **kwargs): channel_name = StubCollection().conf[ConfigKey.CHANNEL] method = 'icx_getTotalSupply' request = make_request(method, kwargs, RequestParamType.get_total_supply) stub = StubCollection().icon_score_stubs[channel_name] response = await stub.async_task().query(request) return response_to_json_query(response, True)
async def test_no_publish_if_exc_during_register(self, request_dict): channel_stub = StubCollection().channel_stubs[CHANNEL_STUB_NAME] channel_stub.register_citizen = AsyncMock(return_value=False) WSDispatcher.publish_heartbeat = AsyncMock() WSDispatcher.publish_new_block = AsyncMock() WSDispatcher.publish_unregister = AsyncMock() await WSDispatcher.node_ws_Subscribe(**request_dict) assert not WSDispatcher.publish_heartbeat.called assert not WSDispatcher.publish_new_block.called assert WSDispatcher.publish_unregister.called
async def icx_sendTransaction(**kwargs): channel = kwargs['context']['channel'] url = kwargs['context']['url'] path = urlparse(url).path del kwargs['context'] if RestProperty().node_type == NodeType.CitizenNode: dispatch_protocol = IcxDispatcher.get_dispatch_protocol_from_url( url) Logger.debug(f'Dispatch Protocol: {dispatch_protocol}') redirect_protocol = StubCollection().conf.get( ConfigKey.REDIRECT_PROTOCOL) Logger.debug(f'Redirect Protocol: {redirect_protocol}') if redirect_protocol: dispatch_protocol = redirect_protocol Logger.debug(f'Protocol: {dispatch_protocol}') return await redirect_request_to_rs(dispatch_protocol, kwargs, RestProperty().rs_target, path=path[1:]) method = 'icx_sendTransaction' request = make_request(method, kwargs) score_stub = get_icon_stub_by_channel_name(channel) icon_stub = score_stub response = await icon_stub.async_task().validate_transaction(request) # Error Check response_to_json_query(response) channel_tx_creator_stub = StubCollection( ).channel_tx_creator_stubs[channel] response_code, tx_hash = await channel_tx_creator_stub.async_task( ).create_icx_tx(kwargs) if response_code != message_code.Response.success: raise GenericJsonRpcServerError( code=JsonError.INVALID_REQUEST, message=message_code.responseCodeMap[response_code][1], http_status=status.HTTP_BAD_REQUEST) if tx_hash is None: raise GenericJsonRpcServerError( code=JsonError.INVALID_REQUEST, message='txHash is None', http_status=status.HTTP_BAD_REQUEST) return convert_params(tx_hash, ParamType.send_tx_response)
async def dispatch(request: 'SanicRequest', channel_name: str = ""): req_json = request.json url = request.url channel = channel_name if channel_name else StubCollection().conf[ConfigKey.CHANNEL] context = { "url": url, "channel": channel, } response: Union[Response, DictResponse, BatchResponse] try: client_ip = request.remote_addr if request.remote_addr else request.ip Logger.info(f'rest_server_v3d request with {req_json}', DISPATCH_V3D_TAG) Logger.info(f"{client_ip} requested {req_json} on {url}") validate_jsonschema_v3(request=req_json) except GenericJsonRpcServerError as e: response = ApiErrorResponse(id=req_json.get('id', 0), code=e.code, message=str(e), http_status=e.http_status, debug=False) except Exception as e: response = ExceptionResponse(e, id=req_json.get('id', 0), debug=False) else: response = await async_dispatch(request.body, methods, context=context) Logger.info(f'rest_server_v3d with response {response}', DISPATCH_V3D_TAG) return sanic_response.json(response.deserialized(), status=response.http_status, dumps=json.dumps)
async def dispatch(request, channel_name=None): req_json = request.json url = request.url channel = channel_name if channel_name else StubCollection().conf[ ConfigKey.CHANNEL] req_json['method'] = convert_upper_camel_method_to_lower_camel( req_json['method']) if 'params' in req_json and 'message' in req_json[ 'params']: # this will be removed after update. req_json['params'] = req_json['params']['message'] context = {'url': url, 'channel': channel} try: client_ip = request.remote_addr if request.remote_addr else request.ip Logger.info(f'rest_server_node request with {req_json}', DISPATCH_NODE_TAG) Logger.info(f'{client_ip} requested {req_json} on {url}') validate_jsonschema_node(request=req_json) except GenericJsonRpcServerError as e: response = ExceptionResponse(e, request_id=req_json.get('id', 0)) except Exception as e: response = ExceptionResponse(e, request_id=req_json.get('id', 0)) else: response = await methods.dispatch(req_json, context=context) Logger.info(f'rest_server_node with response {response}', DISPATCH_NODE_TAG) return sanic_response.json(response, status=response.http_status, dumps=json.dumps)
async def icx_getTransactionResult(**kwargs): channel = kwargs['context']['channel'] request = convert_params(kwargs, RequestParamType.get_tx_result) channel_stub = StubCollection().channel_stubs[channel] verify_result = dict() tx_hash = request["txHash"] response_code, result = await channel_stub.async_task( ).get_invoke_result(tx_hash) if response_code == message_code.Response.fail_tx_not_invoked: raise GenericJsonRpcServerError( code=JsonError.INVALID_PARAMS, message=message_code.responseCodeMap[response_code][1], http_status=status.HTTP_BAD_REQUEST) elif response_code == message_code.Response.fail_invalid_key_error or \ response_code == message_code.Response.fail: raise GenericJsonRpcServerError( code=JsonError.INVALID_PARAMS, message='Invalid params txHash', http_status=status.HTTP_BAD_REQUEST) if result: try: result_dict = json.loads(result) verify_result = result_dict except json.JSONDecodeError as e: Logger.warning( f"your result is not json, result({result}), {e}") response = convert_params(verify_result, ResponseParamType.get_tx_result) return response
async def icx_sendTransaction(**kwargs): channel = kwargs['context']['channel'] url = kwargs['context']['url'] path = urlparse(url).path del kwargs['context'] method = 'icx_sendTransaction' request = make_request(method, kwargs) score_stub = get_icon_stub_by_channel_name(channel) icon_stub = score_stub response = await icon_stub.async_task().validate_transaction(request) # Error Check response_to_json_query(response) channel_tx_creator_stub = StubCollection().channel_tx_creator_stubs[channel] response_code, tx_hash = await channel_tx_creator_stub.async_task().create_icx_tx(kwargs) if response_code == message_code.Response.fail_no_permission: return await IcxDispatcher.__relay_icx_transaction(url, path, kwargs) if response_code != message_code.Response.success: raise GenericJsonRpcServerError( code=JsonError.INVALID_REQUEST, message=message_code.responseCodeMap[response_code][1], http_status=message_code.get_response_http_status_code(response_code, status.HTTP_BAD_REQUEST) ) if tx_hash is None: raise GenericJsonRpcServerError( code=JsonError.INVALID_REQUEST, message='txHash is None', http_status=status.HTTP_BAD_REQUEST ) return convert_params(tx_hash, ParamType.send_tx_response)
async def _publish_heartbeat(): channel_stub = get_channel_stub_by_channel_name(channel_name) exception = None while ws.open: try: is_registered = await channel_stub.async_task( ).is_registered_subscriber(peer_id=peer_id) if is_registered: request = Request("node_ws_PublishHeartbeat") await ws.send(json.dumps(request)) heartbeat_time = StubCollection().conf[ ConfigKey.WS_HEARTBEAT_TIME] await asyncio.sleep(heartbeat_time) continue raise RuntimeError("Unregistered") except Exception as e: exception = e traceback.print_exc() break if not exception: exception = ConnectionError("Connection closed.") request = Request("node_ws_PublishHeartbeat", error=str(exception)) await ws.send(json.dumps(request)) raise exception
async def dispatch(request, channel_name=None): req_json = request.json url = request.url channel = channel_name if channel_name is not None \ else StubCollection().conf[ConfigKey.CHANNEL] context = { "url": url, "channel": channel, } try: client_ip = request.remote_addr if request.remote_addr else request.ip Logger.info(f'rest_server_v3d request with {req_json}', DISPATCH_V3D_TAG) Logger.info(f"{client_ip} requested {req_json} on {url}") validate_jsonschema_v3(request=req_json) except GenericJsonRpcServerError as e: response = ExceptionResponse(e, request_id=req_json.get('id', 0)) except Exception as e: response = ExceptionResponse(e, request_id=req_json.get('id', 0)) else: response = await methods.dispatch(req_json, context=context) Logger.info(f'rest_server_v3d with response {response}', DISPATCH_V3D_TAG) return sanic_response.json(response, status=response.http_status, dumps=json.dumps)
async def icx_getTransactionResult(**kwargs): channel_name = StubCollection().conf[ConfigKey.CHANNEL] channel_stub = StubCollection().channel_stubs[channel_name] verify_result = {} message = None tx_hash = kwargs["tx_hash"] if is_hex(tx_hash): response_code, result = await channel_stub.async_task( ).get_invoke_result(tx_hash) if response_code == message_code.Response.success: # loopchain success if result: try: # apply tx_result_convert result_dict = json.loads(result) fail_status = bool(result_dict.get('failure')) if fail_status: error_code = message_code.Response.fail_validate_params message = "Invalid transaction hash." else: error_code = message_code.Response.success except Exception as e: error_message = f"your result is not json, result({result}), {e}" Logger.warning(error_message) error_code = message_code.Response.fail_validate_params message = error_message else: error_code = message_code.Response.fail_validate_params message = 'tx_result is empty' else: error_code = message_code.Response.fail_validate_params message = "Invalid transaction hash." else: # fail error_code = message_code.Response.fail_validate_params message = "response_code is fail" # parsing response verify_result['response_code'] = str(error_code) if error_code == message_code.Response.success: verify_result['response'] = {'code': error_code} if message: verify_result['message'] = message return verify_result
def mocking_stub_collection(): """Setup StubCollection and Teardown it after each test ends.""" StubCollection().conf = {"channel": CHANNEL_NAME} StubCollection().icon_score_stubs[CHANNEL_NAME] = create_icon_score_stub() yield StubCollection().amqp_target = None StubCollection().amqp_key = None StubCollection().conf = None StubCollection().peer_stub = None StubCollection().channel_stubs = {} StubCollection().channel_tx_creator_stubs = {} StubCollection().icon_score_stubs = {}
async def icx_sendTransaction(context: Dict[str, str], **kwargs): channel = context.get('channel') url = context.get('url') path = urlparse(url).path method = 'icx_sendTransaction' request = make_request(method, kwargs) score_stub = get_icon_stub_by_channel_name(channel) icon_stub = score_stub response = await icon_stub.async_task().validate_transaction(request) # Error Check response_to_json_query(response) # DosGuard if StubCollection().conf.get(ConfigKey.DOS_GUARD_ENABLE, False): response = await icon_stub.async_task().dos_guard(kwargs) # Error Check response_to_json_query(response) channel_tx_creator_stub = StubCollection( ).channel_tx_creator_stubs[channel] response_code, tx_hash, relay_target = \ await channel_tx_creator_stub.async_task().create_icx_tx(kwargs) if response_code == message_code.Response.fail_no_permission: return await IcxDispatcher.__relay_icx_transaction( path, kwargs, relay_target) if response_code != message_code.Response.success: raise GenericJsonRpcServerError( code=JsonError.INVALID_REQUEST, message=message_code.responseCodeMap[response_code][1], http_status=message_code.get_response_http_status_code( response_code, status.HTTP_BAD_REQUEST)) if tx_hash is None: raise GenericJsonRpcServerError( code=JsonError.INVALID_REQUEST, message='txHash is None', http_status=status.HTTP_BAD_REQUEST) return convert_params(tx_hash, ResponseParamType.send_tx)
async def icx_sendTransaction(**kwargs): url = kwargs['context']['url'] path = urlparse(url).path del kwargs['context'] if RestProperty().node_type == NodeType.CitizenNode: dispatch_protocol = Version2Dispatcher.get_dispatch_protocol_from_url( url) Logger.debug(f'Dispatch Protocol: {dispatch_protocol}') redirect_protocol = StubCollection().conf.get( ConfigKey.REDIRECT_PROTOCOL) Logger.debug(f'Redirect Protocol: {redirect_protocol}') if redirect_protocol: dispatch_protocol = redirect_protocol Logger.debug(f'Protocol: {dispatch_protocol}') return await redirect_request_to_rs(dispatch_protocol, kwargs, RestProperty().rs_target, path[1:], ApiVersion.v2.name) request = make_request("icx_sendTransaction", kwargs, ParamType.send_tx) channel = StubCollection().conf[ConfigKey.CHANNEL] icon_stub = StubCollection().icon_score_stubs[channel] response = await icon_stub.async_task().validate_transaction(request) # Error Check response_to_json_query(response) channel_name = StubCollection().conf[ConfigKey.CHANNEL] channel_tx_creator_stub = StubCollection( ).channel_tx_creator_stubs[channel_name] response_code, tx_hash = await channel_tx_creator_stub.async_task( ).create_icx_tx(kwargs) response_data = {'response_code': response_code} if response_code != message_code.Response.success: response_data['message'] = message_code.responseCodeMap[ response_code][1] else: response_data['tx_hash'] = tx_hash return response_data
async def dispatch(request: 'SanicRequest', channel_name: str = ""): """Node dispatch FIXME : this dispatch is not considered to support batch request. If you want to support batch request, need to update code that using req_json. """ req_json = request.json url = request.url channel = channel_name if channel_name else StubCollection().conf[ ConfigKey.CHANNEL] req_json['method'] = convert_upper_camel_method_to_lower_camel( req_json['method']) if 'params' in req_json and 'message' in req_json[ 'params']: # this will be removed after update. req_json['params'] = req_json['params']['message'] context = {'url': url, 'channel': channel} response: Union[Response, DictResponse, BatchResponse] try: client_ip = request.remote_addr if request.remote_addr else request.ip Logger.info(f'rest_server_node request with {req_json}', DISPATCH_NODE_TAG) Logger.info(f'{client_ip} requested {req_json} on {url}') validate_jsonschema_node(request=req_json) except GenericJsonRpcServerError as e: response = ExceptionResponse(e, id=req_json.get('id', 0), debug=False) except Exception as e: response = ExceptionResponse(e, id=req_json.get('id', 0), debug=False) else: response = await async_dispatch(request.body, methods, context=context) Logger.info(f'rest_server_node with response {response}', DISPATCH_NODE_TAG) return sanic_response.json(response.deserialized(), status=response.http_status, dumps=json.dumps)
async def __relay_icx_transaction(url, path, message): relay_target = RestProperty().relay_target relay_target = relay_target if relay_target is not None else RestProperty().rs_target if not relay_target: raise GenericJsonRpcServerError( code=JsonError.INTERNAL_ERROR, message=message_code.responseCodeMap[message_code.Response.fail_invalid_peer_target][1], http_status=status.HTTP_INTERNAL_ERROR ) dispatch_protocol = IcxDispatcher.get_dispatch_protocol_from_url(url) Logger.debug(f'Dispatch Protocol: {dispatch_protocol}') redirect_protocol = StubCollection().conf.get(ConfigKey.REDIRECT_PROTOCOL) Logger.debug(f'Redirect Protocol: {redirect_protocol}') if redirect_protocol: dispatch_protocol = redirect_protocol Logger.debug(f'Protocol: {dispatch_protocol}') return await relay_tx_request(dispatch_protocol, message, relay_target, path=path[1:])
async def publish_heartbeat(ws): exception = None while ws.open: try: request = Request("node_ws_PublishHeartbeat") Logger.debug(f"node_ws_PublishHeartbeat: {request}") await ws.send(json.dumps(request)) heartbeat_time = StubCollection().conf[ ConfigKey.WS_HEARTBEAT_TIME] await asyncio.sleep(heartbeat_time) except Exception as e: exception = e traceback.print_exc() break if not exception: exception = ConnectionError("Connection closed.") error_code = message_code.Response.fail_connection_closed await WSDispatcher.send_and_raise_exception( ws, "node_ws_PublishHeartbeat", exception, error_code)
async def icx_getTransactionByHash(**kwargs): channel = kwargs['context']['channel'] request = convert_params(kwargs, RequestParamType.get_tx_result) channel_stub = StubCollection().channel_stubs[channel] response_code, tx_info = await channel_stub.async_task().get_tx_info( request["txHash"]) if response_code == message_code.Response.fail_invalid_key_error: raise GenericJsonRpcServerError( code=JsonError.INVALID_PARAMS, message='Invalid params txHash', http_status=status.HTTP_BAD_REQUEST) result = tx_info["transaction"] result['txHash'] = request['txHash'] result["txIndex"] = tx_info["tx_index"] result["blockHeight"] = tx_info["block_height"] result["blockHash"] = tx_info["block_hash"] response = convert_params(result, ResponseParamType.get_tx_by_hash) return response
async def __relay_icx_transaction(url, path, message, channel_name, relay_target): if not relay_target: response_code = message_code.Response.fail_invalid_peer_target return { 'response_code': response_code, 'message': message_code.responseCodeMap[response_code][1], 'tx_hash': None } dispatch_protocol = get_protocol_from_uri(url) Logger.debug(f'Dispatch Protocol: {dispatch_protocol}') redirect_protocol = StubCollection().conf.get( ConfigKey.REDIRECT_PROTOCOL) Logger.debug(f'Redirect Protocol: {redirect_protocol}') if redirect_protocol: dispatch_protocol = redirect_protocol Logger.debug(f'Protocol: {dispatch_protocol}') return await relay_tx_request(dispatch_protocol, message, relay_target, path[1:], ApiVersion.v2.name)
def patch_stubcollection(): mock_channel_stub: ChannelInnerStub = MockChannelInnerStub() StubCollection().channel_stubs[CHANNEL_STUB_NAME] = mock_channel_stub
def _(response_code): channel_stub = create_channel_stub(response_code=response_code) StubCollection().channel_stubs[CHANNEL_NAME] = channel_stub
def _(response_code, tx_hash=TX_RESULT_HASH): channel_tx_creator_stub = create_channel_tx_creator_stub( response_code=response_code, tx_hash=tx_hash) StubCollection( ).channel_tx_creator_stubs[CHANNEL_NAME] = channel_tx_creator_stub
async def icx_getLastTransaction(**kwargs): channel_name = StubCollection().conf[ConfigKey.CHANNEL] return ""