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

commit 42e74ae7ae439527e48366bf38cc5cc0ba3d63b8
Author: GeminiCarrie <[email protected]>
AuthorDate: Fri Jun 16 02:59:38 2023 +0000

    Add an example calling functions sequentially
    
    - Add an example using the fusion output of builtin_ordered_set_join as the 
input data for builtin_gbdt_train.
---
 cmake/scripts/test.sh                              |    3 +
 examples/rust/sequential_functions/Cargo.lock      | 1628 ++++++++++++++++++++
 examples/rust/sequential_functions/Cargo.toml      |   35 +
 examples/rust/sequential_functions/src/main.rs     |  380 +++++
 sdk/c/teaclave_client_sdk.h                        |   52 +
 sdk/python/teaclave.py                             |   50 +
 sdk/rust/src/bindings.rs                           |   10 +
 sdk/rust/src/lib.rs                                |   60 +-
 .../functions/ordered_set_join/join0.csv.enc       |  Bin 0 -> 4096 bytes
 .../functions/ordered_set_join/join1.csv.enc       |  Bin 0 -> 4096 bytes
 10 files changed, 2216 insertions(+), 2 deletions(-)

diff --git a/cmake/scripts/test.sh b/cmake/scripts/test.sh
index 0d2474dd..fcdc66cb 100755
--- a/cmake/scripts/test.sh
+++ b/cmake/scripts/test.sh
@@ -243,6 +243,9 @@ builtin_examples() {
   pushd ./builtin_ordered_set_intersect
   RUSTFLAGS=${RUSTFLAGS} cargo run
   popd
+  pushd ./sequential_functions
+  RUSTFLAGS=${RUSTFLAGS} cargo run
+  popd
   popd
 }
 
