From ced5dd97fd76eb1c48eca65ea3e1fcd6dbfa3280 Mon Sep 17 00:00:00 2001 From: Pedro Ferreira Date: Tue, 20 Aug 2024 19:18:00 -0300 Subject: [PATCH] feat: add new hathor core api to get blueprint source code (#333) --- gateways/clients/hathor_core_client.py | 1 + gateways/node_api_gateway.py | 9 ++++++ handlers/node_api.py | 30 ++++++++++++++++++++ serverless.yml | 20 +++++++++++++ tests/unit/gateways/test_node_api_gateway.py | 17 +++++++++++ tests/unit/usecases/test_node_api.py | 9 ++++++ usecases/node_api.py | 3 ++ 7 files changed, 89 insertions(+) diff --git a/gateways/clients/hathor_core_client.py b/gateways/clients/hathor_core_client.py index 762ca56..256f681 100644 --- a/gateways/clients/hathor_core_client.py +++ b/gateways/clients/hathor_core_client.py @@ -20,6 +20,7 @@ NC_STATE_ENDPOINT = "/v1a/nano_contract/state" NC_HISTORY_ENDPOINT = "/v1a/nano_contract/history" NC_BLUEPRINT_INFORMATION_ENDPOINT = "/v1a/nano_contract/blueprint" +NC_BLUEPRINT_SOURCE_CODE_ENDPOINT = "/v1a/nano_contract/blueprint_source_code" STATUS_ENDPOINT = "/v1a/status" TOKEN_ENDPOINT = "/v1a/thin_wallet/token" TOKEN_HISTORY_ENDPOINT = "/v1a/thin_wallet/token_history" diff --git a/gateways/node_api_gateway.py b/gateways/node_api_gateway.py index 1d70b45..4b9ece5 100644 --- a/gateways/node_api_gateway.py +++ b/gateways/node_api_gateway.py @@ -9,6 +9,7 @@ FEATURE_ENDPOINT, GRAPHVIZ_DOT_NEIGHBORS_ENDPOINT, NC_BLUEPRINT_INFORMATION_ENDPOINT, + NC_BLUEPRINT_SOURCE_CODE_ENDPOINT, NC_HISTORY_ENDPOINT, NC_STATE_ENDPOINT, PUSH_TX_ENDPOINT, @@ -254,3 +255,11 @@ def get_nc_blueprint_information(self, blueprint_id: str) -> Optional[dict]: params={"blueprint_id": blueprint_id}, timeout=NODE_API_TIMEOUT_IN_SECONDS, ) + + def get_nc_blueprint_source_code(self, blueprint_id: str) -> Optional[dict]: + """Get blueprint source code.""" + return self.hathor_core_client.get( + NC_BLUEPRINT_SOURCE_CODE_ENDPOINT, + params={"blueprint_id": blueprint_id}, + timeout=NODE_API_TIMEOUT_IN_SECONDS, + ) diff --git a/handlers/node_api.py b/handlers/node_api.py index df9f38b..26de3b7 100644 --- a/handlers/node_api.py +++ b/handlers/node_api.py @@ -392,3 +392,33 @@ def nc_blueprint_information( "body": json.dumps(response or {}), "headers": {"Content-Type": "application/json"}, } + + +@ApiGateway() +def nc_blueprint_source_code( + event: ApiGatewayEvent, _context: LambdaContext, node_api: Optional[NodeApi] = None +) -> dict: + """Get blueprint source code.""" + node_api = node_api or NodeApi() + blueprint_id = event.query.get("blueprint_id") + + if blueprint_id is None: + raise ApiError("invalid_parameters") + + # This might throw HathorCoreTimeout error + response = node_api.get_nc_blueprint_source_code(blueprint_id) + + if response is None or "error" in response: + default_message = "Unknown error when retrieving blueprint source code" + message = ( + response.get("error") + if (response and "error" in response) + else default_message + ) + raise ApiError(message) + + return { + "statusCode": 200, + "body": json.dumps(response or {}), + "headers": {"Content-Type": "application/json"}, + } diff --git a/serverless.yml b/serverless.yml index 311157e..1350fd1 100644 --- a/serverless.yml +++ b/serverless.yml @@ -714,6 +714,26 @@ functions: - name: request.querystring.blueprint_id - name: request.header.origin + node_api_nc_blueprint_code: + handler: handlers/node_api.nc_blueprint_source_code + maximumRetryAttempts: 0 + package: + patterns: + - 'handlers/node_api.py' + layers: + - { Ref: PythonRequirementsLambdaLayer } + events: + - http: + path: node_api/nc_blueprint_source_code + method: get + cors: true + caching: + enabled: true + ttlInSeconds: 300 + cacheKeyParameters: + - name: request.querystring.blueprint_id + - name: request.header.origin + walletServiceAddressBalance: handler: handlers/wallet_service.handle_address_balance timeout: 15 diff --git a/tests/unit/gateways/test_node_api_gateway.py b/tests/unit/gateways/test_node_api_gateway.py index eb2a7af..2cb072d 100644 --- a/tests/unit/gateways/test_node_api_gateway.py +++ b/tests/unit/gateways/test_node_api_gateway.py @@ -371,3 +371,20 @@ def test_nc_blueprint_information(self, hathor_client): ) assert result assert sorted(result) == sorted(obj) + + @patch( + "gateways.node_api_gateway.NC_BLUEPRINT_SOURCE_CODE_ENDPOINT", "mock-endpoint" + ) + def test_nc_blueprint_source_code(self, hathor_client): + obj = {"foo": "bar"} + data = { + "blueprint_id": "1234", + } + hathor_client.get = MagicMock(return_value=obj) + gateway = NodeApiGateway(hathor_core_client=hathor_client) + result = gateway.get_nc_blueprint_source_code(**data) + hathor_client.get.assert_called_once_with( + "mock-endpoint", params=data, timeout=NODE_API_TIMEOUT_IN_SECONDS + ) + assert result + assert sorted(result) == sorted(obj) diff --git a/tests/unit/usecases/test_node_api.py b/tests/unit/usecases/test_node_api.py index 7e748c8..1f28328 100644 --- a/tests/unit/usecases/test_node_api.py +++ b/tests/unit/usecases/test_node_api.py @@ -373,3 +373,12 @@ def test_get_blueprint_information(self, node_api_gateway): node_api_gateway.get_nc_blueprint_information.assert_called_once_with("1234") assert result assert sorted(result) == sorted(obj) + + def test_get_blueprint_source_code(self, node_api_gateway): + obj = {"foo": "bar"} + node_api_gateway.get_nc_blueprint_source_code = MagicMock(return_value=obj) + node_api = NodeApi(node_api_gateway) + result = node_api.get_nc_blueprint_source_code("1234") + node_api_gateway.get_nc_blueprint_source_code.assert_called_once_with("1234") + assert result + assert sorted(result) == sorted(obj) diff --git a/usecases/node_api.py b/usecases/node_api.py index 332c8f6..e84ec4d 100644 --- a/usecases/node_api.py +++ b/usecases/node_api.py @@ -113,3 +113,6 @@ def get_nc_history( def get_nc_blueprint_information(self, blueprint_id: str) -> Optional[dict]: return self.node_api_gateway.get_nc_blueprint_information(blueprint_id) + + def get_nc_blueprint_source_code(self, blueprint_id: str) -> Optional[dict]: + return self.node_api_gateway.get_nc_blueprint_source_code(blueprint_id)