You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by hs...@apache.org on 2023/03/12 01:29:29 UTC
[incubator-teaclave] branch master updated: Improve function arguments by introducing FunctionArgument
This is an automated email from the ASF dual-hosted git repository.
hsun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave.git
The following commit(s) were added to refs/heads/master by this push:
new d02fb0ce Improve function arguments by introducing FunctionArgument
d02fb0ce is described below
commit d02fb0ce04de5970f9d26d54b5c6acfebb513cda
Author: sunhe05 <su...@baidu.com>
AuthorDate: Thu Mar 9 10:18:54 2023 +0000
Improve function arguments by introducing FunctionArgument
---
examples/c/builtin_echo.c | 2 +-
examples/c/builtin_ordered_set_intersect.c | 2 +-
examples/python/builtin_echo.py | 3 +-
examples/python/builtin_face_detection.py | 10 ++-
examples/python/builtin_gbdt_train.py | 14 +++-
examples/python/builtin_online_decrypt.py | 8 +-
examples/python/builtin_ordered_set_intersect.py | 4 +-
examples/python/builtin_password_check.py | 2 +-
.../python/builtin_private_join_and_compute.py | 4 +-
examples/python/builtin_rsa_sign.py | 4 +-
examples/python/mesapy_echo.py | 4 +-
examples/python/mesapy_logistic_reg.py | 4 +-
examples/python/test_disable_function.py | 15 ++--
examples/python/wasm_c_simple_add.py | 14 ++--
examples/python/wasm_rust_psi.py | 7 +-
examples/python/wasm_tvm_mnist.py | 4 +-
examples/rust/builtin_echo/src/main.rs | 4 +-
.../rust/builtin_ordered_set_intersect/src/main.rs | 5 +-
sdk/python/teaclave.py | 35 ++++++--
sdk/rust/src/lib.rs | 6 +-
services/management/enclave/src/service.rs | 15 ++--
.../src/proto/teaclave_frontend_service.proto | 12 ++-
services/proto/src/teaclave_frontend_service.rs | 92 ++++++++++++++++------
.../enclave/src/end_to_end/builtin_echo.rs | 3 +-
.../enclave/src/end_to_end/builtin_gbdt_train.rs | 18 ++---
.../enclave/src/end_to_end/mesapy_data_fusion.rs | 3 +-
.../enclave/src/end_to_end/mesapy_echo.rs | 3 +-
tests/functional/enclave/src/management_service.rs | 14 ++--
types/src/function.rs | 25 +++++-
types/src/staged_function.rs | 4 +
types/src/task_state.rs | 19 ++++-
31 files changed, 255 insertions(+), 104 deletions(-)
diff --git a/examples/c/builtin_echo.c b/examples/c/builtin_echo.c
index 3276be3a..9a838356 100644
--- a/examples/c/builtin_echo.c
+++ b/examples/c/builtin_echo.c
@@ -34,7 +34,7 @@ const char *register_function_request_serialized = QUOTE({
"executor_type" : "builtin",
"public" : true,
"payload" : [],
- "arguments" : ["message"],
+ "arguments" : [{"key": "message", "default_value": "", "allow_overwrite": true}],
"inputs" : [],
"outputs" : [],
"user_allowlist": []
diff --git a/examples/c/builtin_ordered_set_intersect.c b/examples/c/builtin_ordered_set_intersect.c
index ade3596b..2b278202 100644
--- a/examples/c/builtin_ordered_set_intersect.c
+++ b/examples/c/builtin_ordered_set_intersect.c
@@ -60,7 +60,7 @@ const char *register_function_request_serialized = QUOTE(
"executor_type": "builtin",
"public": true,
"payload": [],
- "arguments": ["order"],
+ "arguments": [{"key": "order", "default_value": "", "allow_overwrite": true}],
"inputs": [
{"name": "input_data1", "description": "Client 0 data.", "optional": false},
{"name": "input_data2", "description": "Client 1 data.", "optional": false}
diff --git a/examples/python/builtin_echo.py b/examples/python/builtin_echo.py
index 8c6f154e..fdfed5e8 100644
--- a/examples/python/builtin_echo.py
+++ b/examples/python/builtin_echo.py
@@ -20,6 +20,7 @@
import sys
from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service
+from teaclave import FunctionArgument
class BuiltinEchoExample:
@@ -42,7 +43,7 @@ class BuiltinEchoExample:
name="builtin-echo",
description="Native Echo Function",
executor_type="builtin",
- arguments=["message"])
+ arguments=[FunctionArgument("message")])
print("[+] creating task")
task_id = client.create_task(
diff --git a/examples/python/builtin_face_detection.py b/examples/python/builtin_face_detection.py
index 416e99c3..a0743735 100644
--- a/examples/python/builtin_face_detection.py
+++ b/examples/python/builtin_face_detection.py
@@ -25,6 +25,7 @@ from PIL import Image, ImageDraw
import requests
from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service
+from teaclave import FunctionArgument
class BuiltinFaceDetectionExample:
@@ -49,9 +50,12 @@ class BuiltinFaceDetectionExample:
executor_type="builtin",
inputs=[],
arguments=[
- "image", "min_face_size", "score_thresh",
- "pyramid_scale_factor", "slide_window_step_x",
- "slide_window_step_y"
+ FunctionArgument("image"),
+ FunctionArgument("min_face_size"),
+ FunctionArgument("score_thresh"),
+ FunctionArgument("pyramid_scale_factor"),
+ FunctionArgument("slide_window_step_x"),
+ FunctionArgument("slide_window_step_y")
])
print("[+] creating task")
diff --git a/examples/python/builtin_gbdt_train.py b/examples/python/builtin_gbdt_train.py
index e8ec045a..9b125104 100644
--- a/examples/python/builtin_gbdt_train.py
+++ b/examples/python/builtin_gbdt_train.py
@@ -19,7 +19,7 @@
import sys
-from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap
+from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap
from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service
@@ -44,9 +44,15 @@ class BuiltinGbdtExample:
description="Native Gbdt Training Function",
executor_type="builtin",
arguments=[
- "feature_size", "max_depth", "iterations", "shrinkage",
- "feature_sample_ratio", "data_sample_ratio", "min_leaf_size",
- "loss", "training_optimization_level"
+ FunctionArgument("feature_size"),
+ FunctionArgument("max_depth"),
+ FunctionArgument("iterations"),
+ FunctionArgument("shrinkage"),
+ FunctionArgument("feature_sample_ratio"),
+ FunctionArgument("data_sample_ratio"),
+ FunctionArgument("min_leaf_size"),
+ FunctionArgument("loss"),
+ FunctionArgument("training_optimization_level")
],
inputs=[
FunctionInput("training_data", "Input traning data file.")
diff --git a/examples/python/builtin_online_decrypt.py b/examples/python/builtin_online_decrypt.py
index aee9c80d..9a30b3b0 100644
--- a/examples/python/builtin_online_decrypt.py
+++ b/examples/python/builtin_online_decrypt.py
@@ -21,6 +21,7 @@ import sys
import base64
from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service
+from teaclave import FunctionArgument
class BuiltinOnlineDecryptExample:
@@ -43,7 +44,12 @@ class BuiltinOnlineDecryptExample:
name="builtin_online_decrypt",
description="Native Online Decrypt",
executor_type="builtin",
- arguments=["key", "nonce", "encrypted_data", "algorithm"])
+ arguments=[
+ FunctionArgument("key"),
+ FunctionArgument("nonce"),
+ FunctionArgument("encrypted_data"),
+ FunctionArgument("algorithm")
+ ])
print("[+] creating task")
task_id = client.create_task(
diff --git a/examples/python/builtin_ordered_set_intersect.py b/examples/python/builtin_ordered_set_intersect.py
index 36061971..277cef70 100644
--- a/examples/python/builtin_ordered_set_intersect.py
+++ b/examples/python/builtin_ordered_set_intersect.py
@@ -19,7 +19,7 @@
import sys
-from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap
+from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap
from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin
# In the example, user 0 creates the task and user 0, 1, upload their private data.
@@ -91,7 +91,7 @@ class Client:
name="builtin-ordered-set-intersect",
description="Native Private Set Intersection",
executor_type="builtin",
- arguments=["order"],
+ arguments=[FunctionArgument("order")],
inputs=[
FunctionInput("input_data1", "Client 0 data."),
FunctionInput("input_data2", "Client 1 data.")
diff --git a/examples/python/builtin_password_check.py b/examples/python/builtin_password_check.py
index aad72140..1715be0d 100644
--- a/examples/python/builtin_password_check.py
+++ b/examples/python/builtin_password_check.py
@@ -19,7 +19,7 @@
import sys
-from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap
+from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap
from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin
# In the example, user 0 creates the task and user 0, 1, upload their private data.
diff --git a/examples/python/builtin_private_join_and_compute.py b/examples/python/builtin_private_join_and_compute.py
index 37d198a1..0b7c89b6 100644
--- a/examples/python/builtin_private_join_and_compute.py
+++ b/examples/python/builtin_private_join_and_compute.py
@@ -19,7 +19,7 @@
import sys
-from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap
+from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap
from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin
# In the example, user 3 creates the task and user 0, 1, 2 upload their private data.
@@ -98,7 +98,7 @@ class ConfigClient:
name="builtin-private-join-and-compute",
description="Native Private Join And Compute",
executor_type="builtin",
- arguments=["num_user"],
+ arguments=[FunctionArgument("num_user")],
inputs=[
FunctionInput("input_data0", "Bank A data file."),
FunctionInput("input_data1", "Bank B data file."),
diff --git a/examples/python/builtin_rsa_sign.py b/examples/python/builtin_rsa_sign.py
index 80d95886..3ba494a1 100644
--- a/examples/python/builtin_rsa_sign.py
+++ b/examples/python/builtin_rsa_sign.py
@@ -19,7 +19,7 @@
import sys
-from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap
+from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap
from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin
@@ -61,7 +61,7 @@ def register_func(client):
name="builtin-rsa-sign",
description="Native Rsa Signing Function",
executor_type="builtin",
- arguments=["data"],
+ arguments=[FunctionArgument("data")],
inputs=[FunctionInput("rsa_key", "Input key file.")])
return function_id
diff --git a/examples/python/mesapy_echo.py b/examples/python/mesapy_echo.py
index d24c2aee..b60df003 100644
--- a/examples/python/mesapy_echo.py
+++ b/examples/python/mesapy_echo.py
@@ -19,7 +19,7 @@
import sys
-from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap
+from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap
from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin
@@ -49,7 +49,7 @@ class MesaPyEchoExample:
description="An echo function implemented in Python",
executor_type="python",
payload=list(payload),
- arguments=["message"])
+ arguments=[FunctionArgument("message")])
print("[+] creating task")
task_id = client.create_task(function_id=function_id,
diff --git a/examples/python/mesapy_logistic_reg.py b/examples/python/mesapy_logistic_reg.py
index 758a1865..2b8c8b81 100644
--- a/examples/python/mesapy_logistic_reg.py
+++ b/examples/python/mesapy_logistic_reg.py
@@ -23,7 +23,7 @@ An example about Logistic Regression in MesaPy.
import sys
import binascii
from typing import List
-from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap
+from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap
from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin
from enum import Enum
@@ -117,7 +117,7 @@ class ConfigClient:
name=functionname,
description="worker: %s" % functionname,
executor_type=ex.name,
- arguments=list(args.keys()),
+ arguments=[FunctionArgument(arg) for arg in args],
payload=list(p_str),
inputs=[
FunctionInput(label, "user input data fileļ¼ %s" % label)
diff --git a/examples/python/test_disable_function.py b/examples/python/test_disable_function.py
index 5c51e6d3..dbea609d 100644
--- a/examples/python/test_disable_function.py
+++ b/examples/python/test_disable_function.py
@@ -19,7 +19,7 @@
import sys
-from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap
+from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap
from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin
@@ -50,12 +50,13 @@ class ConfigClient:
print(f"[+] {self.user_id} registering function")
- function_id = client.register_function(name=func_name,
- description=func_name,
- executor_type="builtin",
- arguments=["num_user"],
- inputs=[],
- outputs=[])
+ function_id = client.register_function(
+ name=func_name,
+ description=func_name,
+ executor_type="builtin",
+ arguments=[FunctionArgument("num_user")],
+ inputs=[],
+ outputs=[])
return function_id
diff --git a/examples/python/wasm_c_simple_add.py b/examples/python/wasm_c_simple_add.py
index c45175a5..867cba3a 100644
--- a/examples/python/wasm_c_simple_add.py
+++ b/examples/python/wasm_c_simple_add.py
@@ -19,7 +19,7 @@
import sys
-from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap
+from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap
from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin
@@ -45,11 +45,13 @@ class WASMAddExample:
with open(payload_file, "rb") as f:
payload = f.read()
- function_id = client.register_function(name="entrypoint",
- description="test of wasm",
- executor_type="wamr",
- payload=list(payload),
- arguments=["adder1", "adder2"])
+ function_id = client.register_function(
+ name="entrypoint",
+ description="test of wasm",
+ executor_type="wamr",
+ payload=list(payload),
+ arguments=[FunctionArgument("adder1"),
+ FunctionArgument("adder2")])
print("[+] creating task")
task_id = client.create_task(function_id=function_id,
diff --git a/examples/python/wasm_rust_psi.py b/examples/python/wasm_rust_psi.py
index ead05eb5..61fc1c53 100644
--- a/examples/python/wasm_rust_psi.py
+++ b/examples/python/wasm_rust_psi.py
@@ -19,7 +19,7 @@
import sys
-from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap
+from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap
from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin
@@ -102,7 +102,10 @@ class Client:
payload=list(payload),
executor_type="wamr",
arguments=[
- "input1_fid", "input2_fid", "output1_fid", "output2_fid"
+ FunctionArgument("input1_fid"),
+ FunctionArgument("input2_fid"),
+ FunctionArgument("output1_fid"),
+ FunctionArgument("output2_fid")
],
inputs=[
FunctionInput(USER_DATA_0.input_fid, "Client 0 data."),
diff --git a/examples/python/wasm_tvm_mnist.py b/examples/python/wasm_tvm_mnist.py
index 3178874b..4f3b999c 100644
--- a/examples/python/wasm_tvm_mnist.py
+++ b/examples/python/wasm_tvm_mnist.py
@@ -19,7 +19,7 @@
import sys
-from teaclave import FunctionInput, FunctionOutput, OwnerList, DataMap
+from teaclave import FunctionInput, FunctionOutput, FunctionArgument, OwnerList, DataMap
from utils import USER_ID, USER_PASSWORD, connect_authentication_service, connect_frontend_service, PlatformAdmin
# If you're using `docker-compose` to start the Teaclave server containers,
@@ -61,7 +61,7 @@ def main():
description="WAMR TVM MNIST Prediction",
payload=list(payload),
executor_type="wamr",
- arguments=["input_img"],
+ arguments=[FunctionArgument("input_img")],
inputs=[
FunctionInput("input_img",
"Input image for handwriting number perdiction")
diff --git a/examples/rust/builtin_echo/src/main.rs b/examples/rust/builtin_echo/src/main.rs
index 11e95a69..378b43ba 100644
--- a/examples/rust/builtin_echo/src/main.rs
+++ b/examples/rust/builtin_echo/src/main.rs
@@ -64,7 +64,9 @@ fn echo(message: &str) -> Result<Vec<u8>> {
"An native echo function.",
"builtin",
None,
- Some(&["message"]),
+ Some(vec![teaclave_client_sdk::FunctionArgument::new(
+ "message", "", true,
+ )]),
None,
None,
)?;
diff --git a/examples/rust/builtin_ordered_set_intersect/src/main.rs b/examples/rust/builtin_ordered_set_intersect/src/main.rs
index 636dcd04..d39127d4 100644
--- a/examples/rust/builtin_ordered_set_intersect/src/main.rs
+++ b/examples/rust/builtin_ordered_set_intersect/src/main.rs
@@ -118,7 +118,10 @@ impl Client {
"Native Private Set Intersection.",
"builtin",
None,
- Some(&["order", "save_log"]),
+ Some(vec![
+ teaclave_client_sdk::FunctionArgument::new("order", "", true),
+ teaclave_client_sdk::FunctionArgument::new("save_log", "false", true),
+ ]),
Some(vec![
teaclave_client_sdk::FunctionInput::new("input_data1", "Client 0 data.", false),
teaclave_client_sdk::FunctionInput::new("input_data2", "Client 1 data.", false),
diff --git a/sdk/python/teaclave.py b/sdk/python/teaclave.py
index 5a6907cb..c4a4873c 100644
--- a/sdk/python/teaclave.py
+++ b/sdk/python/teaclave.py
@@ -44,8 +44,8 @@ from OpenSSL.crypto import X509Store, X509StoreContext
from OpenSSL import crypto
__all__ = [
- 'FrontendService', 'AuthenticationService', 'FunctionInput',
- 'FunctionOutput', 'OwnerList', 'DataMap'
+ 'FrontendService', 'AuthenticationService', 'FunctionArgument',
+ 'FunctionInput', 'FunctionOutput', 'OwnerList', 'DataMap'
]
Metadata = Dict[str, str]
@@ -250,6 +250,26 @@ class FunctionOutput:
self.optional = optional
+class FunctionArgument:
+ """Function argument for registring.
+
+ Args:
+ key: Name of the argument.
+ default_value: A default value of the argument. The default value is "".
+ allow_overwrite: If allow_overwrite flag is set to be true. The service
+ will allow the task creator to overwrite the arguement
+ value when creating tasks.
+ """
+
+ def __init__(self,
+ key: str,
+ default_value: str = "",
+ allow_overwrite=True):
+ self.key = key
+ self.default_value = default_value
+ self.allow_overwrite = allow_overwrite
+
+
class OwnerList:
"""Defines data ownership.
@@ -546,8 +566,9 @@ class RegisterFunctionRequest(Request):
def __init__(self, metadata: Metadata, name: str, description: str,
executor_type: str, public: bool, payload: List[int],
- arguments: List[str], inputs: List[FunctionInput],
- outputs: List[FunctionOutput], user_allowlist: List[str]):
+ arguments: List[FunctionArgument],
+ inputs: List[FunctionInput], outputs: List[FunctionOutput],
+ user_allowlist: List[str]):
self.request = "register_function"
self.metadata = metadata
self.name = name
@@ -565,7 +586,7 @@ class UpdateFunctionRequest(Request):
def __init__(self, metadata: Metadata, function_id: str, name: str,
description: str, executor_type: str, public: bool,
- payload: List[int], arguments: List[str],
+ payload: List[int], arguments: List[FunctionArgument],
inputs: List[FunctionInput], outputs: List[FunctionOutput],
user_allowlist: List[str]):
self.request = "update_function"
@@ -738,7 +759,7 @@ class FrontendService(TeaclaveService):
executor_type: str,
public: bool = True,
payload: List[int] = [],
- arguments: List[str] = [],
+ arguments: List[FunctionArgument] = [],
inputs: List[FunctionInput] = [],
outputs: List[FunctionOutput] = [],
user_allowlist: List[str] = [],
@@ -767,7 +788,7 @@ class FrontendService(TeaclaveService):
executor_type: str,
public: bool = True,
payload: List[int] = [],
- arguments: List[str] = [],
+ arguments: List[FunctionArgument] = [],
inputs: List[FunctionInput] = [],
outputs: List[FunctionOutput] = [],
user_allowlist: List[str] = [],
diff --git a/sdk/rust/src/lib.rs b/sdk/rust/src/lib.rs
index d4243a8c..65d80fed 100644
--- a/sdk/rust/src/lib.rs
+++ b/sdk/rust/src/lib.rs
@@ -41,7 +41,7 @@ pub use teaclave_proto::teaclave_frontend_service::{
RegisterOutputFileRequest, RegisterOutputFileResponse,
};
pub use teaclave_types::{
- EnclaveInfo, Executor, FileCrypto, FunctionInput, FunctionOutput, TaskResult,
+ EnclaveInfo, Executor, FileCrypto, FunctionArgument, FunctionInput, FunctionOutput, TaskResult,
};
pub mod bindings;
@@ -211,7 +211,7 @@ impl FrontendClient {
description: &str,
executor_type: &str,
payload: Option<&[u8]>,
- arguments: Option<&[&str]>,
+ arguments: Option<Vec<FunctionArgument>>,
inputs: Option<Vec<FunctionInput>>,
outputs: Option<Vec<FunctionOutput>>,
) -> Result<String> {
@@ -592,7 +592,7 @@ mod tests {
"An native echo function.",
"builtin",
None,
- Some(&["message"]),
+ Some(vec![FunctionArgument::new("message", "", true)]),
None,
None,
)
diff --git a/services/management/enclave/src/service.rs b/services/management/enclave/src/service.rs
index 73a7298e..1557de35 100644
--- a/services/management/enclave/src/service.rs
+++ b/services/management/enclave/src/service.rs
@@ -891,6 +891,8 @@ impl TeaclaveManagementService {
let function_output = FunctionOutput::new("output", "output_desc", false);
let function_input2 = FunctionInput::new("input2", "input_desc", false);
let function_output2 = FunctionOutput::new("output2", "output_desc", false);
+ let function_arg1 = FunctionArgument::new("arg1", "", true);
+ let function_arg2 = FunctionArgument::new("arg2", "", true);
let function = FunctionBuilder::new()
.id(Uuid::parse_str("00000000-0000-0000-0000-000000000001").unwrap())
@@ -898,7 +900,7 @@ impl TeaclaveManagementService {
.description("mock-desc")
.payload(b"mock-payload".to_vec())
.public(true)
- .arguments(vec!["arg1".to_string(), "arg2".to_string()])
+ .arguments(vec![function_arg1, function_arg2])
.inputs(vec![function_input, function_input2])
.outputs(vec![function_output, function_output2])
.owner("teaclave".to_string())
@@ -907,13 +909,14 @@ impl TeaclaveManagementService {
self.write_to_db(&function)?;
let function_output = FunctionOutput::new("output", "output_desc", false);
+ let function_arg1 = FunctionArgument::new("arg1", "", true);
let function = FunctionBuilder::new()
.id(Uuid::parse_str("00000000-0000-0000-0000-000000000002").unwrap())
.name("mock-func-2")
.description("mock-desc")
.payload(b"mock-payload".to_vec())
.public(true)
- .arguments(vec!["arg1".to_string()])
+ .arguments(vec![function_arg1.clone()])
.outputs(vec![function_output])
.owner("teaclave".to_string())
.build();
@@ -926,7 +929,7 @@ impl TeaclaveManagementService {
.description("Private mock function")
.payload(b"mock-payload".to_vec())
.public(false)
- .arguments(vec!["arg1".to_string()])
+ .arguments(vec![function_arg1])
.owner("mock_user".to_string())
.user_allowlist(vec!["mock_user".to_string(), "mock_user1".to_string()])
.build();
@@ -995,12 +998,13 @@ pub mod tests {
pub fn handle_function() {
let function_input = FunctionInput::new("input", "input_desc", false);
let function_output = FunctionOutput::new("output", "output_desc", false);
+ let function_arg = FunctionArgument::new("arg", "", true);
let function = FunctionBuilder::new()
.id(Uuid::new_v4())
.name("mock_function")
.description("mock function")
.payload(b"python script".to_vec())
- .arguments(vec!["arg".to_string()])
+ .arguments(vec![function_arg])
.inputs(vec![function_input])
.outputs(vec![function_output])
.public(true)
@@ -1013,12 +1017,13 @@ pub mod tests {
}
pub fn handle_task() {
+ let function_arg = FunctionArgument::new("arg", "", true);
let function = FunctionBuilder::new()
.id(Uuid::new_v4())
.name("mock_function")
.description("mock function")
.payload(b"python script".to_vec())
- .arguments(vec!["arg".to_string()])
+ .arguments(vec![function_arg])
.public(true)
.owner("mock_user")
.build();
diff --git a/services/proto/src/proto/teaclave_frontend_service.proto b/services/proto/src/proto/teaclave_frontend_service.proto
index 31d8fd07..afd0dbb4 100644
--- a/services/proto/src/proto/teaclave_frontend_service.proto
+++ b/services/proto/src/proto/teaclave_frontend_service.proto
@@ -107,6 +107,12 @@ message FunctionOutput {
bool optional = 3;
}
+message FunctionArgument {
+ string key = 1;
+ string default_value = 2;
+ bool allow_overwrite = 3;
+}
+
message OwnerList {
string data_name = 1;
repeated string uids = 2;
@@ -118,7 +124,7 @@ message RegisterFunctionRequest {
string executor_type = 3;
bool public = 4;
bytes payload = 5;
- repeated string arguments = 6;
+ repeated FunctionArgument arguments = 6;
repeated FunctionInput inputs = 10;
repeated FunctionOutput outputs = 11;
repeated string user_allowlist = 12;
@@ -135,7 +141,7 @@ message UpdateFunctionRequest {
string executor_type = 4;
bool public = 5;
bytes payload = 6;
- repeated string arguments = 7;
+ repeated FunctionArgument arguments = 7;
repeated FunctionInput inputs = 10;
repeated FunctionOutput outputs = 11;
repeated string user_allowlist = 12;
@@ -156,7 +162,7 @@ message GetFunctionResponse {
string owner = 4;
bytes payload = 5;
bool public = 6;
- repeated string arguments = 7;
+ repeated FunctionArgument arguments = 7;
repeated FunctionInput inputs = 10;
repeated FunctionOutput outputs = 11;
repeated string user_allowlist = 12;
diff --git a/services/proto/src/teaclave_frontend_service.rs b/services/proto/src/teaclave_frontend_service.rs
index 6d5b6bf6..2e3c9150 100644
--- a/services/proto/src/teaclave_frontend_service.rs
+++ b/services/proto/src/teaclave_frontend_service.rs
@@ -25,9 +25,9 @@ use core::convert::TryInto;
use std::collections::HashMap;
use teaclave_rpc::into_request;
use teaclave_types::{
- Executor, ExecutorType, ExternalID, FileAuthTag, FileCrypto, FunctionArguments,
- FunctionBuilder, FunctionInput, FunctionOutput, OwnerList, TaskFileOwners, TaskResult,
- TaskStatus, UserID, UserList,
+ Executor, ExecutorType, ExternalID, FileAuthTag, FileCrypto, FunctionArgument,
+ FunctionArguments, FunctionBuilder, FunctionInput, FunctionOutput, OwnerList, TaskFileOwners,
+ TaskResult, TaskStatus, UserID, UserList,
};
use url::Url;
@@ -284,7 +284,7 @@ pub struct RegisterFunctionRequest {
pub executor_type: ExecutorType,
pub payload: Vec<u8>,
pub public: bool,
- pub arguments: Vec<String>,
+ pub arguments: Vec<FunctionArgument>,
pub inputs: Vec<FunctionInput>,
pub outputs: Vec<FunctionOutput>,
pub user_allowlist: Vec<String>,
@@ -331,11 +331,8 @@ impl RegisterFunctionRequestBuilder {
self
}
- pub fn arguments<T: IntoIterator>(mut self, args: T) -> Self
- where
- <T as IntoIterator>::Item: ToString,
- {
- self.request.arguments = args.into_iter().map(|x| x.to_string()).collect();
+ pub fn arguments(mut self, args: Vec<FunctionArgument>) -> Self {
+ self.request.arguments = args;
self
}
@@ -397,7 +394,7 @@ pub struct UpdateFunctionRequest {
pub executor_type: ExecutorType,
pub payload: Vec<u8>,
pub public: bool,
- pub arguments: Vec<String>,
+ pub arguments: Vec<FunctionArgument>,
pub inputs: Vec<FunctionInput>,
pub outputs: Vec<FunctionOutput>,
pub user_allowlist: Vec<String>,
@@ -449,11 +446,8 @@ impl UpdateFunctionRequestBuilder {
self
}
- pub fn arguments<T: IntoIterator>(mut self, args: T) -> Self
- where
- <T as IntoIterator>::Item: ToString,
- {
- self.request.arguments = args.into_iter().map(|x| x.to_string()).collect();
+ pub fn arguments(mut self, args: Vec<FunctionArgument>) -> Self {
+ self.request.arguments = args;
self
}
@@ -528,7 +522,7 @@ pub struct GetFunctionResponse {
pub payload: Vec<u8>,
pub public: bool,
pub executor_type: ExecutorType,
- pub arguments: Vec<String>,
+ pub arguments: Vec<FunctionArgument>,
pub inputs: Vec<FunctionInput>,
pub outputs: Vec<FunctionOutput>,
pub user_allowlist: Vec<String>,
@@ -1123,6 +1117,11 @@ impl std::convert::TryFrom<proto::RegisterFunctionRequest> for RegisterFunctionR
.map(FunctionOutput::try_from)
.collect();
let executor_type = proto.executor_type.try_into()?;
+ let arguments: Result<Vec<FunctionArgument>> = proto
+ .arguments
+ .into_iter()
+ .map(FunctionArgument::try_from)
+ .collect();
let ret = Self {
name: proto.name,
@@ -1130,7 +1129,7 @@ impl std::convert::TryFrom<proto::RegisterFunctionRequest> for RegisterFunctionR
executor_type,
payload: proto.payload,
public: proto.public,
- arguments: proto.arguments,
+ arguments: arguments?,
inputs: inputs?,
outputs: outputs?,
user_allowlist: proto.user_allowlist,
@@ -1151,6 +1150,11 @@ impl From<RegisterFunctionRequest> for proto::RegisterFunctionRequest {
.into_iter()
.map(proto::FunctionOutput::from)
.collect();
+ let arguments: Vec<proto::FunctionArgument> = request
+ .arguments
+ .into_iter()
+ .map(proto::FunctionArgument::from)
+ .collect();
Self {
name: request.name,
@@ -1158,7 +1162,7 @@ impl From<RegisterFunctionRequest> for proto::RegisterFunctionRequest {
executor_type: request.executor_type.into(),
payload: request.payload,
public: request.public,
- arguments: request.arguments,
+ arguments,
inputs,
outputs,
user_allowlist: request.user_allowlist,
@@ -1201,6 +1205,11 @@ impl std::convert::TryFrom<proto::UpdateFunctionRequest> for UpdateFunctionReque
.map(FunctionOutput::try_from)
.collect();
let executor_type = proto.executor_type.try_into()?;
+ let arguments: Result<Vec<FunctionArgument>> = proto
+ .arguments
+ .into_iter()
+ .map(FunctionArgument::try_from)
+ .collect();
let ret = Self {
function_id,
@@ -1209,7 +1218,7 @@ impl std::convert::TryFrom<proto::UpdateFunctionRequest> for UpdateFunctionReque
executor_type,
payload: proto.payload,
public: proto.public,
- arguments: proto.arguments,
+ arguments: arguments?,
inputs: inputs?,
outputs: outputs?,
user_allowlist: proto.user_allowlist,
@@ -1230,6 +1239,11 @@ impl From<UpdateFunctionRequest> for proto::UpdateFunctionRequest {
.into_iter()
.map(proto::FunctionOutput::from)
.collect();
+ let arguments: Vec<proto::FunctionArgument> = request
+ .arguments
+ .into_iter()
+ .map(proto::FunctionArgument::from)
+ .collect();
Self {
function_id: request.function_id.to_string(),
@@ -1238,7 +1252,7 @@ impl From<UpdateFunctionRequest> for proto::UpdateFunctionRequest {
executor_type: request.executor_type.into(),
payload: request.payload,
public: request.public,
- arguments: request.arguments,
+ arguments,
inputs,
outputs,
user_allowlist: request.user_allowlist,
@@ -1406,6 +1420,11 @@ impl std::convert::TryFrom<proto::GetFunctionResponse> for GetFunctionResponse {
.map(FunctionOutput::try_from)
.collect();
let executor_type = proto.executor_type.try_into()?;
+ let arguments: Result<Vec<FunctionArgument>> = proto
+ .arguments
+ .into_iter()
+ .map(FunctionArgument::try_from)
+ .collect();
let ret = Self {
name: proto.name,
@@ -1414,7 +1433,7 @@ impl std::convert::TryFrom<proto::GetFunctionResponse> for GetFunctionResponse {
executor_type,
payload: proto.payload,
public: proto.public,
- arguments: proto.arguments,
+ arguments: arguments?,
inputs: inputs?,
outputs: outputs?,
user_allowlist: proto.user_allowlist,
@@ -1436,6 +1455,11 @@ impl From<GetFunctionResponse> for proto::GetFunctionResponse {
.into_iter()
.map(proto::FunctionOutput::from)
.collect();
+ let arguments: Vec<proto::FunctionArgument> = response
+ .arguments
+ .into_iter()
+ .map(proto::FunctionArgument::from)
+ .collect();
Self {
name: response.name,
@@ -1444,7 +1468,7 @@ impl From<GetFunctionResponse> for proto::GetFunctionResponse {
executor_type: response.executor_type.into(),
payload: response.payload,
public: response.public,
- arguments: response.arguments,
+ arguments,
inputs,
outputs,
user_allowlist: response.user_allowlist,
@@ -1452,6 +1476,30 @@ impl From<GetFunctionResponse> for proto::GetFunctionResponse {
}
}
+impl std::convert::TryFrom<proto::FunctionArgument> for FunctionArgument {
+ type Error = Error;
+
+ fn try_from(proto: proto::FunctionArgument) -> Result<Self> {
+ let ret = Self {
+ key: proto.key,
+ default_value: proto.default_value,
+ allow_overwrite: proto.allow_overwrite,
+ };
+
+ Ok(ret)
+ }
+}
+
+impl From<FunctionArgument> for proto::FunctionArgument {
+ fn from(arg: FunctionArgument) -> Self {
+ Self {
+ key: arg.key,
+ default_value: arg.default_value,
+ allow_overwrite: arg.allow_overwrite,
+ }
+ }
+}
+
fn from_proto_ownership(proto: Vec<proto::OwnerList>) -> TaskFileOwners {
proto
.into_iter()
diff --git a/tests/functional/enclave/src/end_to_end/builtin_echo.rs b/tests/functional/enclave/src/end_to_end/builtin_echo.rs
index 15a1f68d..3b1da0c3 100644
--- a/tests/functional/enclave/src/end_to_end/builtin_echo.rs
+++ b/tests/functional/enclave/src/end_to_end/builtin_echo.rs
@@ -26,12 +26,13 @@ pub fn test_echo_task_success() {
let cred = login(&mut api_client, USERNAME, TEST_PASSWORD).unwrap();
let mut client =
create_frontend_client(shared_enclave_info(), FRONTEND_SERVICE_ADDR, cred).unwrap();
+ let arg = FunctionArgument::new("message", "", true);
// Register Function
let request = RegisterFunctionRequestBuilder::new()
.name("builtin-echo")
.description("Native Echo Function")
- .arguments(vec!["message"])
+ .arguments(vec![arg])
.build();
let response = client.register_function(request).unwrap();
diff --git a/tests/functional/enclave/src/end_to_end/builtin_gbdt_train.rs b/tests/functional/enclave/src/end_to_end/builtin_gbdt_train.rs
index 273f41f8..2672a85c 100644
--- a/tests/functional/enclave/src/end_to_end/builtin_gbdt_train.rs
+++ b/tests/functional/enclave/src/end_to_end/builtin_gbdt_train.rs
@@ -49,15 +49,15 @@ fn register_gbdt_function(client: &mut TeaclaveFrontendClient) -> ExternalID {
let fn_input = FunctionInput::new("training_data", "Input traning data file.", false);
let fn_output = FunctionOutput::new("trained_model", "Output trained model.", false);
let fn_args = vec![
- "feature_size",
- "max_depth",
- "iterations",
- "shrinkage",
- "feature_sample_ratio",
- "data_sample_ratio",
- "min_leaf_size",
- "loss",
- "training_optimization_level",
+ FunctionArgument::new("feature_size", "", true),
+ FunctionArgument::new("max_depth", "", true),
+ FunctionArgument::new("iterations", "", true),
+ FunctionArgument::new("shrinkage", "", true),
+ FunctionArgument::new("feature_sample_ratio", "", true),
+ FunctionArgument::new("data_sample_ratio", "", true),
+ FunctionArgument::new("min_leaf_size", "", true),
+ FunctionArgument::new("loss", "", true),
+ FunctionArgument::new("training_optimization_level", "", true),
];
// Register Function
diff --git a/tests/functional/enclave/src/end_to_end/mesapy_data_fusion.rs b/tests/functional/enclave/src/end_to_end/mesapy_data_fusion.rs
index 266ce273..d2f992da 100644
--- a/tests/functional/enclave/src/end_to_end/mesapy_data_fusion.rs
+++ b/tests/functional/enclave/src/end_to_end/mesapy_data_fusion.rs
@@ -231,10 +231,11 @@ def entrypoint(argv):
"#;
let input_spec = FunctionInput::new("InputData", "Lines of Data", false);
+ let arg = FunctionArgument::new("query", "", true);
let request = RegisterFunctionRequestBuilder::new()
.name("wlc")
.description("Mesapy Word Line Count Function")
- .arguments(vec!["query"])
+ .arguments(vec![arg])
.payload(script.into())
.executor_type(ExecutorType::Python)
.public(true)
diff --git a/tests/functional/enclave/src/end_to_end/mesapy_echo.rs b/tests/functional/enclave/src/end_to_end/mesapy_echo.rs
index 42d1fb60..761f3bea 100644
--- a/tests/functional/enclave/src/end_to_end/mesapy_echo.rs
+++ b/tests/functional/enclave/src/end_to_end/mesapy_echo.rs
@@ -33,6 +33,7 @@ def entrypoint(argv):
assert argv[1] is not None
return argv[1]
";
+ let arg = FunctionArgument::new("message", "", true);
// Register Function
let request = RegisterFunctionRequestBuilder::new()
.name("mesapy_echo_demo")
@@ -40,7 +41,7 @@ def entrypoint(argv):
.payload(script.into())
.executor_type(ExecutorType::Python)
.public(true)
- .arguments(vec!["message"])
+ .arguments(vec![arg])
.build();
let response = client.register_function(request).unwrap();
diff --git a/tests/functional/enclave/src/management_service.rs b/tests/functional/enclave/src/management_service.rs
index 9ee0ea49..95249edd 100644
--- a/tests/functional/enclave/src/management_service.rs
+++ b/tests/functional/enclave/src/management_service.rs
@@ -132,7 +132,7 @@ fn test_register_function() {
.executor_type(ExecutorType::Python)
.payload(b"def entrypoint:\n\treturn".to_vec())
.public(true)
- .arguments(vec!["arg"])
+ .arguments(vec![FunctionArgument::new("arg", "", true)])
.inputs(vec![function_input])
.outputs(vec![function_output])
.build();
@@ -152,7 +152,7 @@ fn test_register_private_function() {
.executor_type(ExecutorType::Python)
.payload(b"def entrypoint:\n\treturn".to_vec())
.public(false)
- .arguments(vec!["arg"])
+ .arguments(vec![FunctionArgument::new("arg", "", true)])
.inputs(vec![function_input])
.outputs(vec![function_output])
.user_allowlist(vec!["mock_user".to_string()])
@@ -173,7 +173,7 @@ fn test_delete_function() {
.executor_type(ExecutorType::Python)
.payload(b"def entrypoint:\n\treturn".to_vec())
.public(true)
- .arguments(vec!["arg"])
+ .arguments(vec![FunctionArgument::new("arg", "", true)])
.inputs(vec![function_input])
.outputs(vec![function_output])
.build();
@@ -196,7 +196,7 @@ fn test_disable_function() {
.executor_type(ExecutorType::Python)
.payload(b"def entrypoint:\n\treturn".to_vec())
.public(true)
- .arguments(vec!["arg"])
+ .arguments(vec![FunctionArgument::new("arg", "", true)])
.inputs(vec![function_input])
.outputs(vec![function_output])
.build();
@@ -219,7 +219,7 @@ fn test_update_function() {
.executor_type(ExecutorType::Python)
.payload(b"def entrypoint:\n\treturn".to_vec())
.public(true)
- .arguments(vec!["arg"])
+ .arguments(vec![FunctionArgument::new("arg", "", true)])
.inputs(vec![function_input])
.outputs(vec![function_output])
.build();
@@ -236,7 +236,7 @@ fn test_update_function() {
.executor_type(ExecutorType::Python)
.payload(b"def entrypoint:\n\treturn".to_vec())
.public(false)
- .arguments(vec!["arg"])
+ .arguments(vec![FunctionArgument::new("arg", "", true)])
.inputs(vec![function_input])
.outputs(vec![function_output])
.user_allowlist(vec!["mock_user".to_string()])
@@ -270,7 +270,7 @@ fn test_get_function() {
.executor_type(ExecutorType::Python)
.payload(b"def entrypoint:\n\treturn".to_vec())
.public(false)
- .arguments(vec!["arg"])
+ .arguments(vec![FunctionArgument::new("arg", "", true)])
.inputs(vec![function_input])
.outputs(vec![function_output])
.build();
diff --git a/types/src/function.rs b/types/src/function.rs
index cf61ccf2..0180d8e8 100644
--- a/types/src/function.rs
+++ b/types/src/function.rs
@@ -82,7 +82,7 @@ pub struct Function {
pub public: bool,
pub executor_type: ExecutorType,
pub payload: Vec<u8>,
- pub arguments: Vec<String>,
+ pub arguments: Vec<FunctionArgument>,
pub inputs: Vec<FunctionInput>,
pub outputs: Vec<FunctionOutput>,
pub owner: UserID,
@@ -131,7 +131,7 @@ impl FunctionBuilder {
self
}
- pub fn arguments(mut self, arguments: Vec<String>) -> Self {
+ pub fn arguments(mut self, arguments: Vec<FunctionArgument>) -> Self {
self.function.arguments = arguments;
self
}
@@ -170,3 +170,24 @@ impl Storable for Function {
self.id
}
}
+
+#[derive(Debug, Deserialize, Serialize, Clone)]
+pub struct FunctionArgument {
+ pub key: String,
+ pub default_value: String,
+ pub allow_overwrite: bool,
+}
+
+impl FunctionArgument {
+ pub fn new(
+ key: impl Into<String>,
+ default_value: impl Into<String>,
+ allow_overwrite: bool,
+ ) -> Self {
+ Self {
+ key: key.into(),
+ default_value: default_value.into(),
+ allow_overwrite,
+ }
+ }
+}
diff --git a/types/src/staged_function.rs b/types/src/staged_function.rs
index 796acc8a..d0ee4923 100644
--- a/types/src/staged_function.rs
+++ b/types/src/staged_function.rs
@@ -100,6 +100,10 @@ impl FunctionArguments {
pub fn into_string(self) -> String {
ArgumentValue::Object(self.inner).to_string()
}
+
+ pub fn insert(&mut self, k: String, v: ArgumentValue) -> Option<ArgumentValue> {
+ self.inner.insert(k, v)
+ }
}
#[derive(Debug, Default)]
diff --git a/types/src/task_state.rs b/types/src/task_state.rs
index 682afd23..aaece9f6 100644
--- a/types/src/task_state.rs
+++ b/types/src/task_state.rs
@@ -129,10 +129,25 @@ impl Task<Create> {
}
//check function compatibility
- let fn_args_spec: HashSet<&String> = function.arguments.iter().collect();
+ let fn_args_spec: HashSet<&String> = function
+ .arguments
+ .iter()
+ .filter(|arg| arg.allow_overwrite)
+ .map(|arg| &arg.key)
+ .collect();
let req_args: HashSet<&String> = req_func_args.inner().keys().collect();
ensure!(fn_args_spec == req_args, "function_arguments mismatch");
+ let mut func_args = req_func_args;
+ for arg in &function.arguments {
+ if !arg.allow_overwrite || !func_args.inner().contains_key(&arg.key) {
+ func_args.insert(
+ arg.key.clone(),
+ serde_json::Value::String(arg.default_value.clone()),
+ );
+ }
+ }
+
// check input fkeys
let inputs_spec: HashSet<&String> = function.inputs.iter().map(|f| &f.name).collect();
let mut req_input_fkeys: HashSet<&String> = req_input_owners.keys().collect();
@@ -166,7 +181,7 @@ impl Task<Create> {
executor: req_executor,
function_id: function.external_id(),
function_owner: function.owner.clone(),
- function_arguments: req_func_args,
+ function_arguments: func_args,
inputs_ownership: req_input_owners,
outputs_ownership: req_output_owners,
participants,
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org