diff --git a/examples/rust/sequential_functions/Cargo.lock 
b/examples/rust/sequential_functions/Cargo.lock
new file mode 100644
index 00000000..8fc8fa73
--- /dev/null
+++ b/examples/rust/sequential_functions/Cargo.lock
@@ -0,0 +1,1628 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "aho-corasick"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "android-tzdata"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
+
+[[package]]
+name = "anyhow"
+version = "1.0.71"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
+
+[[package]]
+name = "async-stream"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51"
+dependencies = [
+ "async-stream-impl",
+ "futures-core",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "async-stream-impl"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.22",
+]
+
+[[package]]
+name = "async-trait"
+version = "0.1.68"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.22",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "base64"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
+
+[[package]]
+name = "base64"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
+
+[[package]]
+name = "bit-vec"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bumpalo"
+version = "3.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1"
+
+[[package]]
+name = "bytes"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
+
+[[package]]
+name = "cc"
+version = "1.0.79"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
+
+[[package]]
+name = "cfg-if"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "chrono"
+version = "0.4.26"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5"
+dependencies = [
+ "android-tzdata",
+ "num-traits",
+]
+
+[[package]]
+name = "crc32fast"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "either"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
+
+[[package]]
+name = "errno"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
+dependencies = [
+ "errno-dragonfly",
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
+name = "errno-dragonfly"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "fastrand"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
+dependencies = [
+ "instant",
+]
+
+[[package]]
+name = "fixedbitset"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
+
+[[package]]
+name = "flate2"
+version = "1.0.26"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
+dependencies = [
+ "futures-core",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
+
+[[package]]
+name = "futures-sink"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
+
+[[package]]
+name = "futures-task"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
+
+[[package]]
+name = "futures-util"
+version = "0.3.28"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "pin-project-lite",
+ "pin-utils",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.10"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
+dependencies = [
+ "cfg-if 1.0.0",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "h2"
+version = "0.3.19"
+source = 
"git+https://github.com/hyperium/h2?tag=v0.3.19#f126229cf436b3609236582d80a5c25cc944dd4b";
+dependencies = [
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http",
+ "indexmap",
+ "slab",
+ "tokio",
+ "tokio-util 0.7.8",
+ "tracing",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "heck"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
+dependencies = [
+ "unicode-segmentation",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
+
+[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[package]]
+name = "http"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "http-body"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
+dependencies = [
+ "bytes",
+ "http",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "httparse"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
+
+[[package]]
+name = "httpdate"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
+
+[[package]]
+name = "hyper"
+version = "0.14.26"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "socket2",
+ "tokio",
+ "tower-service",
+ "tracing",
+ "want",
+]
+
+[[package]]
+name = "hyper-timeout"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1"
+dependencies = [
+ "hyper",
+ "pin-project-lite",
+ "tokio",
+ "tokio-io-timeout",
+]
+
+[[package]]
+name = "idna"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "indexmap"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "instant"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
+name = "io-lifetimes"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
+dependencies = [
+ "hermit-abi 0.3.1",
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
+name = "itertools"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
+
+[[package]]
+name = "js-sys"
+version = "0.3.64"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.147"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
+
+[[package]]
+name = "log"
+version = "0.4.19"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
+dependencies = [
+ "adler",
+]
+
+[[package]]
+name = "mio"
+version = "0.8.8"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
+dependencies = [
+ "libc",
+ "wasi",
+ "windows-sys",
+]
+
+[[package]]
+name = "multimap"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
+
+[[package]]
+name = "num-bigint"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304"
+dependencies = [
+ "autocfg",
+ "num-integer",
+ "num-traits",
+]
+
+[[package]]
+name = "num-integer"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
+dependencies = [
+ "autocfg",
+ "num-traits",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
+dependencies = [
+ "hermit-abi 0.2.6",
+ "libc",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.18.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
+
+[[package]]
+name = "pem"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "a1581760c757a756a41f0ee3ff01256227bdf64cb752839779b95ffb01c59793"
+dependencies = [
+ "base64 0.11.0",
+ "lazy_static",
+ "regex",
+]
+
+[[package]]
+name = "percent-encoding"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
+
+[[package]]
+name = "petgraph"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4"
+dependencies = [
+ "fixedbitset",
+ "indexmap",
+]
+
+[[package]]
+name = "pin-project"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead"
+dependencies = [
+ "pin-project-internal",
+]
+
+[[package]]
+name = "pin-project-internal"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.22",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.63"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "prost"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001"
+dependencies = [
+ "bytes",
+ "prost-derive",
+]
+
+[[package]]
+name = "prost-build"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "62941722fb675d463659e49c4f3fe1fe792ff24fe5bbaa9c08cd3b98a1c354f5"
+dependencies = [
+ "bytes",
+ "heck",
+ "itertools",
+ "lazy_static",
+ "log",
+ "multimap",
+ "petgraph",
+ "prost",
+ "prost-types",
+ "regex",
+ "tempfile",
+ "which",
+]
+
+[[package]]
+name = "prost-derive"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe"
+dependencies = [
+ "anyhow",
+ "itertools",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "prost-types"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "534b7a0e836e3c482d2693070f982e39e7611da9695d4d1f5a4b186b51faef0a"
+dependencies = [
+ "bytes",
+ "prost",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.28"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "rdrand"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "e233b642160555c1aa1ff7a78443c6139342f411b6fa6602af2ebbfee9e166bb"
+dependencies = [
+ "rand_core",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "regex"
+version = "1.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
+
+[[package]]
+name = "ring"
+version = "0.16.20"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
+dependencies = [
+ "cc",
+ "libc",
+ "once_cell",
+ "spin",
+ "untrusted",
+ "web-sys",
+ "winapi",
+]
+
+[[package]]
+name = "rustix"
+version = "0.37.20"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0"
+dependencies = [
+ "bitflags",
+ "errno",
+ "io-lifetimes",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys",
+]
+
+[[package]]
+name = "rustls"
+version = "0.19.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7"
+dependencies = [
+ "base64 0.13.1",
+ "log",
+ "ring",
+ "sct",
+ "webpki",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.13"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
+
+[[package]]
+name = "sct"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
+name = "sequential_functions"
+version = "0.6.0"
+dependencies = [
+ "anyhow",
+ "pem",
+ "serde_json",
+ "teaclave_client_sdk",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.164"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.164"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.22",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.99"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "sgx_build_helper"
+version = "2.0.0"
+
+[[package]]
+name = "sgx_crypto"
+version = "2.0.0"
+dependencies = [
+ "sgx_crypto_sys",
+ "sgx_rand",
+ "sgx_types",
+]
+
+[[package]]
+name = "sgx_crypto_sys"
+version = "2.0.0"
+dependencies = [
+ "sgx_build_helper",
+ "sgx_download_prebuilt",
+ "sgx_types",
+]
+
+[[package]]
+name = "sgx_download_prebuilt"
+version = "2.0.0"
+dependencies = [
+ "sgx_build_helper",
+]
+
+[[package]]
+name = "sgx_rand"
+version = "2.0.0"
+dependencies = [
+ "rand_core",
+ "rdrand",
+]
+
+[[package]]
+name = "sgx_tprotected_fs"
+version = "2.0.0"
+dependencies = [
+ "sgx_crypto",
+ "sgx_rand",
+ "sgx_types",
+ "sgx_uprotected_fs",
+]
+
+[[package]]
+name = "sgx_types"
+version = "2.0.0"
+
+[[package]]
+name = "sgx_uprotected_fs"
+version = "2.0.0"
+dependencies = [
+ "libc",
+ "sgx_types",
+]
+
+[[package]]
+name = "sha1"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770"
+dependencies = [
+ "sha1_smol",
+]
+
+[[package]]
+name = "sha1_smol"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
+
+[[package]]
+name = "slab"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "socket2"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "spin"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+
+[[package]]
+name = "syn"
+version = "1.0.109"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.22"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "teaclave_attestation"
+version = "0.6.0"
+dependencies = [
+ "anyhow",
+ "base64 0.13.1",
+ "bit-vec",
+ "cfg-if 0.1.10",
+ "chrono",
+ "hex",
+ "httparse",
+ "log",
+ "num-bigint",
+ "percent-encoding",
+ "rustls",
+ "serde",
+ "serde_json",
+ "sgx_types",
+ "teaclave_config",
+ "teaclave_types",
+ "thiserror",
+ "url",
+ "uuid",
+ "webpki",
+ "webpki-roots",
+ "yasna",
+]
+
+[[package]]
+name = "teaclave_client_sdk"
+version = "0.6.0"
+dependencies = [
+ "anyhow",
+ "libc",
+ "pem",
+ "serde",
+ "serde_json",
+ "teaclave_attestation",
+ "teaclave_proto",
+ "teaclave_rpc",
+ "teaclave_types",
+ "tokio",
+ "url",
+]
+
+[[package]]
+name = "teaclave_config"
+version = "0.6.0"
+dependencies = [
+ "anyhow",
+ "log",
+ "serde",
+ "toml",
+ "url",
+]
+
+[[package]]
+name = "teaclave_crypto"
+version = "0.6.0"
+dependencies = [
+ "anyhow",
+ "hex",
+ "rand",
+ "ring",
+ "serde",
+ "serde_json",
+ "sgx_tprotected_fs",
+]
+
+[[package]]
+name = "teaclave_proto"
+version = "0.6.0"
+dependencies = [
+ "anyhow",
+ "chrono",
+ "prost",
+ "serde",
+ "serde_json",
+ "sgx_types",
+ "teaclave_crypto",
+ "teaclave_types",
+ "tonic",
+ "tonic-build",
+ "url",
+ "uuid",
+]
+
+[[package]]
+name = "teaclave_rpc"
+version = "0.6.0"
+dependencies = [
+ "anyhow",
+ "log",
+ "rustls",
+ "teaclave_attestation",
+ "teaclave_types",
+ "tonic",
+ "webpki",
+]
+
+[[package]]
+name = "teaclave_types"
+version = "0.6.0"
+dependencies = [
+ "anyhow",
+ "chrono",
+ "hex",
+ "log",
+ "rand",
+ "ring",
+ "serde",
+ "serde_json",
+ "sgx_tprotected_fs",
+ "sgx_types",
+ "teaclave_crypto",
+ "thiserror",
+ "toml",
+ "tonic",
+ "url",
+ "uuid",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
+dependencies = [
+ "autocfg",
+ "cfg-if 1.0.0",
+ "fastrand",
+ "redox_syscall",
+ "rustix",
+ "windows-sys",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.22",
+]
+
+[[package]]
+name = "tinyvec"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
+[[package]]
+name = "tokio"
+version = "1.28.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2"
+dependencies = [
+ "autocfg",
+ "bytes",
+ "libc",
+ "mio",
+ "num_cpus",
+ "pin-project-lite",
+ "socket2",
+ "tokio-macros",
+ "windows-sys",
+]
+
+[[package]]
+name = "tokio-io-timeout"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf"
+dependencies = [
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.22",
+]
+
+[[package]]
+name = "tokio-rustls"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6"
+dependencies = [
+ "rustls",
+ "tokio",
+ "webpki",
+]
+
+[[package]]
+name = "tokio-stream"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842"
+dependencies = [
+ "futures-core",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.6.10"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "log",
+ "pin-project-lite",
+ "tokio",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.8"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "pin-project-lite",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
+name = "toml"
+version = "0.5.11"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "tonic"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "ff08f4649d10a70ffa3522ca559031285d8e421d727ac85c60825761818f5d0a"
+dependencies = [
+ "async-stream",
+ "async-trait",
+ "base64 0.13.1",
+ "bytes",
+ "flate2",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-timeout",
+ "percent-encoding",
+ "pin-project",
+ "prost",
+ "prost-derive",
+ "tokio",
+ "tokio-rustls",
+ "tokio-stream",
+ "tokio-util 0.6.10",
+ "tower",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+ "tracing-futures",
+]
+
+[[package]]
+name = "tonic-build"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "9403f1bafde247186684b230dc6f38b5cd514584e8bec1dd32514be4745fa757"
+dependencies = [
+ "proc-macro2",
+ "prost-build",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "tower"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
+dependencies = [
+ "futures-core",
+ "futures-util",
+ "indexmap",
+ "pin-project",
+ "pin-project-lite",
+ "rand",
+ "slab",
+ "tokio",
+ "tokio-util 0.7.8",
+ "tower-layer",
+ "tower-service",
+ "tracing",
+]
+
+[[package]]
+name = "tower-layer"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
+
+[[package]]
+name = "tower-service"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
+
+[[package]]
+name = "tracing"
+version = "0.1.37"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
+dependencies = [
+ "cfg-if 1.0.0",
+ "log",
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.26"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.22",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.31"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "tracing-futures"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
+dependencies = [
+ "pin-project",
+ "tracing",
+]
+
+[[package]]
+name = "try-lock"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.13"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.22"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
+
+[[package]]
+name = "untrusted"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+
+[[package]]
+name = "url"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+ "serde",
+]
+
+[[package]]
+name = "uuid"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
+dependencies = [
+ "getrandom",
+ "serde",
+ "sha1",
+]
+
+[[package]]
+name = "want"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
+dependencies = [
+ "try-lock",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
+dependencies = [
+ "cfg-if 1.0.0",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.22",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.22",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.87"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
+
+[[package]]
+name = "web-sys"
+version = "0.3.64"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "webpki"
+version = "0.21.4"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "0.21.1"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940"
+dependencies = [
+ "webpki",
+]
+
+[[package]]
+name = "which"
+version = "4.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269"
+dependencies = [
+ "either",
+ "libc",
+ "once_cell",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.48.0"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
+
+[[package]]
+name = "yasna"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index";
+checksum = "0de7bff972b4f2a06c85f6d8454b09df153af7e3a4ec2aac81db1b105b684ddb"
+dependencies = [
+ "bit-vec",
+ "chrono",
+ "num-bigint",
+]
diff --git a/examples/rust/sequential_functions/Cargo.toml 
b/examples/rust/sequential_functions/Cargo.toml
new file mode 100644
index 00000000..bb6106dd
--- /dev/null
+++ b/examples/rust/sequential_functions/Cargo.toml
@@ -0,0 +1,35 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+[package]
+name = "sequential_functions"
+version = "0.6.0"
+authors = ["Teaclave Contributors <[email protected]>"]
+description = "builtin_ordered_set_join and builtin_gbdt_train functions 
example using Teaclave client SDK."
+license = "Apache-2.0"
+edition = "2021"
+
+[dependencies]
+anyhow                = { version = "1.0.26" }
+pem                   = { version = "0.7.0" }
+serde_json            = { version = "1.0.39" }
+teaclave_client_sdk   = { path = "../../../sdk/rust/" }
+
+[patch.crates-io]
+h2                = { git = "https://github.com/hyperium/h2";, tag = "v0.3.19" }
+sgx_tprotected_fs = { path = 
"../../../third_party/rust-sgx-sdk/sgx_protected_fs/tfs" }
+sgx_types         = { path = "../../../third_party/rust-sgx-sdk/sgx_types" }
diff --git a/examples/rust/sequential_functions/src/main.rs 
b/examples/rust/sequential_functions/src/main.rs
new file mode 100644
index 00000000..368b2bdd
--- /dev/null
+++ b/examples/rust/sequential_functions/src/main.rs
@@ -0,0 +1,380 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use anyhow::Result;
+use std::fs;
+use teaclave_client_sdk::{
+    AuthenticationClient, AuthenticationService, EnclaveInfo, FileCrypto, 
FrontendClient,
+    FrontendService, FunctionArgument, FunctionInput, FunctionOutput,
+};
+
+#[macro_export]
+macro_rules! hashmap {
+    ($( $key: expr => $value: expr, )+) => { hashmap!($($key => $value),+) };
+    ($( $key: expr => $value: expr ),*) => {{
+        let mut map = ::std::collections::HashMap::new();
+        $( map.insert($key.into(), $value.into()); )*
+        map
+    }}
+}
+
+const ENCLAVE_INFO_PATH: &str = "../../../release/services/enclave_info.toml";
+#[cfg(dcap)]
+const AS_ROOT_CA_CERT_PATH: &str = 
"../../../config/keys/dcap_root_ca_cert.pem";
+#[cfg(not(dcap))]
+const AS_ROOT_CA_CERT_PATH: &str = "../../../config/keys/ias_root_ca_cert.pem";
+
+const JOIN_INPUT_LABEL1: &str = "input_data1";
+const JOIN_INPUT_LABEL2: &str = "input_data2";
+const JOIN_OUTPUT_LABEL: &str = "output_result";
+const TRAIN_INPUT_LABEL: &str = "training_data";
+const TRAIN_OUTPUT_LABEL: &str = "trained_model";
+
+struct UserData {
+    user_id: String,
+    user_password: String,
+    input_url: String,
+    input_label: String,
+    output_url: String,
+    input_cmac: Vec<u8>,
+    key: Vec<u8>,
+    peer_id: String,
+    peer_input_label: String,
+}
+
+struct Client {
+    client: FrontendClient,
+    user_data: UserData,
+}
+
+struct PlatformAdmin {
+    client: AuthenticationClient,
+}
+
+impl PlatformAdmin {
+    fn new(admin_user_id: &str, admin_user_password: &str) -> Result<Self> {
+        let enclave_info = EnclaveInfo::from_file(ENCLAVE_INFO_PATH)?;
+        let bytes = fs::read(AS_ROOT_CA_CERT_PATH)?;
+        let as_root_ca_cert = pem::parse(bytes)?.contents;
+        let mut client = AuthenticationService::connect(
+            "https://localhost:7776";,
+            &enclave_info,
+            &as_root_ca_cert,
+        )?;
+        let token = client.user_login(admin_user_id, admin_user_password)?;
+        client.set_credential(admin_user_id, &token);
+        Ok(Self { client })
+    }
+
+    fn register_user(
+        &mut self,
+        user_id: &str,
+        user_password: &str,
+        role: &str,
+        attribute: &str,
+    ) -> Result<()> {
+        self.client
+            .user_register(user_id, user_password, role, attribute)
+    }
+}
+
+impl Client {
+    fn new(user_data: UserData) -> Result<Client> {
+        let enclave_info = EnclaveInfo::from_file(ENCLAVE_INFO_PATH)?;
+        let bytes = fs::read(AS_ROOT_CA_CERT_PATH)?;
+        let as_root_ca_cert = pem::parse(bytes)?.contents;
+        let mut client = AuthenticationService::connect(
+            "https://localhost:7776";,
+            &enclave_info,
+            &as_root_ca_cert,
+        )?;
+
+        println!("[+] {} login", user_data.user_id);
+        client.user_login(&user_data.user_id, &user_data.user_password)?;
+
+        let token = client.user_login(&user_data.user_id, 
&user_data.user_password)?;
+
+        let mut client =
+            FrontendService::connect("https://localhost:7777";, &enclave_info, 
&as_root_ca_cert)?;
+        client.set_credential(&user_data.user_id, &token);
+
+        Ok(Client { client, user_data })
+    }
+
+    fn set_train_task(&mut self) -> Result<String> {
+        println!("[+] {} registering function", self.user_data.user_id);
+        let function_id = self.client.register_function(
+            "builtin-gbdt-train",
+            "Native Gbdt Training Function.",
+            "builtin",
+            None,
+            Some(vec![
+                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("training_optimization_level", "", true),
+                FunctionArgument::new("loss", "", true),
+            ]),
+            Some(vec![FunctionInput::new(
+                TRAIN_INPUT_LABEL,
+                "Fusion data.",
+                false,
+            )]),
+            Some(vec![FunctionOutput::new(
+                TRAIN_OUTPUT_LABEL,
+                "Output trained model.",
+                false,
+            )]),
+            None,
+        )?;
+        self.client.get_function(&function_id)?;
+
+        let function_arguments = hashmap!(
+                                "feature_size" => 4,
+                                "max_depth" => 4,
+                                "iterations" => 100,
+                                "shrinkage" => 0.1,
+                                "feature_sample_ratio" => 1.0,
+                                "data_sample_ratio" => 1.0,
+                                "min_leaf_size" => 1,
+                                "loss" => "LAD",
+                                "training_optimization_level" => 2);
+
+        let inputs_ownership = hashmap!(TRAIN_INPUT_LABEL => 
vec![self.user_data.user_id.to_string(),self.user_data.peer_id.to_string()]);
+        let outputs_ownership =
+            hashmap!(TRAIN_OUTPUT_LABEL 
=>vec![self.user_data.user_id.to_string()],);
+
+        println!("[+] {} creating task", self.user_data.user_id);
+        let task_id = self.client.create_task(
+            &function_id,
+            Some(function_arguments),
+            "builtin",
+            Some(inputs_ownership),
+            Some(outputs_ownership),
+        )?;
+        Ok(task_id)
+    }
+
+    fn set_fusion_task(&mut self) -> Result<String> {
+        println!("[+] {} registering function", self.user_data.user_id);
+        let function_id = self.client.register_function(
+            "builtin-ordered-set-join",
+            "Join two sets of CSV data based on the specified sorted columns.",
+            "builtin",
+            None,
+            Some(vec![
+                FunctionArgument::new("left_column", "", true),
+                FunctionArgument::new("right_column", "", true),
+                FunctionArgument::new("ascending", "true", true),
+                FunctionArgument::new("drop", "true", true),
+                FunctionArgument::new("save_log", "false", true),
+            ]),
+            Some(vec![
+                FunctionInput::new(JOIN_INPUT_LABEL1, "Client 0 data.", false),
+                FunctionInput::new(JOIN_INPUT_LABEL2, "Client 1 data.", false),
+            ]),
+            Some(vec![FunctionOutput::new(
+                JOIN_OUTPUT_LABEL,
+                "Output data.",
+                false,
+            )]),
+            None,
+        )?;
+        self.client.get_function(&function_id)?;
+        let function_arguments = hashmap!("left_column" => 0, "right_column" 
=> 0, "ascending" => true, "drop"=>true,"save_log" => "true");
+        let inputs_ownership = hashmap!(&self.user_data.input_label => 
vec![self.user_data.user_id.to_string()], &self.user_data.peer_input_label => 
vec![self.user_data.peer_id.to_string()]);
+        let outputs_ownership = hashmap!(JOIN_OUTPUT_LABEL=>vec![
+            self.user_data.user_id.to_string(),
+            self.user_data.peer_id.to_string(),
+        ]);
+
+        println!("[+] {} creating task", self.user_data.user_id);
+        let task_id = self.client.create_task(
+            &function_id,
+            Some(function_arguments),
+            "builtin",
+            Some(inputs_ownership),
+            Some(outputs_ownership),
+        )?;
+        Ok(task_id)
+    }
+
+    fn register_input_data(&mut self, task_id: &str) -> Result<()> {
+        println!(
+            "[+] {} registering input file {}",
+            self.user_data.user_id, self.user_data.input_url
+        );
+        let data_id = self.client.register_input_file(
+            &self.user_data.input_url,
+            &self.user_data.input_cmac,
+            teaclave_client_sdk::FileCrypto::new(
+                "teaclave-file-128",
+                &self.user_data.key,
+                &Vec::new(),
+            )?,
+        )?;
+        let inputs = hashmap!(&self.user_data.input_label => data_id);
+        self.client.assign_data(task_id, Some(inputs), None)?;
+
+        Ok(())
+    }
+
+    fn register_input_from_output(
+        &mut self,
+        task_id: &str,
+        label: &str,
+        data_id: &str,
+    ) -> Result<()> {
+        let new_id = self.client.register_input_from_output(data_id)?;
+        let inputs = hashmap!(label => new_id);
+        self.client.assign_data(task_id, Some(inputs), None)
+    }
+
+    fn register_output_data(&mut self, task_id: &str, label: &str) -> 
Result<()> {
+        let data_id = self.client.register_output_file(
+            &self.user_data.output_url,
+            FileCrypto::new("teaclave-file-128", &self.user_data.key, 
&Vec::new())?,
+        )?;
+        let outputs = hashmap!(label => data_id);
+        self.client.assign_data(task_id, None, Some(outputs))
+    }
+
+    fn register_fusion_data(&mut self, task_id: &str, label: &str) -> 
Result<String> {
+        let data_id = self.client.register_fusion_output(vec![
+            self.user_data.user_id.to_string(),
+            self.user_data.peer_id.to_string(),
+        ])?;
+
+        let outputs = hashmap!(label => data_id.clone());
+
+        println!(
+            "[+] {} assigning fusion data to task",
+            self.user_data.user_id
+        );
+        self.client.assign_data(task_id, None, Some(outputs))?;
+        Ok(data_id)
+    }
+
+    fn run_task(&mut self, task_id: &str) -> Result<()> {
+        println!("[+] {} invoking task", self.user_data.user_id);
+        self.client.invoke_task(task_id)?;
+        Ok(())
+    }
+
+    fn approve_task(&mut self, task_id: &str) -> Result<()> {
+        println!("[+] {} approving task", self.user_data.user_id);
+        self.client.approve_task(task_id)?;
+        Ok(())
+    }
+
+    fn get_task_result(&mut self, task_id: &str) -> Result<(Vec<u8>, 
Vec<String>)> {
+        println!("[+] {} getting result", self.user_data.user_id);
+        let response = self.client.get_task_result(task_id)?;
+        Ok(response)
+    }
+}
+
+// User0 provides some training features, while User1 provides another set of 
training features and label.
+// Based on the sorted ID columns, these two data are concatenated and used as 
training data for the GBDT.
+fn main() -> Result<()> {
+    let mut admin = PlatformAdmin::new("admin", "teaclave")?;
+    // Ignore registering errors
+    let _ = admin.register_user("user0", "password", "PlatformAdmin", "");
+    let _ = admin.register_user("user1", "password", "PlatformAdmin", "");
+    let user0_data = UserData {
+        user_id: "user0".to_string(),
+        user_password: "password".to_string(),
+        input_url: 
"http://localhost:6789/fixtures/functions/ordered_set_join/join0.csv.enc";
+            .to_string(),
+        input_label: JOIN_INPUT_LABEL1.to_string(),
+        output_url: 
"http://localhost:6789/fixtures/functions/gbdt_training/output_model.enc";
+            .to_string(),
+        input_cmac: vec![
+            0x3f, 0x91, 0xd2, 0x74, 0x47, 0x63, 0x44, 0x5d, 0x26, 0x5e, 0xa4, 
0x69, 0xde, 0xbb,
+            0x74, 0xf0,
+        ],
+        key: vec![0; 16],
+        peer_id: "user1".to_string(),
+        peer_input_label: JOIN_INPUT_LABEL2.to_string(),
+    };
+
+    let user1_data = UserData {
+        user_id: "user1".to_string(),
+        user_password: "password".to_string(),
+        input_url: 
"http://localhost:6789/fixtures/functions/ordered_set_join/join1.csv.enc";
+            .to_string(),
+        input_label: JOIN_INPUT_LABEL2.to_string(),
+        output_url: "".to_string(),
+        input_cmac: vec![
+            0xd1, 0xe5, 0xa5, 0x20, 0x48, 0x9c, 0x93, 0xd0, 0x25, 0x4c, 0x8c, 
0x22, 0xcd, 0xef,
+            0xab, 0x89,
+        ],
+        key: vec![0; 16],
+        peer_id: "user0".to_string(),
+        peer_input_label: JOIN_INPUT_LABEL1.to_string(),
+    };
+
+    let mut user0 = Client::new(user0_data)?;
+    let mut user1 = Client::new(user1_data)?;
+
+    let task_id = user0.set_fusion_task()?;
+
+    user0.register_input_data(&task_id)?;
+    user1.register_input_data(&task_id)?;
+    let fusion_id = user0.register_fusion_data(&task_id, JOIN_OUTPUT_LABEL)?;
+
+    user0.approve_task(&task_id)?;
+    user1.approve_task(&task_id)?;
+
+    user0.run_task(&task_id)?;
+
+    let result_user0 = user0.get_task_result(&task_id)?;
+
+    println!(
+        "[+] User 0 result: {:?} log: {:?} ",
+        String::from_utf8(result_user0.0),
+        result_user0.1
+    );
+
+    let result_user1 = user1.get_task_result(&task_id)?;
+
+    println!(
+        "[+] User 1 result: {:?} log {:?}",
+        String::from_utf8(result_user1.0),
+        result_user1.1
+    );
+
+    let train_task_id = user0.set_train_task()?;
+    user0.register_input_from_output(&train_task_id, TRAIN_INPUT_LABEL, 
&fusion_id)?;
+    user0.register_output_data(&train_task_id, TRAIN_OUTPUT_LABEL)?;
+    user0.approve_task(&train_task_id)?;
+    anyhow::ensure!(
+        user0.run_task(&train_task_id).is_err(),
+        "An error should be returned here because it is waiting for user1's 
approval."
+    );
+    user1.approve_task(&train_task_id)?;
+    user0.run_task(&train_task_id)?;
+
+    let result_user0 = user0.get_task_result(&train_task_id)?;
+    println!("[+] User 0 result: {:?}", String::from_utf8(result_user0.0),);
+    println!("[+] done");
+    Ok(())
+}
diff --git a/sdk/c/teaclave_client_sdk.h b/sdk/c/teaclave_client_sdk.h
index 4720193a..c5a458d0 100644
--- a/sdk/c/teaclave_client_sdk.h
+++ b/sdk/c/teaclave_client_sdk.h
@@ -409,6 +409,58 @@ int teaclave_register_output_file_serialized(struct 
FrontendClient *client,
                                              char *serialized_response,
                                              size_t *serialized_response_len);
 
+/**
+ * Send JSON serialized request to the service with the `client` and
+ * get the serialized response.
+ *
+ * # Arguments
+ *
+ * * `client`: service client.
+ * * `serialized_request`; JSON serialized request
+ * * `serialized_response`: buffer to store the JSON serialized response.
+ * * `serialized_response_len`: length of the allocated
+ *   `serialized_response`, will be set as the length of
+ *   `serialized_response` when return successfully.
+ *
+ * # Return
+ *
+ * The function returns 0 for success. On error, the function returns 1.
+ *
+ * # Safety
+ *
+ * Inconsistent length of allocated buffer may caused overflow.
+ */
+int teaclave_register_fusion_output_serialized(struct FrontendClient *client,
+                                               const char *serialized_request,
+                                               char *serialized_response,
+                                               size_t 
*serialized_response_len);
+
+/**
+ * Send JSON serialized request to the service with the `client` and
+ * get the serialized response.
+ *
+ * # Arguments
+ *
+ * * `client`: service client.
+ * * `serialized_request`; JSON serialized request
+ * * `serialized_response`: buffer to store the JSON serialized response.
+ * * `serialized_response_len`: length of the allocated
+ *   `serialized_response`, will be set as the length of
+ *   `serialized_response` when return successfully.
+ *
+ * # Return
+ *
+ * The function returns 0 for success. On error, the function returns 1.
+ *
+ * # Safety
+ *
+ * Inconsistent length of allocated buffer may caused overflow.
+ */
+int teaclave_register_input_from_output_serialized(struct FrontendClient 
*client,
+                                                   const char 
*serialized_request,
+                                                   char *serialized_response,
+                                                   size_t 
*serialized_response_len);
+
 /**
  * Send JSON serialized request to the service with the `client` and
  * get the serialized response.
diff --git a/sdk/python/teaclave.py b/sdk/python/teaclave.py
index d1ca3841..e556ffdf 100644
--- a/sdk/python/teaclave.py
+++ b/sdk/python/teaclave.py
@@ -695,6 +695,22 @@ class RegisterOutputFileRequest(Request):
             url=url, crypto_info=crypto_info.message)
 
 
+class RegisterInputFromOutputRequest(Request):
+
+    def __init__(self, metadata: Metadata, data_id: str):
+        super().__init__("RegisterInputFromOutput",
+                         fe.RegisterInputFromOutputResponse, metadata)
+        self.message = fe.RegisterInputFromOutputRequest(data_id=data_id)
+
+
+class RegisterFusionOutputRequest(Request):
+
+    def __init__(self, metadata: Metadata, owner_list: List[str] = []):
+        super().__init__("RegisterFusionOutput",
+                         fe.RegisterFusionOutputResponse, metadata)
+        self.message = fe.RegisterFusionOutputRequest(owner_list=owner_list)
+
+
 class UpdateInputFileRequest(Request):
 
     def __init__(self, metadata: Metadata, data_id: str, url: str):
@@ -936,6 +952,40 @@ class FrontendService(TeaclaveService):
             raise TeaclaveException(
                 f"Failed to register output file ({reason})")
 
+    def register_input_from_output(self, data_id: str):
+        """Register an input data from an output data.
+
+        Args:
+
+            data_id (str): ExternalID of the output data.
+
+        Returns:
+
+            str: ExternalID of input data
+        """
+
+        self.check_metadata()
+        self.check_channel()
+        request = RegisterInputFromOutputRequest(self.metadata, data_id)
+        response = self.call_method(request)
+        return response.data_id
+
+    def register_fusion_output(self, owners: List[str] = []):
+        """Register a fusion output data.
+
+        Args:
+
+            owners (List[OwnerList], optional): Owners of the output data. 
Defaults to [].
+        
+        Returns:
+
+            str: ExternalID of fusion output data
+        """
+
+        request = RegisterFusionOutputRequest(self.metadata, owners)
+        response = self.call_method(request)
+        return response.data_id
+
     def create_task(self,
                     function_id: str,
                     function_arguments: Dict[str, Any],
diff --git a/sdk/rust/src/bindings.rs b/sdk/rust/src/bindings.rs
index 1e3664c8..baae09a4 100644
--- a/sdk/rust/src/bindings.rs
+++ b/sdk/rust/src/bindings.rs
@@ -556,6 +556,16 @@ generate_function_serialized!(
     teaclave_register_output_file_serialized,
     register_output_file_serialized
 );
+generate_function_serialized!(
+    FrontendClient,
+    teaclave_register_fusion_output_serialized,
+    register_fusion_output_serialized
+);
+generate_function_serialized!(
+    FrontendClient,
+    teaclave_register_input_from_output_serialized,
+    register_input_from_output_serialized
+);
 generate_function_serialized!(
     FrontendClient,
     teaclave_create_task_serialized,
diff --git a/sdk/rust/src/lib.rs b/sdk/rust/src/lib.rs
index e3293a92..ecc497f9 100644
--- a/sdk/rust/src/lib.rs
+++ b/sdk/rust/src/lib.rs
@@ -36,8 +36,10 @@ pub use teaclave_proto::teaclave_frontend_service::{
     CreateTaskResponse, GetFunctionRequest, GetFunctionResponse, 
GetFunctionUsageStatsRequest,
     GetFunctionUsageStatsResponse, GetTaskRequest, GetTaskResponse, 
InvokeTaskRequest,
     QueryAuditLogsRequest, QueryAuditLogsResponse, RegisterFunctionRequest,
-    RegisterFunctionRequestBuilder, RegisterFunctionResponse, 
RegisterInputFileRequest,
-    RegisterInputFileResponse, RegisterOutputFileRequest, 
RegisterOutputFileResponse,
+    RegisterFunctionRequestBuilder, RegisterFunctionResponse, 
RegisterFusionOutputRequest,
+    RegisterFusionOutputResponse, RegisterInputFileRequest, 
RegisterInputFileResponse,
+    RegisterInputFromOutputRequest, RegisterInputFromOutputResponse, 
RegisterOutputFileRequest,
+    RegisterOutputFileResponse,
 };
 pub use teaclave_types::{
     EnclaveInfo, Entry, Executor, FileCrypto, FunctionArgument, FunctionInput, 
FunctionOutput,
@@ -386,6 +388,60 @@ impl FrontendClient {
         Ok(response.data_id)
     }
 
+    pub fn register_input_from_output_with_request(
+        &mut self,
+        request: RegisterInputFromOutputRequest,
+    ) -> Result<RegisterInputFromOutputResponse> {
+        do_request_with_credential!(self, register_input_from_output, request)
+    }
+
+    pub fn register_input_from_output_serialized(
+        &mut self,
+        serialized_request: &str,
+    ) -> Result<String> {
+        let request = serde_json::from_str(serialized_request)?;
+        let response = self.register_input_from_output_with_request(request)?;
+        let serialized_response = serde_json::to_string(&response)?;
+
+        Ok(serialized_response)
+    }
+
+    pub fn register_input_from_output(&mut self, data_id: &str) -> 
Result<String> {
+        let data_id = teaclave_types::ExternalID::try_from(data_id)?;
+        let request = RegisterInputFromOutputRequest::new(data_id);
+        let response = self.register_input_from_output_with_request(request)?;
+
+        Ok(response.data_id)
+    }
+
+    pub fn register_fusion_output_with_request(
+        &mut self,
+        request: RegisterFusionOutputRequest,
+    ) -> Result<RegisterFusionOutputResponse> {
+        do_request_with_credential!(self, register_fusion_output, request)
+    }
+
+    pub fn register_fusion_output_serialized(
+        &mut self,
+        serialized_request: &str,
+    ) -> Result<String> {
+        let request = serde_json::from_str(serialized_request)?;
+        let response = self.register_fusion_output_with_request(request)?;
+        let serialized_response = serde_json::to_string(&response)?;
+
+        Ok(serialized_response)
+    }
+
+    pub fn register_fusion_output(
+        &mut self,
+        owners: impl Into<teaclave_types::OwnerList>,
+    ) -> Result<String> {
+        let request = RegisterFusionOutputRequest::new(owners);
+        let response = self.register_fusion_output_with_request(request)?;
+
+        Ok(response.data_id)
+    }
+
     pub fn create_task_serialized(&mut self, serialized_request: &str) -> 
Result<String> {
         let request = serde_json::from_str(serialized_request)?;
         let response = self.create_task_with_request(request)?;
diff --git a/tests/fixtures/functions/ordered_set_join/join0.csv.enc 
b/tests/fixtures/functions/ordered_set_join/join0.csv.enc
new file mode 100644
index 00000000..b28fa1b9
Binary files /dev/null and 
b/tests/fixtures/functions/ordered_set_join/join0.csv.enc differ
diff --git a/tests/fixtures/functions/ordered_set_join/join1.csv.enc 
b/tests/fixtures/functions/ordered_set_join/join1.csv.enc
new file mode 100644
index 00000000..626d57c1
Binary files /dev/null and 
b/tests/fixtures/functions/ordered_set_join/join1.csv.enc differ


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to