diff --git a/doc/schemas/app_openapi.json b/doc/schemas/app_openapi.json index b26989625..3b362cdc4 100644 --- a/doc/schemas/app_openapi.json +++ b/doc/schemas/app_openapi.json @@ -268,7 +268,7 @@ "info": { "description": "This CCF sample app implements a simple logging application, securely recording messages at client-specified IDs. It demonstrates most of the features available to CCF apps.", "title": "CCF Sample Logging App", - "version": "1.10.1" + "version": "1.10.2" }, "openapi": "3.0.0", "paths": { @@ -1105,7 +1105,7 @@ } }, "x-ccf-forwarding": { - "$ref": "#/components/x-ccf-forwarding/always" + "$ref": "#/components/x-ccf-forwarding/sometimes" } } }, diff --git a/doc/schemas/gov_openapi.json b/doc/schemas/gov_openapi.json index 2310dfdf8..75aeebae3 100644 --- a/doc/schemas/gov_openapi.json +++ b/doc/schemas/gov_openapi.json @@ -430,7 +430,7 @@ "info": { "description": "This API is used to submit and query proposals which affect CCF's public governance tables.", "title": "CCF Governance API", - "version": "2.8.0" + "version": "2.8.1" }, "openapi": "3.0.0", "paths": { @@ -875,7 +875,7 @@ } }, "x-ccf-forwarding": { - "$ref": "#/components/x-ccf-forwarding/always" + "$ref": "#/components/x-ccf-forwarding/sometimes" } } }, diff --git a/doc/schemas/node_openapi.json b/doc/schemas/node_openapi.json index 877f0bd30..526872c24 100644 --- a/doc/schemas/node_openapi.json +++ b/doc/schemas/node_openapi.json @@ -845,7 +845,7 @@ "info": { "description": "This API provides public, uncredentialed access to service and node state.", "title": "CCF Public Node API", - "version": "2.30.0" + "version": "2.30.1" }, "openapi": "3.0.0", "paths": { @@ -1296,7 +1296,7 @@ } }, "x-ccf-forwarding": { - "$ref": "#/components/x-ccf-forwarding/always" + "$ref": "#/components/x-ccf-forwarding/sometimes" } } }, diff --git a/include/ccf/historical_queries_adapter.h b/include/ccf/historical_queries_adapter.h index 29fefd3d5..147814a33 100644 --- a/include/ccf/historical_queries_adapter.h +++ b/include/ccf/historical_queries_adapter.h @@ -19,13 +19,25 @@ namespace ccf::historical using CheckAvailability = std::function; - using HandleHistoricalQuery = + using HandleReadWriteHistoricalQuery = std::function; + using HandleReadOnlyHistoricalQuery = std::function; + + using HandleHistoricalQuery = HandleReadWriteHistoricalQuery; + + using CommandTxIDExtractor = std::function( + endpoints::CommandEndpointContext& args)>; + + using ReadOnlyTxIDExtractor = std::function( + endpoints::ReadOnlyEndpointContext& args)>; + using TxIDExtractor = std::function(endpoints::EndpointContext& args)>; - std::optional txid_from_header(endpoints::EndpointContext& args); + std::optional txid_from_header( + endpoints::CommandEndpointContext& args); bool is_tx_committed_v1( kv::Consensus* consensus, @@ -56,6 +68,18 @@ namespace ccf::historical const CheckHistoricalTxStatus& available, const TxIDExtractor& extractor = txid_from_header); + ccf::endpoints::ReadOnlyEndpointFunction read_only_adapter_v3( + const HandleReadOnlyHistoricalQuery& f, + ccfapp::AbstractNodeContext& node_context, + const CheckHistoricalTxStatus& available, + const ReadOnlyTxIDExtractor& extractor = txid_from_header); + + ccf::endpoints::EndpointFunction read_write_adapter_v3( + const HandleReadWriteHistoricalQuery& f, + ccfapp::AbstractNodeContext& node_context, + const CheckHistoricalTxStatus& available, + const TxIDExtractor& extractor = txid_from_header); + /// @cond // Doxygen cannot parse these declarations; some combination of a macro, // attribute syntax, and namespaced types results in the following warning diff --git a/samples/apps/logging/logging.cpp b/samples/apps/logging/logging.cpp index fa0007c43..96b6aecde 100644 --- a/samples/apps/logging/logging.cpp +++ b/samples/apps/logging/logging.cpp @@ -247,7 +247,7 @@ namespace loggingapp "This CCF sample app implements a simple logging application, securely " "recording messages at client-specified IDs. It demonstrates most of " "the features available to CCF apps."; - openapi_info.document_version = "1.10.1"; + openapi_info.document_version = "1.10.2"; index_per_public_key = std::make_shared( PUBLIC_RECORDS, context, 10000, 20); @@ -830,7 +830,7 @@ namespace loggingapp // SNIPPET_START: get_historical auto get_historical = [this]( - ccf::endpoints::EndpointContext& ctx, + ccf::endpoints::ReadOnlyEndpointContext& ctx, ccf::historical::StatePtr historical_state) { const auto pack = ccf::jsonhandler::detect_json_pack(ctx.rpc_ctx); @@ -872,10 +872,11 @@ namespace loggingapp return ccf::historical::is_tx_committed_v2( consensus, view, seqno, error_reason); }; - make_endpoint( + make_read_only_endpoint( "/log/private/historical", HTTP_GET, - ccf::historical::adapter_v3(get_historical, context, is_tx_committed), + ccf::historical::read_only_adapter_v3( + get_historical, context, is_tx_committed), auth_policies) .set_auto_schema() .add_query_parameter("id") @@ -886,7 +887,7 @@ namespace loggingapp // SNIPPET_START: get_historical_with_receipt auto get_historical_with_receipt = [this]( - ccf::endpoints::EndpointContext& ctx, + ccf::endpoints::ReadOnlyEndpointContext& ctx, ccf::historical::StatePtr historical_state) { const auto pack = ccf::jsonhandler::detect_json_pack(ctx.rpc_ctx); @@ -923,10 +924,10 @@ namespace loggingapp ctx.rpc_ctx->set_response_status(HTTP_STATUS_NO_CONTENT); } }; - make_endpoint( + make_read_only_endpoint( "/log/private/historical_receipt", HTTP_GET, - ccf::historical::adapter_v3( + ccf::historical::read_only_adapter_v3( get_historical_with_receipt, context, is_tx_committed), auth_policies) .set_auto_schema() @@ -937,7 +938,7 @@ namespace loggingapp auto get_historical_with_receipt_and_claims = [this]( - ccf::endpoints::EndpointContext& ctx, + ccf::endpoints::ReadOnlyEndpointContext& ctx, ccf::historical::StatePtr historical_state) { const auto pack = ccf::jsonhandler::detect_json_pack(ctx.rpc_ctx); @@ -981,10 +982,10 @@ namespace loggingapp ctx.rpc_ctx->set_response_status(HTTP_STATUS_NO_CONTENT); } }; - make_endpoint( + make_read_only_endpoint( "/log/public/historical_receipt", HTTP_GET, - ccf::historical::adapter_v3( + ccf::historical::read_only_adapter_v3( get_historical_with_receipt_and_claims, context, is_tx_committed), auth_policies) .set_auto_schema() diff --git a/src/endpoints/common_endpoint_registry.cpp b/src/endpoints/common_endpoint_registry.cpp index fa260ce32..b222a0e0f 100644 --- a/src/endpoints/common_endpoint_registry.cpp +++ b/src/endpoints/common_endpoint_registry.cpp @@ -21,7 +21,7 @@ namespace ccf namespace { std::optional txid_from_query_string( - ccf::endpoints::EndpointContext& ctx) + ccf::endpoints::CommandEndpointContext& ctx) { const auto parsed_query = http::parse_query(ctx.rpc_ctx->get_request_query()); @@ -235,10 +235,10 @@ namespace ccf ccf::jsonhandler::set_response(out, ctx.rpc_ctx, pack); }; - make_endpoint( + make_read_only_endpoint( "/receipt", HTTP_GET, - ccf::historical::adapter_v3( + ccf::historical::read_only_adapter_v3( get_receipt, context, is_tx_committed, txid_from_query_string), no_auth_required) .set_auto_schema() diff --git a/src/node/historical_queries_adapter.cpp b/src/node/historical_queries_adapter.cpp index ca70983a8..4b8d36782 100644 --- a/src/node/historical_queries_adapter.cpp +++ b/src/node/historical_queries_adapter.cpp @@ -159,7 +159,8 @@ namespace ccf namespace ccf::historical { - std::optional txid_from_header(endpoints::EndpointContext& args) + std::optional txid_from_header( + endpoints::CommandEndpointContext& args) { const auto tx_id_header = args.rpc_ctx->get_request_header(http::headers::CCF_TX_ID); @@ -397,18 +398,23 @@ namespace ccf::historical return true; } - ccf::endpoints::EndpointFunction adapter_v3( - const HandleHistoricalQuery& f, + template < + class TQueryHandler, + class TEndpointFunction, + class TEndpointContext, + class TTxIDExtractor> + TEndpointFunction _adapter_v3( + const TQueryHandler& f, ccfapp::AbstractNodeContext& node_context, const CheckHistoricalTxStatus& available, - const TxIDExtractor& extractor) + const TTxIDExtractor& extractor) { auto& state_cache = node_context.get_historical_state(); auto network_identity_subsystem = node_context.get_subsystem(); return [f, &state_cache, network_identity_subsystem, available, extractor]( - endpoints::EndpointContext& args) { + TEndpointContext& args) { // Extract the requested transaction ID ccf::TxID target_tx_id; { @@ -495,6 +501,43 @@ namespace ccf::historical }; } + ccf::endpoints::EndpointFunction adapter_v3( + const HandleHistoricalQuery& f, + ccfapp::AbstractNodeContext& node_context, + const CheckHistoricalTxStatus& available, + const TxIDExtractor& extractor) + { + return _adapter_v3< + HandleHistoricalQuery, + ccf::endpoints::EndpointFunction, + ccf::endpoints::EndpointContext>(f, node_context, available, extractor); + } + + ccf::endpoints::ReadOnlyEndpointFunction read_only_adapter_v3( + const HandleReadOnlyHistoricalQuery& f, + ccfapp::AbstractNodeContext& node_context, + const CheckHistoricalTxStatus& available, + const ReadOnlyTxIDExtractor& extractor) + { + return _adapter_v3< + HandleReadOnlyHistoricalQuery, + ccf::endpoints::ReadOnlyEndpointFunction, + ccf::endpoints::ReadOnlyEndpointContext>( + f, node_context, available, extractor); + } + + ccf::endpoints::EndpointFunction read_write_adapter_v3( + const HandleReadWriteHistoricalQuery& f, + ccfapp::AbstractNodeContext& node_context, + const CheckHistoricalTxStatus& available, + const TxIDExtractor& extractor) + { + return _adapter_v3< + HandleReadWriteHistoricalQuery, + ccf::endpoints::EndpointFunction, + ccf::endpoints::EndpointContext>(f, node_context, available, extractor); + } + ccf::endpoints::EndpointFunction adapter_v2( const HandleHistoricalQuery& f, AbstractStateCache& state_cache, diff --git a/src/node/rpc/member_frontend.h b/src/node/rpc/member_frontend.h index ff452006a..0382cf5b1 100644 --- a/src/node/rpc/member_frontend.h +++ b/src/node/rpc/member_frontend.h @@ -489,7 +489,7 @@ namespace ccf openapi_info.description = "This API is used to submit and query proposals which affect CCF's " "public governance tables."; - openapi_info.document_version = "2.8.0"; + openapi_info.document_version = "2.8.1"; } static std::optional get_caller_member_id( diff --git a/src/node/rpc/node_frontend.h b/src/node/rpc/node_frontend.h index cfeb8da39..f8e38e13a 100644 --- a/src/node/rpc/node_frontend.h +++ b/src/node/rpc/node_frontend.h @@ -367,7 +367,7 @@ namespace ccf openapi_info.description = "This API provides public, uncredentialed access to service and node " "state."; - openapi_info.document_version = "2.30.0"; + openapi_info.document_version = "2.30.1"; } void init_handlers() override