Skip to main content

sui_rpc_api/grpc/v2/move_package_service/
get_function.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{
5    ErrorReason, Result, RpcService,
6    grpc::v2::move_package_service::{
7        conversions::{convert_error, convert_function},
8        load_package,
9    },
10};
11use sui_rpc::proto::google::rpc::bad_request::FieldViolation;
12use sui_rpc::proto::sui::rpc::v2::{GetFunctionRequest, GetFunctionResponse};
13use sui_types::move_package::MovePackage;
14
15#[tracing::instrument(skip(service))]
16pub fn get_function(
17    service: &RpcService,
18    request: GetFunctionRequest,
19) -> Result<GetFunctionResponse> {
20    let package_id_str = request.package_id.as_ref().ok_or_else(|| {
21        FieldViolation::new("package_id")
22            .with_description("missing package_id")
23            .with_reason(ErrorReason::FieldMissing)
24    })?;
25
26    let module_name = request.module_name.as_ref().ok_or_else(|| {
27        FieldViolation::new("module_name")
28            .with_description("missing module_name")
29            .with_reason(ErrorReason::FieldMissing)
30    })?;
31
32    let function_name = request.name.as_ref().ok_or_else(|| {
33        FieldViolation::new("name")
34            .with_description("missing name")
35            .with_reason(ErrorReason::FieldMissing)
36    })?;
37
38    let package = load_package(service, package_id_str)?;
39    get_function_response(&package, module_name, function_name)
40}
41
42/// Build a `GetFunction` response from an already-loaded package. Shared with other implementors
43/// of `MovePackageService` (e.g. sui-kv-rpc) that load packages from a different backend.
44pub fn get_function_response(
45    package: &MovePackage,
46    module_name: &str,
47    function_name: &str,
48) -> Result<GetFunctionResponse> {
49    let resolver_package =
50        sui_package_resolver::Package::read_from_package(package).map_err(convert_error)?;
51
52    let resolver_module = resolver_package
53        .module(module_name)
54        .map_err(convert_error)?;
55
56    let func_def = resolver_module
57        .function_def(function_name)
58        .map_err(convert_error)?
59        .ok_or_else(|| {
60            crate::RpcError::new(
61                tonic::Code::Internal,
62                format!("Function not found: {}", function_name),
63            )
64        })?;
65
66    let descriptor = convert_function(function_name, &func_def);
67
68    Ok(GetFunctionResponse::new(descriptor))
69}